Skip to main content

SCSS

Coding standards for Sass/SCSS code.

These are additional standards

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.

Use the XIP reset script

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:

  1. Sass inheritance.
  2. Normal css rules.
  3. Pseudo-classes and pseudo-elements
  4. 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';
Deprecation warning

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 */
}