CSS layers

All of Todae's CSS sits in one cascade layer, todae, so a company design system or an app places Todae with a single name. Inside it, in order:

  • todae.reset: reserved for a reset. It is empty.
  • todae.base: tokens, styles for native elements such as links and disclosures, and the visually hidden classes.
  • todae.components: the styles of every part.
  • todae.theme: a company's tokens, written by todae-tokens build. See Build on Todae.

A later layer beats an earlier one whatever the selectors, and CSS outside any layer beats every layer.

Unlayered CSS needs no setup

Plain stylesheets, CSS Modules and vanilla-extract's default output are unlayered, so they beat Todae with no setup. A class you put on a part wins over Todae's styles for that part, except the few !important rules described below.

Declare the order once, first

When your stack has layers of its own, write one @layer statement that names them all, at the top of your CSS entry, before anything loads. A layer's place is fixed where it is first named, and later statements cannot move it.

Put todae after any reset and before your components and utilities:

@layer reset, todae, acme, app;

A company design system on Todae puts its own component CSS in its layer (acme here), so product code in a later layer or unlayered still wins over it.

Import Todae's CSS from the same CSS file, after the statement. Importing it from JavaScript before that file loads names todae first, and every other layer then beats it.

Tailwind CSS 4

Tailwind 4 uses the layers theme, base, components and utilities, and its reset (preflight) is in base. Put todae after base:

@layer theme, base, todae, components, utilities;

@import 'tailwindcss';
@import '@tounsoo/todae/todae.css';
@import './todae-theme.css';

Preflight then loses to Todae's styles, and utilities such as bg-red-500 or px-8 on a part win over Todae's. With Todae ahead of base, preflight removes button backgrounds and link underlines; with Todae after utilities, a utility on a part loses wherever Todae sets the same property.

To use Todae's tokens in utilities, map them with @theme inline:

@theme inline {
  --color-accent: var(--todae-color-accent-default);
  --color-muted: var(--todae-color-fg-muted);
}

Without inline, Tailwind sets the variable on :root, so every utility takes the value computed there. It does not follow data-appearance, ThemeProvider or button variants below the root.

Tailwind CSS 3

Tailwind 3 writes no cascade layers: its @layer is its own directive, and the output is unlayered, so preflight beats every Todae layer. Put preflight in a layer with postcss-import 15 or later, listed before tailwindcss in your PostCSS config. postcss-import does not read the package's exports, so import Todae's CSS by its file path:

@layer tw-base, todae;

@import 'tailwindcss/base' layer(tw-base);
@import '@tounsoo/todae/dist/todae.css';
@import './todae-theme.css';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';

Or turn preflight off with corePlugins: { preflight: false } and keep @tailwind utilities.

!important

!important reverses the layer order: an important declaration in an earlier layer beats one in a later layer, and any important declaration beats a normal one. Todae marks only the rules that must hold, such as todae-visually-hidden and hidden tab panels, so !important utilities cannot undo them. A Tailwind ! utility does beat Todae's normal styles.