Skip to content

Instantly share code, notes, and snippets.

What would you like to do?

Start with a boilerplate

Use variables

For colors, font sizes, spacings etc. Avoid magic numbers.

Use meaningful variable names: $color-visual-grid not $color or $vslgrd-clr.

Don't name the color variables based on the color, but on a function instead. So if the main color of the brand is yellow, use $brand-primary instead of $yellow.

You will need to define multiple shades of a color. To make it clear how light or dark the shade is, use suffixes incrementing by 100, just like defined here. Base color can start with 500, with lighter going down, and darker going up.


When adding declarations for multiple selectors place each of the selectors in a new line. Don’t write property values that you don’t need - so instead of margin: 0 0 $m-base 0 only override bottom. For readability, you can also nest these declarations (see the example below). So be careful with shorthands, as you can override something you didn't mean to. Most of the time they're not recommended, except for flex, where it's recommended.

Sort the declarations alphabetically (your IDE probably already has a keyboard shortcut or a plugin for that), with mixins at the top.

        size: $font-size-lg
        weight: $font-weight-bold
        bottom: $m-base
        top: $m-sm

Helper classes

Using helpers classes, like text-center is fine, provided this is the only class added to this element. If you're adding multiple classes, this is a good case for using BEM.

If the element already has a class, eg. section__header and you'd like to modify it, add a modifier class like -centered.

Mixins vs extends

TL;DR: use mixins. If you think you want to @extend, never do it on a .class but on a %placeholder instead. If you want to know when to use which check this out - if not, I'm cool with using just mixins, that's how I do it. Even if the mixin does not accept any parameter, it's easy to add that option. If you had used a placeholder extend, you would need to change it to a mixin, and change every occurence of that extend throughout your code.

Further explanation why not to extend:


  • Use the SASS syntax.
  • Use hyphens when naming mixins, extends, classes & variables: span-columns not span_columns or spanColumns.
  • Use space between property and value: width: 20px not width:20px.
  • Use a blank line above selector that has styles.
  • Use single quotation marks for attribute selectors and property values.
  • Use only lowercase, including colors.
  • Don’t add unnecessary units, eg 0px vs 0, unless required by a mixin
  • Don’t add 0 before fractions, like opacity: 0.7 vs opacity: .7

Use BEM-ish syntax

We use a slight modification of BEM. So get familiar with the regular BEM first, and then instead of button__content button__content--sm you would just use button__content -sm. Note that -sm is not a global modificator, it will work only with button__content. In SASS you can refer to it like this:

        padding: $m-sm $m-base

            padding: $m-xs $m-sm

Please note that this:


is not BEM, as footer-links should be your base after which you can add __wrapper, __column etc.

Also if the BEM documentation didn't make it clear enough, please don't do this footer__links__column.


  • Don't use ID's for style.
  • Avoid styling by tag, like .nav li. Only general tag styling overrides are allowed, like setting margins on p.
  • Avoid using the direct descendant selector >.
  • Avoid nesting more than 3 selectors deep.
  • Don't nest more than 4 selectors deep.
  • Avoid using HTML tags on classes: .widgets not div.widgets.

Media queries

Know the values of breakpoints, they’re set in variables. It's OK to add another breakpoint, for example for very large screens or for other orientation, but don't set custom, magic-numbered breakpoints for patching layout issues, eg. @media (max-width: 1399px) and (min-width: 1350px)

Add all media queries at the bottom of the file, for readability you can also separate them with a comment so it’s easier to spot.

When writing media queries start with mobile-first and use mostly min-width. Write smaller screen sizes first. Use mixins for that:

//----- media queries ---------------------------------------------------------------------------------
        font-size: $font-size-xl

There are too many devices to test them all, but the resolutions to pay the most attention to are:

  • 320px - this is the minimum resolution where your website should be working nicely. At least until Galaxy Fold becomes popular, with 280px of width when fold
  • 768px - tablets portrait
  • 1024px - tablets landscape
  • Desktops: 1280px, 1366px, 1920px

Using !important is alright (sometimes)

But you need to know when to use it. One case is for helpers, that you always want to make sure work, like:

    color: $brand-danger !important

The other could be overriding inline styles that are for example introduced by a JS plugin and cannot be removed in any other way.

Support the browsers that you need to

Don’t add any vendor prefixes, it’s the job of autoprefixer.

If you want to use a property that is new and you’re not sure if the browsers you’re developing for support it, check on caniuse. Install Chrome/Safari/Firefox and test on these browsers.

For IE11/Edge we have a Windows laptop. We have an iPad, iPhone 5 and 7, and some Android phones. If that does not cover your needs, for iOS there’s the Simulator in Xcode, and for Android the Android Studio.

You can also test with browserstack. I'm also considering lambdatest

VirtualBox with IE machines should be a solution of last resort, as the performance of it is really poor.

Don’t keep unnecessary files

Make sure you remember about CSS when removing that feature that the client decided not to use.

Try removing instead of adding

When we try to fix stuff it’s common to start adding rules, but first, try removing instead.

Files should not be longer than 300 lines

When approaching that limit know when to refactor.

Setup a linter

Locally / on a CLI

Copy link

Darex1991 commented Jan 14, 2019


  "extends": ["stylelint-config-standard", "stylelint-config-prettier"],
  "plugins": ["stylelint-order"],
  "rules": {
    "at-rule-no-unknown": null,
    "at-rule-semicolon-space-before": "never",
    "block-no-empty": true,
    "block-opening-brace-space-before": "always",
    "color-hex-case": "upper",
    "color-hex-length": "long",
    "color-named": "never",
    "declaration-colon-space-after": "always-single-line",
    "function-name-case": null,
    "declaration-empty-line-before": [
        "ignore": ["after-declaration", "inside-single-line-block"]
    "function-comma-space-after": "always-single-line",
    "indentation": 2,
    "length-zero-no-unit": true,
    "max-nesting-depth": [5, { "ignore": ["blockless-at-rules"] }],
    "max-empty-lines": 1,
    "no-descending-specificity": null,
    "number-leading-zero": "never",
    "order/properties-alphabetical-order": true,
    "rule-empty-line-before": [
        "except": ["first-nested"]
    "selector-list-comma-newline-after": "always",
    "selector-list-comma-newline-before": "never-multi-line",
    "selector-pseudo-element-colon-notation": "single",
    "unit-whitelist": ["rem", "%", "px", "vw", "vh", "deg", "s", "vmax", "vmin"],
    "value-list-comma-space-after": "always-single-line"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment