CSS @ Scale

Writing Maintainable Styles

Mike Selander

CSS is Easy

CSS is Easy
Hard

CSS is Easy
First-Class

Avoid Specificity Like the Plague

Specificity:

1. A really hard to say word

2. A measure of how certain that a selector will take precedent

p { ... }
1 😄
.class { ... }, selector:hover
10 🙂
#id { ... }
100 😱

1,000 💩
p !important { ... }
1,000,000,000 💩🔥
.list-item { ... }
10
ul ol li.red  { ... }
13
li.red.level { ... }
21
ul#summer-drinks li { ... }
102
body #content .data img:hover { ... }
122

Classes offer high clarity with low specificity

Avoid:

html body .group p span .something-specific { ... }

Prefer:

.something-specific { ... }

Classes
Are King

  1. Low specificity, high clarity
  2. Classes can be re-used
  3. We can stack classes, but not IDs
  4. We can decouple markup from styling

Title

Text

Text

  • List item

Title

Text

...

Title

Text

Text

  • List item

Title

Text

...
.element > div p {
    color: blue;
}

Title

Text

Text

  • List item

Title

Text

...
.element > div > div p {
    color: blue;
}

Title

Text

Text

  • List item

Title

Text

...
.element > div > div:not(:last-child) p {
    color: blue;
}

Title

Text

Text

  • List item

Title

Text

...
.element > div > div:not(:last-child) p,
.element > div > div:not(:last-child) li {
    color: blue;
}

Title

Text

Text

  • List item

Title

Text

...
.element > div > div:not(:last-child) p,
.element > div > div:not(:last-child) li {
    color: blue;
}

Title

Text

Text

  • List item

Title

Text

...
.blue-text {
    color: blue;
}

Use ________ Naming Methodology

Naming conventions provide
logic
to your classes

It's not which methodology you choose, it's choosing one at all

Many Options

  • BEM ← 😍
  • OOCSS
  • ITCSS

BEM

Block
.block
.human
Element
.block__element
.human__arm
Modifier
.block--modifier
.human--standing

:root is Your Friend

:root is always the highest-level "parent" element

:root gives us a single place to define global styles

Avoid:

.header { line-height: 1.5; ... }
.main { line-height: 1.5; ... }
.sidebar { line-height: 1.5; ... }
.footer { line-height: 1.5; ... }
...

Prefer:

:root { line-height: 1.5; ... }

Bonus:
:root is also where your CSS variables land

:root {
	--bkg-color: black;
	...
}

Start with a blank slate

Normalizing Styles

  • Preserves useful defaults.
  • Normalizes styles.
  • Corrects bugs and common browser inconsistencies.
  • It's super easy to use!

Install

$ npm install --save normalize.css

Use

@import "~normalize.css"

Co-locate
(and break up)
Your CSS

Avoid:

-> blocks
	-> my-block.php

-> styles
	-> my-block.scss

-> src
	-> my-block.js

Prefer:

-> blocks
	-> my-block
		-> index.js
		-> block.php
		-> styles.scss

Document
your CSS

Types of Documentation

  • File Documentation
  • Section Documentation
  • Inline Documentation

File Documentation

/**
 * Button styles.
 */

/**
 * WordPress-specific styles
 *
 * Styles for over-riding or adapting WordPress-specific classes and hacks.
 * The HTML used with these styles is out of our control, and thusly may not
 * adhere to our normal standards.
 */

Section Documentation

/**
 * Media query mixins.
 *
 * All styles should be written mobile-first, only a limited few should be max-width.
 */

/**
 * Colors
 */

/**
 * Breakpoints
 */

Inline Documentation

/* The high-specificity is necessary to override the Bootstrap style . */
.my-class__item a:nth-of-type(3n):after { /* … */ }

/* Prevent a sliver of the photo from showing up behind the banner */
transform: translate( 1px, 1px );

/* All WP images should get some margin and start out centered. */
[class*="wp-image"] {
	display: block;
	margin: 10px auto;
}

/*
* Multiline comments are formatted with asterisk
* at the start of each line.
*/

Find
a style guide

Lots of Options

Use
Stylelint

Stylelint

A mighty, modern linter that helps you avoid errors and enforce conventions in your styles.

Install

$ npm install @humanmade/stylelint

Use

$ stylelint "foo/*.css"

Autoprefix
All the Things

Autoprefixer:

Parses CSS and adds vendor prefixes to rules, automagically

.example {
    display: grid;
    transition: all .5s;
    user-select: none;
    background: linear-gradient(to bottom, white, black);
}
.example {
    display: -ms-grid;
    display: grid;
    -webkit-transition: all .5s;
    -o-transition: all .5s;
    transition: all .5s;
    -webkit-user-select: none;
       -moz-user-select: none;
        -ms-user-select: none;
            user-select: none;
    background: -webkit-gradient(linear, left top, left bottom, from(white), to(black));
    background: -o-linear-gradient(top, white, black);
    background: linear-gradient(to bottom, white, black);
}

Thank You!

🐦 @Mike_Selander

But wait, there's more!

  • Sass vs Stylus vs CSS vs ...
  • CSS Variables vs CSS Modules vs SCSS Variables
  • Serving a single stylesheet vs code splitting
  • Critical delivery building
  • Webpack vs Parcel vs Grunt
  • CSS in JS 😱🙅‍♂️
  • The meaning of life