CSS Module patterns

CSS module primer

CSS module overview

A CSS module is a regular stylesheet (CSS file) whose classes are subject to processing.

A processor parses the classes in the stylesheet (such as superGreat) and derive a unique name for them (such as superGreat_1kmox6oL39). It then transforms the stylesheet to use those unique classes instead.

.superGreat /* pre-processing */
.superGreat_1kmox6oL39 /* post-processing */

Since the developer only knows about the initial class names, the processor creates a JS object that maps the initial name (such as superGreat) to its generated value. We then embed the values in the className or classNames props:

import classes from "xxx.module.css";
/* {
    superGreat: "superGreat_1kmox6oL39",
} */
<div className={classes.superGreat}></div> // superGreat_1kmox6oL3

Note: We avoid hyphens in class names because JavaScript lookup for variables with hyphens requires quotes:

<div className={classes["super-great"]}></div> // superGreat_1kmox6oL3

Mantine pattern

targeting inner-elements (naive version)

import classes from "xxx.module.css";
/* {
    superCool: "superCool_5cEkq2n0x1",
    superNice: "superNice_1kmox6oL39",
    superGreat: "superGreat_1kmox6oL39",
} */

<Button
classNames={{
        root: classes.superCool, // "superCool_5cEkq2n0x1"
        label: classes.superNice,	// "superNice_1kmox6oL39",
        section: classes.superGreat, // "superGreat_1kmox6oL39",
}
    }}
  >

target inner elements (name classes according to inner elements)

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

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

.root:hover {
}

.label {
}

We then apply the classes on the Mantine's instance:

import PrimaryButtonClassNames from "PrimaryButton.module.css";

  {/* verbose */}
<Button
classNames={{
        root: PrimaryButtonClassNames.root,
        label: PrimaryButtonClassNames.label,
    }}
  >

When we follow the inner-element-as-a-classname pattern, we can give the map directly to classNames, since it matches exactly what is expected by classNames:

  {/* short */}
<Button classNames={PrimaryButtonClassNames}>

module name

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

earlymorning logo

CSS Module patterns

CSS module primer

CSS module overview

A CSS module is a regular stylesheet (CSS file) whose classes are subject to processing.

A processor parses the classes in the stylesheet (such as superGreat) and derive a unique name for them (such as superGreat_1kmox6oL39). It then transforms the stylesheet to use those unique classes instead.

.superGreat /* pre-processing */
.superGreat_1kmox6oL39 /* post-processing */

Since the developer only knows about the initial class names, the processor creates a JS object that maps the initial name (such as superGreat) to its generated value. We then embed the values in the className or classNames props:

import classes from "xxx.module.css";
/* {
    superGreat: "superGreat_1kmox6oL39",
} */
<div className={classes.superGreat}></div> // superGreat_1kmox6oL3

Note: We avoid hyphens in class names because JavaScript lookup for variables with hyphens requires quotes:

<div className={classes["super-great"]}></div> // superGreat_1kmox6oL3

Mantine pattern

targeting inner-elements (naive version)

import classes from "xxx.module.css";
/* {
    superCool: "superCool_5cEkq2n0x1",
    superNice: "superNice_1kmox6oL39",
    superGreat: "superGreat_1kmox6oL39",
} */

<Button
classNames={{
        root: classes.superCool, // "superCool_5cEkq2n0x1"
        label: classes.superNice,	// "superNice_1kmox6oL39",
        section: classes.superGreat, // "superGreat_1kmox6oL39",
}
    }}
  >

target inner elements (name classes according to inner elements)

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

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

.root:hover {
}

.label {
}

We then apply the classes on the Mantine's instance:

import PrimaryButtonClassNames from "PrimaryButton.module.css";

  {/* verbose */}
<Button
classNames={{
        root: PrimaryButtonClassNames.root,
        label: PrimaryButtonClassNames.label,
    }}
  >

When we follow the inner-element-as-a-classname pattern, we can give the map directly to classNames, since it matches exactly what is expected by classNames:

  {/* short */}
<Button classNames={PrimaryButtonClassNames}>

module name

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