Logo

Themes

We've seen how XMLUI enables reactive data binding without requiring you to master React's complexity. The same principle applies to layout and style: XMLUI's theme system ensures that your apps look good and behave gracefully without requiring you to master the complexity of CSS (Cascading Style Sheets). You can use the dropdown to switch from the default theme (xmlui) to one called earthtone. Then use the ToneChangerButton to switch between light and dark modes.
You've now switched the settings for thousands of theme variables. Each theme variable defines the value that influences an aspect of a component's appearance: text color and font, background color, margin, border, padding, etc. They follow a naming convention that enables a setting to control appearance globally or in progressively more granular ways. For example, here are the variables that can control the border color of a solid button using the primary color when the mouse hovers over it:
color-primary
backgroundColor-Button
backgroundColor-Button-solid
backgroundColor-Button-primary
backgroundColor-Button-primary-solid
backgroundColor-Button-primary-solid--hover
When it renders a button, XMLUI works up the chain from the most specific setting to the most general. This arrangement gives designers many degrees of freedom to craft exquisitely detailed themes. But almost all the settings are optional, and those that are defined by default use other variables instead of hardcoded values. So, for example, the default setting for backgroundColor-Button-primary is $color-primary-500. That's the midpoint in a range of colors that play a primary role in the UI. There's a set of such roles, each associated with a color palette. The key roles are:
  • Surface creates neutral backgrounds and containers
  • Primary draws attention to important elements and actions
  • Secondary provides visual support without competing with primary elements
Here's a simple example to show how the cascade of specificity works. If we override textColor-primary it applies to both Text and Markdown.
<Theme textColor-primary="red">
  <Text>This is Text</Text>
  <Markdown>This is Markdown</Markdown>
</Theme>
<Theme textColor-primary="red">
  <Text>This is Text</Text>
  <Markdown>This is Markdown</Markdown>
</Theme>
But we can target Markdown for different treatment with a more specific theme variable.
<Theme
  textColor-primary="red"
  textColor-Text-markdown="blue"
  >
  <Text>This is Text</Text>
  <Markdown>This is Markdown</Markdown>
</Theme>
<Theme
  textColor-primary="red"
  textColor-Text-markdown="blue"
  >
  <Text>This is Text</Text>
  <Markdown>This is Markdown</Markdown>
</Theme>
On this page you can see the complete set of roles and explore how different themes express them. To create a new theme you can minimally supply just three values: for $color-primary, $color-secondary, and $color-surface. Here is the complete definition for our custom earthtone theme.
{
  "name": "Earthtone",
  "id": "earthtone",
  "themeVars": {
    "color-primary": "hsl(30, 50%, 30%)",
    "color-secondary": "hsl(120, 40%, 25%)",
    "color-surface": "hsl(39, 43%, 97%)",
  }
}
To see how our TubeStops component looks with earthtone vs the default, we can wrap two instances of it using the Theme component. Here we use only the default settings for both themes.
earthtone
waterloo-city
xmlui
waterloo-city
Here we vary the settings as shown.
<Theme
  themeId="earthtone"
  backgroundColor-Card="$color-secondary-100"
  fontFamily="serif"
  border-Badge="2px solid black"
  textColor-Badge="black"
  backgroundColor-Badge="yellow"
  fontWeight-Badge="normal"
  fontSize-Badge="larger"
>
<Theme
  themeId="xmlui"
  backgroundColor-Card="$color-warning-200"
  fontFamily="monaco"
  border-Badge="none"
  textColor-Badge="$color-warn-900"
  backgroundColor-Badge="$color-warn-600"
  fontWeight-Badge="bold"
  fontSize-Badge="18pt"
>
earthtone
waterloo-city
xmlui
waterloo-city
It's easy to make a mess by varying these settings but you will rarely need to touch them. A designer of a custom theme might want to, but even then the defaults will handle almost every situation. And remember: you can create an entire new theme from just a handful of reference colors.
This site is an XMLUI™ app.