How to support dark mode

BetaThis feature is new and we're actively working to improve it. Updated

You can customize how your message appears in dark mode when a user’s device or inbox is set to that preference.

Why set dark mode styles?

Dark mode is increasingly the default setting across devices and email clients. As customer expectations shift toward modern design standards, supporting dark mode helps:

  • Reduce broken email experiences by providing intentional styling
  • Increase readability with properly contrasted colors designed for dark backgrounds
  • Meet accessibility standards and user preferences
  • Reduce support complaints about poor email rendering in dark mode

Where to set dark mode styles

You can set default, global dark mode styles in Styles. You can also modify dark mode styles of standard components while editing an email and code custom components to support dark mode.

To set dark mode for global styles, go to Set global styles.

In this article, you’ll learn how to set dark mode styles on standard and custom components, the building blocks of Design Studio emails.

Limitations

For now, there is no UI feature to streamline image swapping or advanced layout changes based on dark mode. You’ll have to add these changes to the code editor.

Not all email clients support dark mode styles. Some email clients, like Gmail, force dark mode, which automatically changes the colors of your email, whether you set dark mode styles or not.

Add dark mode styles to standard components

You can globally set dark mode styles for standard components in Styles. You’ll define your colors under Variables then assign these variables to light or dark mode for standard components under Components.

You can also change the styles for individual emails that deviate from your global branding.

To change a dark mode color through the visual editor:

  1. Click a standard component.
  2. Find a color property like text color, background/fill, or border color.
  3. Set your default color or choose a different global style variable.
  4. Click the moon icon to open dark mode.
  5. Set the color for dark mode or choose a different global style variable.
  6. Click the moon toggle at the top of the editor to preview your message in dark mode.

Your changes save automatically. Remember to publish your changes if the email is connected to a campaign, broadcast, etc.

This feature also supports the email client Thunderbird so our out-of-the-box dark mode styles are compatible with more email clients!

Add dark mode styles to custom components

Currently, you’ll have to code dark mode into custom components. Try out our GPT made for custom components to get started faster!

  1. Create a custom component file.
  2. Create properties with schema that enable dark mode.
  3. Set a function to define the values of properties depending on if they’re objects or strings.
  4. Set variables to process the property values.
  5. Create a style object that references your variables.
  6. Reference the style object in the template.

In this example, we’ll create a custom component so you can specify dark mode styles for background and text colors through the visual editor.

<!--
  Insert this component in your email with the following code:

  <dark-mode-test></dark-mode-test>
-->
<script>
  export const config = {
    label: "dark mode test",
    presets: [
      {
        label: "dark mode test",
        content: `<dark-mode-test></dark-mode-test>`
      }
    ]
  };

  export const slots = Component.defineSlots({
    default: {
      schema: Component.slots.text(),
    },
  });

  export const props = Component.defineProps({
    'background':{
      section: 'Styles',
      label: 'Fill',
      schema: Component.props
        .withDynamicStyles(Component.props.string(), {
          darkMode: true,
      })
      .optional(),
      type: 'background',
    },
    'color':{
      section: 'Styles',
      label: 'Color',
      schema: Component.props
        .withDynamicStyles(Component.props.string(), {
          darkMode: true,
      })
      .optional(),
      type: 'color',
    }
  });

  function lightDark(value) {
    if (typeof value === 'object') {
      return {
        light: value.light || '',
        dark: value.dark || undefined,
      };
    }
    if (typeof value === 'string') {
      return { light: value, dark: undefined };
    }
  }

  const newColor = lightDark(props.color);
  const newBackground = lightDark(props.background);

  const styleObject = {
    color: newColor?.light,
    background: newBackground?.light,
  };
</script>
<style #if="newColor?.dark || newBackground?.dark">
  @media (prefers-color-scheme: dark){
    .dark{
      color: set(newColor?.dark) !important;
      background: set(newBackground?.dark) !important;
    }
  }
</style>
<style  #if="newColor?.dark || newBackground?.dark" media="(prefers-color-scheme: dark)" isolated="thunderbird">
  .moz-text-html .dark{
      color: set(newColor?.dark) !important;
      background: set(newBackground?.dark) !important;
    }
</style>
<template>
  <div :style="styleObject" class="dark">
    <slot>Content goes here</slot>
  </div>
</template>

Create dark mode-enabled properties

If you’re building a custom component and want it to support dark mode, any properties that should respond to theme changes, like colors or backgrounds, must be marked as dynamic.

Use .withDynamicStyles() in your property schema to ensure those styles update automatically when the theme changes.

schema: Component.props
  .withDynamicStyles(Component.props.string(), {
    darkMode: true
  })
  .optional(),
  • Component.props.string() is one of the validation types you can use to define your property.
  • darkMode is a boolean. After you’ve added your custom component to the visual editor, click it to open the Properties panel. When darkMode is set to true, you’ll see the dark mode moon toggle in the panel. Click it to set the style.

Set a function to handle light/dark property outputs

This function sets up the ability for your custom component to pass light and dark mode values, ensuring that you always get an object with both light and dark properties, even if one or both are not explicitly provided in the initial input.

  function lightDark(value) {
    if (typeof value === 'object') {
      return {
        light: value.light || '',
        dark: value.dark || undefined,
      };
    }
    if (typeof value === 'string') {
      return { light: value, dark: undefined };
    }
  }

Set variables to process the property values

Then define two variables, one for the text color and one for the background color, to use in a style object we can reference in our template.

const newColor = lightDark(props.color);
const newBackground = lightDark(props.background);

Create a style object to reference in your template

Finally, add a style object to the script tag so you can reference these properties in the template.

const styleObject = {
  color: newColor?.light,
  background: newBackground?.light,
};

Add your style object to the template

Now you can reference the style object in the content of the custom component through the template tag.

<template>
  <div style="styleObject">
    <slot>
      Content goes here
    </slot>
  </div>
</template>

Add @media queries to support more email clients

After your script tag, add style tags to define dark mode styles.

Here we’ve added two style tags. The first includes a generic media query that sets a class dark. The second isolates styles needed to support Thunderbird. Learn more about the attribute prefers-color-scheme

<style #if="newColor?.dark || newBackground?.dark">
  @media (prefers-color-scheme: dark){
    .dark{
      color: set(newColor?.dark) !important;
      background: set(newBackground?.dark) !important;
    }
  }
</style>
<style  #if="newColor?.dark || newBackground?.dark" media="(prefers-color-scheme: dark)" isolated="thunderbird">
  .moz-text-html .dark{
      color: set(newColor?.dark) !important;
      background: set(newBackground?.dark) !important;
    }
</style>

Then in the template tag you’d add class="dark".

<template>
  <div :style="styleObject" class="dark">
    <slot>Content goes here</slot>
  </div>
</template>
Copied to clipboard!
  Contents
Is this page helpful?