SCSS
Coding standards for Sass/SCSS code.
Please also follow the CSS coding standards for consistent SCSS code.
Project setup
Add reset styles
To be able to use semantic elements in many use-cases, it makes sense to use a reset script to strip them from any browser default styling. This makes it much easier to style them yourself. You can use any reset script you want, as long as it benefits your project.
The XIP scss library offers a reset (with preset for Angular). Check it out.
Use Sass with SCSS syntax
We use Sass as preprocessor, using the SCSS syntax. For more information and features, read the Sass documentation.
Formatting
We follow the Sass Guidelines. Read these first.
Ordering properties correctly
Ordering your (S)CSS properties makes your code more maintainable and readable. In short, you should order your SCSS rules as follows:
- Sass inheritance.
- Normal css rules.
- Pseudo-classes and pseudo-elements
- Nested rules.
.some-element {
/* Sass inheritance */
@extend something;
@include something;
/* Pseudo-classes and pseudo-elements */
&:hover {
}
&:focus {
}
&::after {
}
/* Nested rules */
&-addition {
}
&--modifier {
}
&__element {
}
}
Example
When we combine all the rules explained above, we get the following examples, bad and good:
🚫 Very bad example
@import url(https://site.com);
$fonts: (Roboto, Arial, sans-serif);
$elementPosition: relative;
$breakpoints: (
'small': 767px,
'medium': 992px,
'large': 1200px,
);
.one,
.second_one,
.anotherOne {
&:hover {
background-color: #ff0000;
color: #ffffff;
}
border-color: rgba(0, 0, 0, 0.1);
color: #ff0000;
&--disabled {
opacity: 0.5;
}
padding: 0.5rem 1rem;
width: 100% / 3;
margin: 0;
@include flex;
}
✅ Good example
@use url('https://site.com');
$fonts: ('Roboto', 'Arial', sans-serif);
$element-position: relative;
$breakpoints: (
'small': 767px,
'medium': 992px,
'large': 1200px,
);
.one,
.second-one,
.another-one {
@include flex;
margin: 0;
width: (100% / 3);
border-color: rgba(0, 0, 0, 0.1);
padding: 0.5rem 1rem;
color: #f00;
&:hover {
background-color: #f00;
color: #fff;
}
&--disabled {
opacity: 0.5;
}
}
Reusing code
Prefer CSS custom properties
Prefer native CSS custom attributes over SCSS variables. Your SCSS code need to be compiled if an SCSS variable changes. CSS custom attributes are computed in the browser, and can be changed at runtime.
Use variables, mixins & functions
Coming soon.
Use @use instead of @import
When you import reusable SCSS code (functions, mixins, variables), include them with @use:
// 🚫 Bad: using @import
@import 'mixins/flex';
@import 'animations/fade-in';
// ✅ Good: using @use
@use 'mixins/flex';
@use 'animations/fade-in';
The @import rule will be deprecated at some point, and it is encouraged to use the new @use rule instead. Read more about the rationale and timeline in the docs.
Use declarative namespaces
Use declarative namespaces. Don’t abbreviate your namespace or use single-letter namespaces. Don’t load modules without a namespace.
Don’t do this:
// 🚫 Bad: using abbreviated implicit namespace
@use 'variables/theme' as c;
button {
color: c.$primary;
}
// 🚫 Bad: loads module without namespace
@use 'variables/theme' as *;
button {
color: $primary;
}
But do this instead:
// ✅ Good: using explicit namespaces
@use 'variables/theme' as colors;
button {
color: colors.$primary;
}
// ✅ Good: using automatic namespace
@use 'variables/theme';
button {
color: theme.$primary;
}
Naming conventions
Use kebab-case for variables, functions and mixins
Use kebab-case (e.g. $my-variable) instead of camelCase or snake_case for variables, functions and mixins.
// 🚫 Bad naming
$myAwesomeVariable: #000;
$my_awesome_variable: #000;
$MY_AWESOME_VARIABLE: #000;
// ✅ Good naming
$my-public-variable: #000;
Prefix private variables, functions and mixins
Prefix variable, function and mixin names that are intended to be used only within the same module (file) with an underscore (e.g. $_my-variable).
This will make your member private when including your module with @use.
Give functions and mixins actionable names
Use function and mixin names that clearly explain what they do. Function and mixin names should therefor include a verb, such as do, render, get or format.
// 🚫 Bad: does not start with a verb
@function color($tint) {
@return map-get($colors, $tint);
}
@mixin reset() {
/* reset code */
}
// ✅ Good: starts with a verb
@function get-color($tint) {
@return map-get($colors, $tint);
}
@mixin apply-reset() {
/* reset code */
}