CRITICAL: Use for Makepad 2.0 theme system. Triggers on: makepad theme, theme variable, theme color, theme font, theme spacing, dark mode, light mode, theme switching, mod.themes, theme_mod, theme.color_, theme.font_, theme.space_, theme.mspace_, 主题, 颜色, 字体, 暗色模式, 亮色模式, 主题切换, 样式
The Makepad 2.0 theme system provides a comprehensive set of design tokens accessed
through theme.* variables in Splash scripts. It delivers consistent styling for
colors, typography, spacing, and widget states across your entire application.
Three built-in themes are available:
mod.themes.dark -- dark desktop theme (default)mod.themes.light -- light desktop thememod.themes.skeleton -- minimal skeleton theme with hardcoded valuesGolden rule: Always use theme.* variables instead of hardcoded values for any
color, font size, or spacing in production UIs. This ensures your app automatically
supports theme switching and maintains visual consistency.
The theme must be loaded before widgets are loaded. The standard pattern is:
impl App {
fn run(vm: &mut ScriptVm) -> Self {
// Step 1: Load theme definitions (dark, light, skeleton)
crate::makepad_widgets::theme_mod(vm);
// Step 2: Select active theme (MUST come before widgets_mod)
script_eval!(vm, {
mod.theme = mod.themes.light // or mod.themes.dark
});
// Step 3: Load widget definitions (they reference mod.theme)
crate::makepad_widgets::widgets_mod(vm);
// Step 4: Load your app's script_mod
App::from_script_mod(vm, self::script_mod)
}
}
If you skip steps 1-2, the default theme is dark (set inside theme_mod).
The counter example uses the simplified one-liner crate::makepad_widgets::script_mod(vm)
which bundles steps 1-3 with the default dark theme.
theme_mod() does the following:
makepad_draw::script_mod(vm) to load drawing primitivesmod.themes moduletheme_desktop_dark, theme_desktop_light, and theme_desktop_skeletonmod.theme = mod.themes.dark as the defaultThen widgets_mod() creates mod.prelude.widgets_internal with theme: mod.theme,
making theme.* available in all widget scripts that use mod.prelude.widgets.*.
Each theme defines tunable global parameters that control the overall feel:
| Parameter | Purpose | Default (dark/light) |
|---|---|---|
color_contrast | Controls color palette spread | 1.0 |
color_tint | Tint applied to backgrounds | #0000ff |
color_tint_amount | How much tint to apply (0-1) | 0.0 |
space_factor | Base spacing multiplier | 6.0 |
corner_radius | Base corner radius | 2.5 |
beveling | Bevel intensity | 0.75 |
font_size_base | Base font size in px | 10.0 |
font_size_contrast | Font size step between levels | 2.5 |
These are the colors you will use most often in application code:
| Variable | Purpose | Light Appearance | Dark Appearance |
|---|---|---|---|
theme.color_bg_app | App background | Light gray (~#DDD) | Dark gray (~#333) |
theme.color_fg_app | Foreground layer | Slightly darker | Slightly lighter |
theme.color_bg_container | Card/container bg | Semi-transparent light | Semi-transparent dark |
theme.color_bg_even | Alternating row (even) | Lighter | Darker |
theme.color_bg_odd | Alternating row (odd) | Darker | Lighter |
theme.color_bg_highlight | Highlight background | White-ish #FFFFFF22 | White-ish low opacity |
theme.color_bg_highlight_inline | Inline highlight | color_d_1 | color_d_3 |
theme.color_bg_unfocussed | Unfocused highlight | 85% of bg_highlight | 85% of bg_highlight |
theme.color_app_caption_bar | Caption bar bg | Transparent | Transparent |
theme.color_white | Pure white | #FFFFFF | #FFFFFF |
theme.color_makepad | Makepad brand | #FF5C39 | #FF5C39 |
| Variable | Purpose |
|---|---|
theme.color_label_inner | Primary text on inner elements (buttons, labels) |
theme.color_label_inner_hover | Text on hover |
theme.color_label_inner_down | Text when pressed |
theme.color_label_inner_focus | Text when focused |
theme.color_label_inner_active | Text when active/selected |
theme.color_label_inner_inactive | Secondary/muted text |
theme.color_label_inner_disabled | Disabled text |
theme.color_label_outer | Primary text on outer elements (tabs, headers) |
theme.color_label_outer_off | Outer text when off |
theme.color_label_outer_disabled | Disabled outer text |
theme.color_text | General text color |
theme.color_text_hover | Text on hover |
theme.color_text_focus | Text on focus |
theme.color_text_disabled | Disabled text |
theme.color_text_placeholder | Placeholder text |
theme.color_text_meta | Metadata text |
theme.color_text_cursor | Text cursor color |
Outset colors (buttons, raised elements):
| Variable | Purpose |
|---|---|
theme.color_outset | Default button background |
theme.color_outset_hover | Button on hover |
theme.color_outset_down | Button when pressed |
theme.color_outset_active | Active toggle state |
theme.color_outset_focus | Focused button |
theme.color_outset_disabled | Disabled button |
theme.color_outset_inactive | Inactive button |
Inset colors (text inputs, checkboxes, radio buttons):
| Variable | Purpose |
|---|---|
theme.color_inset | Default input background |
theme.color_inset_hover | Input on hover |
theme.color_inset_focus | Input on focus |
theme.color_inset_disabled | Disabled input |
theme.color_inset_empty | Empty input |
Selection and highlight:
| Variable | Purpose |
|---|---|
theme.color_selection_focus | Text selection highlight |
theme.color_selection_hover | Selection on hover |
theme.color_highlight | General accent/highlight |
theme.color_cursor | Cursor color |
theme.color_cursor_focus | Focused cursor |
| Variable | Purpose | Value |
|---|---|---|
theme.color_error | Error state | Red (#C00) |
theme.color_warning | Warning state | Orange (#FA0) |
theme.color_high | High severity | Red (#C00) |
theme.color_mid | Medium severity | Orange (#FA0) |
theme.color_low | Low severity | Yellow-green (#8A0) |
theme.color_panic | Panic/critical | Magenta (#f0f) |
The theme has a layered bevel system for 3D-like widget effects:
| Group | Variables | Purpose |
|---|---|---|
color_bevel* | _hover, _focus, _active, _down, _disabled | Flat bevel |
color_bevel_inset_1* | Same suffixes | Inner shadow (layer 1) |
color_bevel_inset_2* | Same suffixes | Inner highlight (layer 2) |
color_bevel_outset_1* | Same suffixes | Outer highlight (layer 1) |
color_bevel_outset_2* | Same suffixes | Outer shadow (layer 2) |
| Variable Group | Purpose |
|---|---|
theme.color_icon* | Icon colors (default, inactive, active, disabled) |
theme.color_mark* | Checkmark/radio mark colors |
theme.color_val* | Progress bar and slider fill colors |
theme.color_handle* | Slider handle colors |
theme.color_shadow* | Shadow effects |
theme.color_drag_quad | Drag preview overlay |
theme.color_dock_tab_active | Active dock tab background |
Font sizes are computed from font_size_base and font_size_contrast:
| Variable | Formula | Default Value |
|---|---|---|
theme.font_size_1 | base + 8 * contrast | 30.0 (largest heading) |
theme.font_size_2 | base + 4 * contrast | 20.0 (medium heading) |
theme.font_size_3 | base + 2 * contrast | 15.0 (small heading) |
theme.font_size_4 | base + 1 * contrast | 12.5 (subheading) |
theme.font_size_p | base | 10.0 (body text) |
theme.font_size_code | fixed | 9.0 (monospace code) |
| Variable | Description | Font File |
|---|---|---|
theme.font_regular | Regular weight body text | IBMPlexSans-Text.ttf |
theme.font_bold | Bold/semibold text | IBMPlexSans-SemiBold.ttf |
theme.font_italic | Italic text | IBMPlexSans-Italic.ttf |
theme.font_bold_italic | Bold italic text | IBMPlexSans-BoldItalic.ttf |
theme.font_code | Monospace code font | LiberationMono-Regular.ttf |
theme.font_label | Label text (legacy) | IBMPlexSans-Text.ttf |
theme.font_icons | Icon font (FontAwesome) | fa-solid-900.ttf |
Each font style includes multi-language support:
| Variable | Value | Purpose |
|---|---|---|
theme.font_wdgt_line_spacing | 1.2 | Widget text |
theme.font_hl_line_spacing | 1.05 | Heading text |
theme.font_longform_line_spacing | 1.2 | Long-form text |
Spacing is derived from space_factor (default 6.0):
| Variable | Formula | Default Value |
|---|---|---|
theme.space_1 | 0.5 * space_factor | 3.0 (extra small) |
theme.space_2 | 1.0 * space_factor | 6.0 (small/standard) |
theme.space_3 | 1.5 * space_factor | 9.0 (medium) |
All-sides presets:
| Variable | Description | Values |
|---|---|---|
theme.mspace_1 | XS padding all sides | 3px each |
theme.mspace_2 | SM padding all sides | 6px each |
theme.mspace_3 | MD padding all sides | 9px each |
Horizontal-only presets:
| Variable | Description | Values |
|---|---|---|
theme.mspace_h_1 | XS horizontal padding | left/right: 3px, top/bottom: 0 |
theme.mspace_h_2 | SM horizontal padding | left/right: 6px, top/bottom: 0 |
theme.mspace_h_3 | MD horizontal padding | left/right: 9px, top/bottom: 0 |
Vertical-only presets:
| Variable | Description | Values |
|---|---|---|
theme.mspace_v_1 | XS vertical padding | top/bottom: 3px, left/right: 0 |
theme.mspace_v_2 | SM vertical padding | top/bottom: 6px, left/right: 0 |
theme.mspace_v_3 | MD vertical padding | top/bottom: 9px, left/right: 0 |
| Variable | Purpose | Default |
|---|---|---|
theme.data_item_height | Standard data row height | ~23px |
theme.data_icon_width | Standard icon width | ~16px |
theme.data_icon_height | Standard icon height | ~22px |
theme.container_corner_radius | Container border radius | 5.0 |
theme.textselection_corner_radius | Text selection radius | 1.25 |
theme.tab_height | Tab bar height | 36.0 |
// Background color
draw_bg.color: theme.color_bg_container
// Text color
draw_text.color: theme.color_label_inner
// Muted/secondary text
draw_text.color: theme.color_label_inner_inactive
// Color math -- multiply for opacity
draw_text.color: theme.color_label_inner_inactive * 0.8
// Semantic colors
draw_bg.color: theme.color_warning
draw_bg.color: theme.color_error
// Body text size
draw_text.text_style.font_size: theme.font_size_p
// Heading sizes
draw_text.text_style.font_size: theme.font_size_1 // Largest
draw_text.text_style.font_size: theme.font_size_2 // Medium
draw_text.text_style.font_size: theme.font_size_3 // Small
draw_text.text_style.font_size: theme.font_size_4 // Sub-heading
// Code font size
draw_text.text_style.font_size: theme.font_size_code
// Bold text with custom size (override with {} syntax)
draw_text.text_style: theme.font_bold{font_size: theme.font_size_2}
// Bold text keeping default size
draw_text.text_style: theme.font_bold{}
// Code font
draw_text.text_style: theme.font_code{}
// Override font size using +: merge syntax
draw_text +: {text_style +: {font_size: theme.font_size_3}}
// Uniform padding