Sass offers powerful tools to manage styles more efficiently, among which @extend and inheritance stand out. These features allow you to share styles across different selectors, reducing redundancy and maintaining consistency. This guide explores how to use @extend and inheritance in Sass to create cleaner, more maintainable stylesheets.
What is @extend in Sass?
The @extend directive allows one selector to inherit the styles of another. This means you can apply the styles of a base selector to multiple other selectors, promoting style reuse and reducing redundancy.
Example:
.button {
padding: 10px 20px;
background-color: blue;
color: white;
border: none;
border-radius: 5px;
}
.primary-button {
@extend .button;
background-color: darkblue;
}
Compiled CSS:
.button, .primary-button {
padding: 10px 20px;
background-color: blue;
color: white;
border: none;
border-radius: 5px;
}
.primary-button {
background-color: darkblue;
}
Benefits of Using @extend:
- Reduces Redundancy: Share styles between selectors without duplicating code.
- Consistent Styling: Ensure consistent styles across different elements by inheriting common base styles.
- Improved Maintainability: Update styles in one place, propagating changes across all selectors that extend the base style.
How to Use @extend and Inheritance:
Basic Inheritance:
Use @extend to allow one selector to inherit the styles of another.
Example:
// Define base styles
.notice {
padding: 15px;
margin: 10px 0;
border: 1px solid transparent;
border-radius: 4px;
}
// Extend base styles
.success {
@extend .notice;
background-color: #dff0d8;
border-color: #d6e9c6;
}
.error {
@extend .notice;
background-color: #f2dede;
border-color: #ebccd1;
}
Compiled CSS:
.notice, .success, .error {
padding: 15px;
margin: 10px 0;
border: 1px solid transparent;
border-radius: 4px;
}
.success {
background-color: #dff0d8;
border-color: #d6e9c6;
}
.error {
background-color: #f2dede;
border-color: #ebccd1;
}
Using Placeholders with %extend:
Placeholders, denoted by %, are special selectors that only exist to be extended. They do not generate any CSS on their own.
Example:
// Define a placeholder
%message {
padding: 10px;
margin: 5px 0;
border: 1px solid #ccc;
}
// Extend the placeholder
.info {
@extend %message;
background-color: #d9edf7;
border-color: #bce8f1;
}
.warning {
@extend %message;
background-color: #fcf8e3;
border-color: #faebcc;
}
Compiled CSS:
.info, .warning {
padding: 10px;
margin: 5px 0;
border: 1px solid #ccc;
}
.info {
background-color: #d9edf7;
border-color: #bce8f1;
}
.warning {
background-color: #fcf8e3;
border-color: #faebcc;
}
Combining @extend with Nested Selectors:
@extend works seamlessly with nested selectors, allowing you to extend nested styles.
Example:
// Define nested base styles
.panel {
border: 1px solid #ddd;
padding: 10px;
.panel-heading {
font-weight: bold;
}
.panel-body {
padding: 10px;
}
}
// Extend nested styles
.card {
@extend .panel;
}
Compiled CSS:
.panel, .card {
border: 1px solid #ddd;
padding: 10px;
}
.panel .panel-heading, .card .panel-heading {
font-weight: bold;
}
.panel .panel-body, .card .panel-body {
padding: 10px;
}
Avoiding Specificity Issues:
While @extend is powerful, it can sometimes lead to specificity issues if overused or misused. Be mindful of how selectors are combined and consider using mixins for more complex styles.
Example:
// Use `@extend` for simple base styles
%button-base {
padding: 10px 20px;
border-radius: 5px;
}
// Use mixins for more complex scenarios
@mixin button-variant($bg-color) {
background-color: $bg-color;
color: #fff;
}
.button-primary {
@extend %button-base;
@include button-variant(blue);
}
.button-secondary {
@extend %button-base;
@include button-variant(green);
}
Compiled CSS:
.button-primary, .button-secondary {
padding: 10px 20px;
border-radius: 5px;
}
.button-primary {
background-color: blue;
color: #fff;
}
.button-secondary {
background-color: green;
color: #fff;
}
Organizing Extensions and Inheritance:
Organize your base styles and extensions logically to maintain a clean and readable codebase.
Example Directory Structure:
scss/
base/
_buttons.scss
_notifications.scss
components/
_cards.scss
_panels.scss
main.scss
base/_buttons.scss:
%button-base {
padding: 10px 20px;
border-radius: 5px;
}
components/_cards.scss:
.card {
@extend %button-base;
background-color: #fff;
border: 1px solid #ddd;
}
main.scss:
@import 'base/buttons';
@import 'components/cards';
Best Practices for Using @extend:
- Use Placeholders: Prefer placeholders over standard selectors for shared styles to prevent unwanted CSS output.
- Keep Extensions Simple: Avoid complex extensions that can lead to specificity and maintenance issues.
- Combine with Mixins: Use mixins for more complex, reusable styles that require parameters or need to be included conditionally.
- Organize by Functionality: Group related styles and extensions logically to keep your stylesheets organized and maintainable.
Conclusion:
Sass @extend and inheritance provide powerful tools for sharing and reusing styles across different selectors. By leveraging these features, you can create efficient, maintainable, and consistent stylesheets. Using @extend along with placeholders and combining it with mixins when necessary will help you manage complex styles effectively and streamline your CSS development workflow.