Color

Materialize offers a lot of colors which can be used in your next project.

Material color roles

Use Material roles when colors should follow the theme. A source color generates a coordinated palette; CSS variables carry that palette to your page and components. The named colors below, such as teal lighten-2, are fixed colors and do not automatically follow the generated palette.

UseBackgroundMatching text
Main actionprimaryon-primary
Soft accent panelprimary-containeron-primary-container
Page or cardsurfaceon-surface
Secondary surfacesurface-varianton-surface-variant
Error messageerror-containeron-error-container

Use background classes and their matching -text classes together. An on-* role is the foreground intended for that background.

<!-- Theme-aware colors, inherited from the nearest theme scope. -->
<div class="card-panel primary-container on-primary-container-text">
  A soft accent panel with its matching text color.
</div>
<button type="button" class="btn filled">Primary action</button>
/* The same roles work in your own CSS. */
.my-panel {
  background: var(--md-sys-color-surface);
  color: var(--md-sys-color-on-surface);
  border: 1px solid var(--md-sys-color-outline-variant);
}

Generate a palette

Install @material/material-color-utilities (already included in these docs). These examples use the package’s TypeScript theme helpers.

// npm install @material/material-color-utilities
import { argbFromHex, themeFromSourceColor, applyTheme } from '@material/material-color-utilities';

// 1. Convert a source hex color to the library's ARGB representation.
// 2. Generate coordinated light and dark schemes.
const theme = themeFromSourceColor(argbFromHex('#6750A4'));

// 3. Write --md-sys-color-* CSS variables onto the target.
applyTheme(theme, { target: document.body, dark: false });

The source color is a seed, so the generated primary color may differ from the exact hex you provided. applyTheme writes variables; elements must use those variables or Material color classes to show the result.

Try page, card, and section themes

Use the color picker to choose a source color, press Save, then choose a mode and target. Try different colors for the card and section to compare them with the page. A locally themed element keeps its palette until you apply a new one or reset it.

Choose a color and target. Previews do not change saved preferences.

Card theme

This card can have its own palette and mode.

Matching container and foreground colors.
Section theme

One wrapper passes its palette to all descendants.

This panel inherits the section’s theme.

Change the whole page

const theme = themeFromSourceColor(argbFromHex('#006B5F'));

function setPageMode(dark: boolean) {
  applyTheme(theme, { target: document.body, dark });
  // Keep Materialize mode selectors and native form controls in sync.
  document.documentElement.setAttribute('theme', dark ? 'dark' : 'light');
  document.documentElement.style.colorScheme = dark ? 'dark' : 'light';
}

setPageMode(window.matchMedia('(prefers-color-scheme: dark)').matches);
// Call setPageMode(true) or setPageMode(false) from your own theme toggle.

Use document.body consistently when that is where your application writes its palette. Variables on body override inherited values from html. Changing only the theme attribute does not regenerate variables written by applyTheme; reapply the matching scheme too.

For this documentation project, its Themes helper also saves the source color and mode in local storage:

// This helper belongs to the documentation project; it is not a library export.
import { Themes } from './themes';

const themes = new Themes(document);
themes.setThemePrimaryColor('#006B5F');
themes.setDarkMode();
// themes.setLightMode();

Theme a card or another element

<!-- The palette is local to this element and its descendants. -->
<div id="project-card" class="card-panel surface on-surface-text">
  <h5>Project card</h5>
  <button type="button" class="btn filled">Open project</button>
</div>
const card = document.querySelector<HTMLElement>('#project-card')!;
const cardTheme = themeFromSourceColor(argbFromHex('#B15C00'));

applyTheme(cardTheme, { target: card, dark: false });
card.style.colorScheme = 'light';

// Use the same approach for a section, toolbar, dialog, or button.
// Applying to a wrapper also themes the children inside it.
// A button can be targeted directly with applyTheme(theme, { target: button, dark: false }).

CSS variables inherit downward, so a local palette does not affect siblings or parents. To follow page mode, reapply each local palette with the new dark value when your theme toggle changes.

A dropdown or tooltip appended to document.body inherits the page palette. To match a themed card, render it inside that scope where the component supports it, or apply the card palette to the popup itself.

// Return a locally themed element to the inherited page palette.
for (const property of Array.from(card.style)) {
  if (property.startsWith('--md-sys-color-')) card.style.removeProperty(property);
}
card.style.removeProperty('color-scheme');

Change only one element color

If you only need a different accent on one component, use another role such as secondary-container, or override a matching token pair locally. A token override does not generate a full palette or a separate dark scheme.

<div class="card-panel secondary-container on-secondary-container-text">
  Uses the existing secondary container colors.
</div>
<button type="button" class="btn filled"
  style="--md-sys-color-primary: #285943; --md-sys-color-on-primary: #ffffff;">
  Local green action
</button>

Prefer generated schemes for light/dark support. If you choose custom pairs, verify their text contrast in every state. Setting --md-sys-color-primary alone does not update on-primary, container colors, or the rest of the palette.

Live preview TypeScript
import {
  applyTheme,
  argbFromHex,
  themeFromSourceColor,
} from "@material/material-color-utilities";
import { Themes } from "./themes";
import "./color-theme-demo.scss";

const seed = document.querySelector<HTMLInputElement>("#theme-demo-seed")!;
const dark = document.querySelector<HTMLInputElement>("#theme-demo-dark")!;
const card = document.querySelector<HTMLElement>("#theme-demo-card")!;
const section = document.querySelector<HTMLElement>("#theme-demo-section")!;
const status = document.querySelector<HTMLElement>("#theme-demo-status")!;
const savedTheme = new Themes(document);
dark.checked = savedTheme.isDarkMode();

// Only CSS tokens on the chosen target change; no saved preference is overwritten.
function previewTheme(target: HTMLElement) {
  const theme = themeFromSourceColor(argbFromHex(seed.value));
  applyTheme(theme, { target, dark: dark.checked });
  target.style.colorScheme = dark.checked ? "dark" : "light";
  if (target === document.body) {
    document.documentElement.setAttribute(
      "theme",
      dark.checked ? "dark" : "light",
    );
    document.documentElement.style.colorScheme = dark.checked
      ? "dark"
      : "light";
  }
}

document
  .querySelector("#theme-demo-page-apply")!
  .addEventListener("click", () => {
    previewTheme(document.body);
    status.textContent = `Page preview: ${seed.value}, ${dark.checked ? "dark" : "light"} mode.`;
  });
for (const [id, target] of [
  ["#theme-demo-card-apply", card],
  ["#theme-demo-section-apply", section],
] as const) {
  document.querySelector(id)!.addEventListener("click", () => {
    previewTheme(target);
    status.textContent = `${target === card ? "Card" : "Section"} preview updated; the page palette is unchanged.`;
  });
}

document.querySelector("#theme-demo-reset")!.addEventListener("click", () => {
  // Remove only generated theme properties, so these examples inherit the page again.
  for (const target of [card, section]) {
    Array.from(target.style)
      .filter((name) => name.startsWith("--md-sys-color-"))
      .forEach((name) => target.style.removeProperty(name));
    target.style.removeProperty("color-scheme");
  }
  const isDark = savedTheme.isDarkMode();
  savedTheme.applyThemeProperties(isDark);
  document.body.style.removeProperty("color-scheme");
  document.documentElement.setAttribute("theme", isDark ? "dark" : "light");
  dark.checked = isDark;
  status.textContent =
    "Saved page theme restored. Card and section inherit it again.";
});
Live preview SCSS
.color-theme-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-block: 16px;
}
.color-theme-controls > label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--md-sys-color-on-surface);
}
.color-theme-controls input[type="color"] {
  width: 48px;
  height: 40px;
  padding: 4px;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: 8px;
}
.color-theme-surface {
  padding: 24px;
  margin-block: 16px;
  border-radius: 16px;
  border: 1px solid var(--md-sys-color-outline-variant);
  background: var(--md-sys-color-surface);
  color: var(--md-sys-color-on-surface);
}
.color-theme-surface h5 {
  margin-top: 0;
}
.color-theme-note {
  padding: 12px 16px;
  border-radius: 12px;
  background: var(--md-sys-color-primary-container);
  color: var(--md-sys-color-on-primary-container);
  margin-block: 16px;
}

Fixed color classes

Here is a color palette based on the material design base colors. Each of these colors is defined with a base color class and an optional lighten or darken class.

Background Color

To apply a background color, just add the color name and light/darkness as a class to the element.

This is a card panel with a teal lighten-2 class
<div class="card-panel teal lighten-2">This is a card panel with a teal lighten-2 class</div>

Text Color

To apply a text color, just append -text to the color class like this:

This is a card panel with dark blue text
<div class="card-panel">
  <span class="blue-text text-darken-2">This is a card panel with dark blue text</span>
</div>

Sass

For background colors, you can apply the color simply by extending the classes like the example below.


  .ilike-blue-container {
    @extend .blue, .lighten-4;
  }
        

For changing text color, you can apply the color simply by extending the classes like the example below.


  .ilike-blue-container {
    @extend .blue-text, .text-lighten-4;
  }
        

Color Palette

Borders

Every color also has a -border variant, applying it to border-color instead of background-color. Combine it with a shade class exactly like the background/text variants (teal-border darken-2).

teal-border darken-2
red-border accent-3
amber-border
<div class="card-panel teal-border darken-2" style="border: 3px solid;">teal-border darken-2</div>
<div class="card-panel red-border accent-3" style="border: 3px solid;">red-border accent-3</div>
<div class="card-panel amber-border" style="border: 3px solid;">amber-border</div>

Light/Dark Mode Colors

light-mode-* and dark-mode-* variants apply a color only while the system is actually in that color scheme (via @media (prefers-color-scheme: ...)) - the other one does nothing. Put both on the same element to pick a different color per scheme automatically, without any JS:

Indigo lighten-2 in light mode, amber darken-2 in dark mode - switch your system's appearance to see it change.
<div class="card-panel light-mode-indigo dark-mode-amber lighten-2-light-mode darken-2-dark-mode">
  Indigo lighten-2 in light mode, amber darken-2 in dark mode
</div>

The base color (no shade) is simpler - no extra suffix needed:

<div class="card-panel light-mode-red dark-mode-blue">
  Plain red in light mode, plain blue in dark mode
</div>

Text and border follow the same pattern: light-mode-*-text/dark-mode-*-text and light-mode-*-border/dark-mode-*-border.

Gradients

30 ready-made two-color gradients, each named gradient-45deg-<start>-<end>. Add gradient-shadow alongside one for a drop shadow tinted to match the gradient's end color (like the two below).

<div class="gradient-45deg-purple-pink" style="height: 80px;"></div>
<div class="gradient-45deg-orange-deep-orange gradient-shadow" style="height: 80px;"></div>

light-blue-teal + shadow

indigo-light-blue + shadow

light-blue-indigo + shadow

yellow-green + shadow

orange-deep-orange + shadow

deep-purple-purple + shadow

red-pink + shadow

light-green-amber + shadow

amber-amber + shadow

purple-pink + shadow

teal-cyan + shadow

blue-grey-blue-grey + shadow

orange-amber + shadow

indigo-blue + shadow

brown-brown + shadow

blue-grey-blue + shadow

purple-deep-orange + shadow

green-teal + shadow

purple-light-blue + shadow

cyan-cyan + shadow

yellow-teal + shadow

purple-deep-purple + shadow

cyan-light-green + shadow

purple-amber + shadow

indigo-purple + shadow

deep-purple-blue + shadow

deep-orange-orange + shadow

light-blue-cyan + shadow

blue-indigo + shadow

semi-dark + shadow