Using Stylus Silent Mixins to Keep CSS Lean
Learn how Stylus silent mixins let you define reusable style blocks that only appear in the compiled CSS when called, reducing bloat while keeping your stylesheets maintainable.
28 Aug 2026, 01:09 UTC

The Problem: Unused Styles Bloating Your CSS
When you start extracting reusable patterns into mixins, it's tempting to define a mixin for every variation. If those mixins are always included, the compiler copies their properties into every selector that calls them, even when you only need a subset. This can cause unnecessary duplication and increase file size.
What Are Silent Mixins in Stylus?
Stylus offers a silent flag for mixins. A silent mixin defines a block of styles that is not emitted into the CSS unless the mixin is explicitly invoked. This lets you keep a library of utility patterns without paying the cost of unused definitions.
Defining a Silent Mixin
To make a mixin silent, prefix its name with a ! or use the silent keyword (depending on Stylus version). The body of the mixin behaves like any other; it accepts arguments and can contain nested selectors.
// Run: stylus input.styl -o output.css
!silent-card(padding = 16px, bg = #fff)
display block
padding padding
background-color bg
border-radius 8px
box-shadow 0 2px 4px rgba(0,0,0,0.1)
// Normal usage
.alert
!silent-card(12px, #ffe5e5)
border 1px solid #f0c0c0
.hero
!silent-card()
background-image url('/hero.jpg')
Because the mixin is silent, the CSS only appears where it is called. If you never call !silent-card, nothing is added to the output.
Worked Example: Building a Theme‑Aware Button Set
Imagine a design system where buttons share a base shape but vary in color and size depending on the theme. Rather than repeat the padding, border‑radius, and transition properties, we place them in a silent mixin and pass the theme values as arguments.
// Define silent base button
!btn-base(size = medium, theme = default)
font-size:
if size == small 12px
else if size == large 20px
else 16px
padding:
if size == small 6px 12px
else if size == large 12px 24px
else 8px 16px
border-radius 4px
transition background-color 0.2s ease
// Theme colors
background-color:
if theme == primary #0066ff
else if theme == danger #ff4444
else #ffffff
color:
if theme == primary #ffffff
else if theme == danger #ffffff
else #333333
// Apply to different selectors
.primary-btn
!btn-base(size = large, theme = primary)
.secondary-btn
!btn-base(theme = secondary) // uses default size medium
.small-link
!btn-base(size = small, theme = default)
text-decoration none
Compile the file with stylus buttons.styl -o buttons.css. Inspect buttons.css; you will see three rule sets, each containing the properties generated from the mixin with the appropriate arguments. No extra CSS is produced for the mixin definition itself.
Trade‑off: Readability vs. File Size
Silent mixins keep the generated CSS lean because they avoid emitting unused code. However, they introduce an extra layer of indirection. When debugging in the browser, the DevTools show the final CSS properties, not the mixin name, which can make tracing the source back to the Stylus file slightly harder. Teams often mitigate this by commenting the mixin call or using source maps if their build pipeline supports them.
Practical Verification Steps
- Install Stylus locally:
npm install --save-dev stylus - Create a file
mixins.stylwith the silent mixin example above. - Run
npx stylus mixins.styl -o mixins.css. - Open
mixins.cssand confirm that only the selectors that call the mixin contain properties, and that the mixin block does not appear as a standalone rule. - If you comment out all calls and recompile, the output file should be empty (aside from any global styles).
This quick check confirms that the silent flag works as expected and helps you decide whether to adopt the pattern in your project.
Closing Action
Audit your existing Stylus files for mixins that are defined but never conditionally varied. If a mixin is simply a collection of static properties that you reuse, consider turning it into a silent mixin and calling it only where needed. This will keep your CSS output minimal while preserving the authoring convenience of reusable style blocks.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.