53
Scalable CSS Architecture Artur Kot & Michał Pierzchała

Scalable CSS Architecture

Embed Size (px)

Citation preview

Page 1: Scalable CSS Architecture

Scalable CSS Architecture

Artur Kot & Michał Pierzchała

Page 2: Scalable CSS Architecture

Does it even exist?

Scalable CSS? Maintainable CSS?

Page 3: Scalable CSS Architecture

What we need

Modularity Encapsulation Predictability

Page 4: Scalable CSS Architecture

What we have

Page 5: Scalable CSS Architecture

What we really have

Cascade Global namespace Selectors specificity

Page 6: Scalable CSS Architecture

Solution?

Page 7: Scalable CSS Architecture

–David Heinemeier Hansson

“Convention over configuration”

Page 8: Scalable CSS Architecture

Like in JavaScript

Embrace the good parts Throw away the bad parts

Page 9: Scalable CSS Architecture

Introducing

Page 10: Scalable CSS Architecture

ITCSSInverted Triangle

CSS

Page 11: Scalable CSS Architecture
Page 12: Scalable CSS Architecture

// main.scss

@import 'settings/*'; @import 'tools/*'; @import 'generic/*'; @import 'elements/*'; @import 'objects/*'; @import 'components/*'; @import 'trumps/*';

Page 13: Scalable CSS Architecture

used with preprocessors font definitions, colours, variables, etc.

1. Settings

2. Toolsglobally used mixins and functions

Page 14: Scalable CSS Architecture

normalising styles box-sizing

3. Generic

4. Elementsbare HTML elements

reset lists, anchors, etc

Page 15: Scalable CSS Architecture

simple & reusable containers, grids, global animations, etc

5. Objects

6. Componentsactual UI

CSS ❤ components

Page 16: Scalable CSS Architecture

utilities and helper classes visibility, alternative colours

override anything

7. Trumps

Page 17: Scalable CSS Architecture
Page 18: Scalable CSS Architecture

Some constraints and recommendations

Page 19: Scalable CSS Architecture

Groups order is crucial (Inner order doesn’t matter)

Page 20: Scalable CSS Architecture

Avoid “!important”

Page 21: Scalable CSS Architecture

Use BEM (Block Element Modifier)

Page 22: Scalable CSS Architecture

<section class="c-component c-component--small"> <div class="c-component__bg"></div> <h2 class="c-component__heading">A component!</h2> <div class="c-component__child"> Lorem ipsum dolor sit amet, consectetur adipisicing elit <button class="c-component__grandchild">inside</button> </div> </section>

Page 23: Scalable CSS Architecture

• .[component-name]__[child]—[modifier] • Remember that it’s on only a convention! • Use 🍌 instead of __ or 🍓instead —

if you like • Important: separation of the parent

element and its children. • Be consistent.

Page 24: Scalable CSS Architecture

JS hooks

• .js-[name] • readonly to identify DOM elements for JS • can’t be styled!

Page 25: Scalable CSS Architecture

State classes

• .is-[name] • .has-[name] • should be used in favour of —modifiers

in case a component changes its state after the page is loaded

• handy to use with JS

Page 26: Scalable CSS Architecture

Resist from nesting

Page 27: Scalable CSS Architecture

Temptation to target tags.c-my-list li { [item styles] }

<ul> <li> <div class=”c-some-component-with-a-list”> <ul> <li>another list!</li> <li> and now you need to override

.c-my-list li with stronger selector...</li> </ul> </div> </li> </ul>

Page 28: Scalable CSS Architecture

• You can’t predict the future. It’s possible that a sneaky designer could design a nested list inside your element. What to do then? More nesting. :)

• It, obviously, works but what if you’ve got identical list but with divs instead of lis?

• Usually, nesting is like a domino effect: one innocent nested selector results in dozen deeper nested selectors. Avoid when possible.

Page 29: Scalable CSS Architecture

You can’t entirely avoid nesting. It’s impossible.

The goal is to minimise it and its side effects.

Page 30: Scalable CSS Architecture

.c-component { /* third-party code */ .super-slick-slider { float: left !important; }

/* state affects children */ &.is-open { .c-component__grandchild { display: block; }

.c-component__inner { display: flex; }

.c-component__inner-most { color: red; } } }

Page 31: Scalable CSS Architecture

.c-component { /* state classes */ &.is-open, &.has-popup { display: block; } /* state pseudo-selectors */ &:hover, &:focus, &:nth-child(2n) { border-bottom: 1px solid; }

/* relationships */ + &, ~ &, > &, * { display: none; } }

Page 32: Scalable CSS Architecture

Do Repeat Yourself

If it makes your life easier (usually does)

extra bytes will be squashed by gzip anyway…

Page 33: Scalable CSS Architecture

Tricky MQ nesting

.c-component { @media { &.is-cos { @media { color: red; } } } }

.c-component { color: blue;

@media { color: red; }

&.is-cos { @media { color: yellow; } } }

BAD GOOD

Page 34: Scalable CSS Architecture

Keep it tidy

Page 35: Scalable CSS Architecture

Sync filenames with naming

/* _my-pretty-component.scss: */

.c-my-pretty-cmp { color: brown; }

/* _my-pretty-component.scss: */

.c-my-pretty-component { color: blue; }

BAD GOOD

Page 36: Scalable CSS Architecture

Do not mix components with each other

Page 37: Scalable CSS Architecture

Not in stylesheets

/* Some time before */

.c-my-box { width: 320px; }

.c-my-box__inner { padding: 20px; background: blue;

.c-my-other-box { color: white; } }

/* Few weeks later… */

.c-my-other-box { color: white;

/* Doesn’t work :( */ &--pink { color: pink;

} }

Page 38: Scalable CSS Architecture

Nor in the markup<div class=”c-boxie c-footer”></div>

.c-boxie { display: block; }

.c-footer { display: flex; }

What display will it get?

Page 39: Scalable CSS Architecture

Objects for reusability Components for explicitness

Page 40: Scalable CSS Architecture

Use objects for mixing with component!

<div class=”o-boxie c-footer”></div>

.o-boxie { display: block; }

Page 41: Scalable CSS Architecture

Trumps are the new “!important”

Page 42: Scalable CSS Architecture

<h3 class=”o-title t-color-blue”>Heading</h3>

.o-title { font-size: 12px; color: red; }

/* trumps/utilities.scss */

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

Page 43: Scalable CSS Architecture

It’s easier to maintain separated UI components than ones mixed in HTML markup

Take it serious

Page 44: Scalable CSS Architecture

It Just Works™ for CSS, SCSS, LESS

Page 45: Scalable CSS Architecture

Piece of cake

Critical CSS or PRPL?

Page 46: Scalable CSS Architecture

/* critical.index.scss */

@import 'settings/*'; @import ‘tools/*'; @import 'generic/*'; @import 'elements/*'; @import 'components/colorbar'; @import 'components/header'; @import 'components/hero';

Page 47: Scalable CSS Architecture

Kinda

Use in existing messy codebase?

Page 48: Scalable CSS Architecture

Gradual adoptionNeeds pre-/post-processor (sorry CSS 😞)

#create #strongest #selector { @import 'settings/*'; @import 'tools/*'; @import 'generic/*'; @import 'elements/*'; @import 'objects/*'; @import 'components/*'; @import 'trumps/*'; }

Page 49: Scalable CSS Architecture

With predefined and ready to use (or remove) components

Featured in Chisel, our new project generator

Page 50: Scalable CSS Architecture
Page 51: Scalable CSS Architecture

ITCSSISAWESOMER

Page 52: Scalable CSS Architecture

Cool JS-based alternatives

CSS Modules CSS in JS

Available with Webpack & Browserify

Page 53: Scalable CSS Architecture

Thank you.

Artur Kot & Michał Pierzchała