CSS Module pattern

css module pattern overview

A processor parses a given stylesheet to scan the classes and expose them to JS. It generates a globally unique name for each of them. It packs the developer-defined classes and globally unique classes in a dictionary object:

export const classes = {
    supercool: "supercool_5cEkq2n0x1",
    supernice: "supernice_1kmox6oL39",
    superGreat: "superGreat_1kmox6oL39",
    "super-awesome": "super-awesome_1kmox6oL39",
} // conceptual // class dictionary

We import the dictionary.

import classes from "xxx.module.css";

<Button
classNames={{
        root: classes.xxx, 	// resolves to the processed class
        label: classes.xxx,	// resolves to the processed class
    }}
  >

pattern: a module targets a Mantine component custom variant

In this pattern, the module's purpose is to define the style of a Mantine component custom variant for which we create a name. For example, we may create a PrimaryButton variant of Button. We name the CSS Module with the variant name: PrimaryButton.module.css

We name the classes according to the inner-element they target, such as root or label.

/* PrimaryButton.module.css */
.root {
}

.root:hover {
}

.label {
}

We may then use the classes to inline-customize a Mantine's component instance, or to create a fully-fledged React component variant.

import PrimaryButtonClassNames from "PrimaryButton.module.css";
{/* provide properties */}
<Button
classNames={{
        root: PrimaryButtonClassNames.root,
        label: PrimaryButtonClassNames.label,
    }}
  >

provide the classes object directly

When we follow the inner-element-as-a-classname naming pattern, we may give the CSS-module object directly to classNames, since classNames expects an object with inner-element named properties.

<Button classNames={primaryButtonClassNames}>
earlymorning logo

© 2025 - All rights reserved

CSS Module pattern

css module pattern overview

A processor parses a given stylesheet to scan the classes and expose them to JS. It generates a globally unique name for each of them. It packs the developer-defined classes and globally unique classes in a dictionary object:

export const classes = {
    supercool: "supercool_5cEkq2n0x1",
    supernice: "supernice_1kmox6oL39",
    superGreat: "superGreat_1kmox6oL39",
    "super-awesome": "super-awesome_1kmox6oL39",
} // conceptual // class dictionary

We import the dictionary.

import classes from "xxx.module.css";

<Button
classNames={{
        root: classes.xxx, 	// resolves to the processed class
        label: classes.xxx,	// resolves to the processed class
    }}
  >

pattern: a module targets a Mantine component custom variant

In this pattern, the module's purpose is to define the style of a Mantine component custom variant for which we create a name. For example, we may create a PrimaryButton variant of Button. We name the CSS Module with the variant name: PrimaryButton.module.css

We name the classes according to the inner-element they target, such as root or label.

/* PrimaryButton.module.css */
.root {
}

.root:hover {
}

.label {
}

We may then use the classes to inline-customize a Mantine's component instance, or to create a fully-fledged React component variant.

import PrimaryButtonClassNames from "PrimaryButton.module.css";
{/* provide properties */}
<Button
classNames={{
        root: PrimaryButtonClassNames.root,
        label: PrimaryButtonClassNames.label,
    }}
  >

provide the classes object directly

When we follow the inner-element-as-a-classname naming pattern, we may give the CSS-module object directly to classNames, since classNames expects an object with inner-element named properties.

<Button classNames={primaryButtonClassNames}>