Reusing Style Templates in Sass with @content Mixins: A Practical Guide
Learn how to use Sass mixins with @content to keep component styles DRY while avoiding CSS bloat. Read a concrete example, trade‑offs, and best practices for reusable component styling.
22 Oct 2025, 22:04 UTC

The Problem: Duplicate Component Styles
When you build a UI library or a large application, you often find yourself copying and pasting the same block of CSS across several components. Each copy adds a new selector and increases the compiled file size. It also makes maintenance a nightmare: a change in one component requires hunting every duplicate.
Mixins with @content: The Solution
In Sass, a mixin is a reusable block of styles that can be included anywhere. By adding the @content directive inside a mixin, you create a placeholder that the caller supplies. This pattern lets you keep the common structure in one place while allowing each component to inject its own specific rules.
Key benefits:
- DRY: Core styles live once.
- Encapsulation: Component‑specific overrides stay local.
- Reduced CSS bloat: The
@contentblock is compiled only once per mixin call.
Practical Example: Button Component
Below is a minimal setup that demonstrates how a button mixin with @content can be reused across two components – a primary button and a secondary button.
1. Define the mixin (styles/_button-base.scss)
// styles/_button-base.scss
@mixin button-base($base-color) {
display: inline-block;
padding: 0.5rem 1rem;
border-radius: 4px;
background: $base-color;
color: #fff;
cursor: pointer;
// Allow the caller to inject additional rules
@content;
}
2. Create component files that use the mixin
// styles/primary-button.scss
@import 'button-base';
.primary-button {
@include button-base(#0066cc) {
// Override when hovered
&:hover {
background: darken(#0066cc, 10%);
}
}
}
// styles/secondary-button.scss
@import 'button-base';
.secondary-button {
@include button-base(#999999) {
// Add a subtle border for the secondary style
border: 1px solid darken(#999999, 15%);
}
}
3. Compile (Sass CLI)
# Compile the two component files into a single CSS bundle
# Run from the project root
sass --watch styles/primary-button.scss:dist/primary-button.css \
styles/secondary-button.scss:dist/secondary-button.css
After compilation, inspect dist/primary-button.css and dist/secondary-button.css. You should see the shared base styles duplicated only once per component, while the @content block appears in the appropriate place.
Trade‑offs and Caveats
- Specificity surprises: Because
@contentis inserted at the point of inclusion, nested selectors inside the caller can create unexpected specificity. Always review the generated CSS to ensure it matches your design intent. - Build time: Each mixin call recompiles the
@contentblock. In very large projects with thousands of calls, this can add a few milliseconds to build time. For typical applications, the overhead is negligible. - Complexity for trivial changes: If you only need to tweak a single property, a variable may be simpler than a mixin. Reserve
@contentfor situations where you need to inject multiple rules or nested structures.
Actionable Takeaways
- When you notice repeated selector blocks across components, consider extracting the shared styles into a mixin with
@content. - Keep the mixin lean: only include the truly shared rules, and let the caller provide the variable parts.
- After refactoring, run a quick diff of the compiled CSS to confirm that file size hasn’t increased unexpectedly.
- Use browser dev tools to verify that the final computed styles have the intended specificity and cascade.
By adopting @content mixins thoughtfully, you can keep your Sass codebase DRY, maintainable, and efficient.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.