Keep Stylus Nesting Shallow: A Practical Cap for Component CSS
Use Stylus & nesting for BEM-style components, but cap depth at two or three levels to control specificity and keep overrides simple.
18 Nov 2025, 18:12 UTC

Your component stylesheet starts clean: a .card block with a title and a featured modifier. Six months later, that same file nests .card inside .section inside .layout, and a utility class can no longer override a button color because the generated selector carries more specificity than your team intended. Specificity is the browser’s system for deciding which rule wins when several rules match the same element. Stylus makes it too easy to keep indenting.
The useful takeaway is simple: use Stylus’s & parent-reference operator for BEM-style nesting—Block, Element, Modifier—but enforce a hard cap of two or three levels. Compile the file, inspect the flattened selectors, and pin the compiler version so upgrades do not silently change your output.
What the & operator actually does
In Stylus, & refers to the selector of the enclosing rule. A nested block such as &__title inside .card becomes .card__title in the output. Because Stylus is a build-time compiler, the browser receives static CSS only; there is no preprocessor runtime and no client-side parsing cost.
That convenience is also the risk. Every level of nesting repeats the parent selector and adds specificity. A selector produced from four or five nested blocks can override utility classes and make later exceptions harder to write.
A worked example: card component with a depth cap
This example keeps nesting at two levels: the block, then its element and modifier. It does not nest a modifier inside an element, which would produce a third level such as .card__title--featured.
$accent = #0b6efd
.card
padding: 1rem
border: 1px solid #ddd
&__title
font-size: 1.25rem
margin: 0 0 0.5rem
&--featured
border-color: $accent
Expected flattened output structure:
.card {
padding: 1rem;
border: 1px solid #ddd;
}
.card__title {
font-size: 1.25rem;
margin: 0 0 0.5rem;
}
.card--featured {
border-color: #0b6efd;
}
Compile the source from your project root. This assumes Stylus is installed as a local dependency.
./node_modules/.bin/stylus src/components/card.styl --out dist/css/card.css --sourcemap card.css.map
- Where to run: project root, in a terminal.
- Permissions: read access to the source file and write access to the output directory; no elevated privileges required.
- Placeholders: replace
src/components/card.stylanddist/css/card.csswith your actual paths. - Expected checks: confirm
dist/css/card.cssexists, contains.card__titleand.card--featured, and thatcard.css.mapappears next to it. - Risks: the command overwrites an existing output file with the same name; different Stylus versions may handle whitespace or property syntax differently.
Why cap nesting at two or three levels
Specificity accumulates quickly. A selector such as .layout .section .card__title is harder to override than .card__title, and it ties your CSS to a particular HTML structure. If a designer later moves the title outside the card, the rule stops applying. Limiting nesting keeps selectors flat, predictable, and easier to refactor.
A practical team rule is: allow the block and one nested level, such as &__element or &--modifier. Stop there. If you need a variation of an element, add a class to the HTML rather than nesting another & block inside the element.
Limitations and verification
- Stylus has a smaller ecosystem than PostCSS or Tailwind. Confirm editor syntax highlighting, formatter support, and any plugins before adopting it for a new project.
- Pin the compiler version in
package.json, runstylus --versionto record it, and review release notes before upgrading. Syntax and mixin behavior can differ across releases. - Enable sourcemaps in your render options or CLI command. In browser devtools, inspect an element and confirm the rule maps back to a line in the
.stylsource, not just the generated CSS file.
Actionable closing
Add the depth cap to your component style guide and review it during pull requests. After compiling, grep the output for selectors with more than three compound parts; if you find one, flatten it before merging. A short Stylus file with shallow nesting compiles to CSS that is easier to debug, override, and delete when the component changes.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.