Theming

Stacks provides a robust theming API to handle theming in various contexts.

Light, dark, and high contrast modes

Section titled Light, dark, and high contrast modes

Stacks supports light, dark, and high contrast modes. By using Stacks, you will get each of these modes for free. By using a Stacks component, an atomic color class, or CSS variable directly, your theme will switch appropriately based on the following methods:

  1. You can apply .theme-system to the body element. This will change colors based on the prefers-color-scheme media query, which is ultimately powered by the user’s system or browser settings. This can be preferable for folks who have their system turn to dark mode based on ambient light or time of day.
  2. Alternatively, you can set a dark mode that is not system dependent by attaching .theme-dark to the body element.
  3. Adding .theme-highcontrast to the body element will boost colors to WCAG Level AAA contrast ratios in as many places as possible. This mode stacks on top of both light and dark modes. The only exception is branded themed colors remain untouched by high contrast mode.

There are also conditional classes that can be applied to override assumed dark mode colors, force light mode, or to force dark mode. Forcing modes can be good for previews in admin-only situations.

Stacks provides an API to apply custom themes.

Use .create-custom-theme-hsl-variables(@color, @tier, @modeCustom) to create a custom theme.

This function generates two sets of CSS variables: 1) independent h/s/l color variables and 2) variables at each colors stop that reference the h/s/l variables. Provide this function the arguments defined below to generate theme colors which will apply across Stacks.

Argument Type Default Description
@color HSL, hex, or other color value Color to use to generate theme values.
@tier primary | secondary primary Color tier to generate.
@modeCustom base | dark base The color mode the theme applies to.
.theme-custom.themed {
.create-custom-theme-hsl-variables(hsl(172, 37%, 48%), primary);
.create-custom-theme-hsl-variables(hsl(259, 29%, 55%), secondary);
.create-custom-theme-hsl-variables(hsl(201, 70%, 55%), primary, dark);
.create-custom-theme-hsl-variables(hsl(270, 34%, 40%), secondary, dark);
}
/* Input */
.theme-custom.themed {
.create-custom-theme-hsl-variables(hsl(172, 37%, 48%), primary);
}

/* Output */
.theme-custom.themed {
/* HSL variables */
--theme-base-primary-color-h: 172;
--theme-base-primary-color-s: 37%;
--theme-base-primary-color-l: 48%;
/* Color variables based on HSL variables */
--theme-primary-custom: var(--theme-primary-custom-400);
--theme-primary-custom-100: hsl(var(--theme-base-primary-color-h), calc(var(--theme-base-primary-color-s) + 0 * 1%), clamp(70%, calc(var(--theme-base-primary-color-l) + 50 * 1%), 95%));
--theme-primary-custom-200: hsl(var(--theme-base-primary-color-h), calc(var(--theme-base-primary-color-s) + 0 * 1%), clamp(55%, calc(var(--theme-base-primary-color-l) + 35 * 1%), 90%));
--theme-primary-custom-300: hsl(var(--theme-base-primary-color-h), calc(var(--theme-base-primary-color-s) + 0 * 1%), clamp(35%, calc(var(--theme-base-primary-color-l) + 15 * 1%), 75%));
--theme-primary-custom-400: hsl(var(--theme-base-primary-color-h), calc(var(--theme-base-primary-color-s) + 0 * 1%), clamp(20%, calc(var(--theme-base-primary-color-l) + 0 * 1%), 60%));
--theme-primary-custom-500: hsl(var(--theme-base-primary-color-h), calc(var(--theme-base-primary-color-s) + 0 * 1%), clamp(15%, calc(var(--theme-base-primary-color-l) + -14 * 1%), 45%));
--theme-primary-custom-600: hsl(var(--theme-base-primary-color-h), calc(var(--theme-base-primary-color-s) + 0 * 1%), clamp(5%, calc(var(--theme-base-primary-color-l) + -26 * 1%), 30%));
}

Manual addition of theme variables

Section titled Manual addition of theme variables

If you need to apply a theme without using the above function, you can do so by manually adding the variables above to your CSS. The most common use for this approach is when the theme needs to change client-side, such as when allowing the user to change and preview a theme dynamically.

With this approach, we recommend targeting new h/s/l color variables on a parent element that includes .themed class.

HSL
Loading…
theme-primary
theme-primary-100
theme-primary-200
theme-primary-300
theme-primary-400
theme-primary-500
theme-primary-600

Stacks provides CSS variables for fine grained control of theming. These variables allow you to adjust the theming on specific components and elements, as well as body background and font color.

--theme-background-color
--theme-body-font-color
--theme-button-active-background-color
--theme-button-background-color
--theme-button-color
--theme-button-filled-active-background-color
--theme-button-filled-active-border-color
--theme-button-filled-background-color
--theme-button-filled-border-color
--theme-button-filled-color
--theme-button-filled-hover-background-color
--theme-button-filled-hover-color
--theme-button-filled-selected-background-color
--theme-button-filled-selected-border-color
--theme-button-filled-selected-color
--theme-button-hover-background-color
--theme-button-hover-color
--theme-button-outlined-border-color
--theme-button-outlined-selected-border-color
--theme-button-primary-active-background-color
--theme-button-primary-background-color
--theme-button-primary-color
--theme-button-primary-hover-background-color
--theme-button-primary-hover-color
--theme-button-primary-number-color
--theme-button-primary-selected-background-color
--theme-button-primary-selected-color
--theme-button-selected-background-color
--theme-button-selected-color
--theme-link-color
--theme-link-color-hover
--theme-link-color-visited
--theme-post-body-font-family
--theme-post-title-color
--theme-post-title-color-hover
--theme-post-title-color-visited
--theme-post-title-font-family
--theme-tag-background-color
--theme-tag-border-color
--theme-tag-color
--theme-tag-hover-background-color
--theme-tag-hover-border-color
--theme-tag-hover-color
--theme-topbar-accent-border
--theme-topbar-background-color
--theme-topbar-bottom-border
--theme-topbar-height
--theme-topbar-item-background-hover
--theme-topbar-item-border-current
--theme-topbar-item-color
--theme-topbar-item-color-current
--theme-topbar-item-color-hover
--theme-topbar-search-background
--theme-topbar-search-border
--theme-topbar-search-border-focus
--theme-topbar-search-color
--theme-topbar-search-placeholder
--theme-topbar-search-shadow-focus
--theme-topbar-select-background
--theme-topbar-select-color

Stacks allows for further theming various portions of a page. You can simply pair the .themed class with an atomic color stop, and a new theming scope. For this example, we’re using a class name of .theme-team-[xxx] with a unique ID appended.

<div class="bg-theme-primary-740"></div>
<div class="themed theme-team-001 bg-theme-primary-400"></div>
<div class="themed theme-team-002 bg-theme-primary-400"></div>
<div class="themed theme-team-003 bg-theme-primary-400"></div>

<style>
.theme-team-001 {
--theme-base-primary-color-h: 349;
--theme-base-primary-color-s: 81%;
--theme-base-primary-color-l: 58%;
--theme-base-secondary-color-h: 349;
--theme-base-secondary-color-s: 81%;
--theme-base-secondary-color-l: 58%;
}

.theme-team-002 {
--theme-base-primary-color-h: 41;
--theme-base-primary-color-s: 93%;
--theme-base-primary-color-l: 58%;
--theme-base-secondary-color-h: 41;
--theme-base-secondary-color-s: 93%;
--theme-base-secondary-color-l: 58%;
}

.theme-team-003 {
--theme-base-primary-color-h: 288;
--theme-base-primary-color-s: 76%;
--theme-base-primary-color-l: 38%;
--theme-base-secondary-color-h: 288;
--theme-base-secondary-color-s: 76%;
--theme-base-secondary-color-l: 38%;

/* Override colors for dark mode only */
--theme-dark-primary-color-h: 288;
--theme-dark-primary-color-s: 45%;
--theme-dark-primary-color-l: 60%;
--theme-dark-secondary-color-h: 288;
--theme-dark-secondary-color-s: 45%;
--theme-dark-secondary-color-l: 60%;
}
</style>
body
.themed.theme-team-001
C
.themed.theme-team-002
C
.themed.theme-team-003
C
body .theme-light__forced
.theme-light__forced .themed.theme-team-001
C
.theme-light__forced .themed.theme-team-002
C
.theme-light__forced .themed.theme-team-003
C
body .theme-dark__forced
.theme-dark__forced .themed.theme-team-001
C
.theme-dark__forced .themed.theme-team-002
C
.theme-dark__forced .themed.theme-team-003
C
Deploys by Netlify