.selector{property:value;}.another-selector{another-property:another-value;}.am-i-related-to-that-stuff-above{seriously:'who knows';}#tlec.col-b#more-tleo-promo.promo-entry{oh-god:'this is really paranoid';}
Why is it so hard?
People write new CSS for everything.
Everything goes into the global scope.
Not inherently obvious how selectors interrelate.
Build Smaller, Isolated Things
Single Responsibility
Do one thing and do it well
Single Responsibility
Components
Macro-layout
Theming
Composition
Create Lego bricks to clip together
Be Additive
Mobile first & extend from core functionality
Build Bottom Up
Base Styles → Components → Pages
Naming Conventions
Give hints about how elements interrelate
BEM
<divclass="media media--right"><divclass="media__img"><imgsrc="cats.gif"alt=""/></div><divclass="media__body">
Now you've got a hint that I belong to
the media block when reading HTML
</div></div>
$breakup-included-blocks:('basic','thin');@mixinbreakup-block($block-name){@ifindex($breakup-included-blocks,$block-name)!=false{@content;}}@includebreakup-block('basic'){.a{content:'I shall be output';}}@includebreakup-block('wide'){.b{content:'I shall *not* be output';}}
Media Query Wraps
$breakup-included-blocks:('basic','thin');$breakup-naked:false;@mixinbreakup-media($declaration,$allow-naked:false){@ifnot$breakup-naked{@media#{$declaration}{@content;}}@else{@if$allow-naked==true{@content;}}}@includebreakup-media('(min-width: 36em)',true){.c{content:'I am wrapped in a MQ';content:'unless $breakup-naked is true';}}
Breakpoints
@mixinbreakup-breakpoint($breakpoint-name){// Not a real function
$mq-declaration:find-mq-from-name($breakpoint-name);@includebreakup-block($breakpoint-name){@includebreakup-media($mq-declaration,true){@content;}}}
Tweakpoints
// _component.scss
@includebreakup-tweakpoint('(min-width: 45em)','wide'){.component{content:'From tweakpoint within wide';}}// Equivalent to:
@includebreakup-block('wide'){@includebreakup-media('(min-width: 45em)'){.component{content:'From tweakpoint within wide';}}}