CSS Codebase Structuring:
no more headache

Andrey
Mikhaylov

github.com/lolmaus

goo.gl/8cV086

  • BEM
  • OOCSS
  • SMACSS
  • MVCSS
  • SUCKS

Let the
holy war
begin!

Use a
CSS preprocessor

    Node: libsass

Ruby: Sass

All styles applied only via BEM-like blocks

Only semantic
HTML classes

Boo

rap

tst

A component

.mainMenu
 

.mainMenu-header
 

.mainMenu-menuItem
 

.mainMenu-menuItem-icon
 

.mainMenu-expandButton

mainMenu.sass

All component files go into one folder, forming a flat list

Modifier classes

SMACSS

BEM

.main-menu__item-icon--active
.main-menu__item-icon--expanded
.main-menu__item-icon--visible

.is-active
.is-expanded
.is-visible

.mainMenu-itemIcon.-active
.mainMenu-itemIcon.-expanded
.mainMenu-itemIcon.-visible.-expanded

Modifier classes

.foo-bar

  color: black

 

  &.-active

    color: red


  &.-expanded

    font-weight: bold

 

  &.-visible

    opacity: 1

.foo-bar {

  color: black; }

 

.foo-bar.-active {

  color: red; }

 

.foo-bar.-expanded {

  font-weight: bold; }

 

.foo-bar.-visible {
  opacity: 1; }

Modifier classes

State

Kind

-active
-visible
-expanded

_home
_services
_pricing

.mainMenu

  .mainMenu-item._home
  .mainMenu-item._services.-active
  .mainMenu-item._pricing
  .mainMenu-item._login
  .mainMenu-item._signup

Every element is responsible for:
 

  • own looks
  • own positioning
    in the parent context
  • own looks
  • positioning its immediate content

"Internal"
properties

"External"
properties

​Make sense on the element alone
 

  • border
  • padding
  • color
  • background

​Make sense in the element's parent context

  • float
  • margin
  • top, left и т. д.
  • z-index

.foo-bar {

  color: red; }

.foo .foo-bar {

  float: red; }

?

width

position

vertical-align

.menu

  border: 10px


.menu-item

  line-height: 18px

  font-size:   14px

  float:       left

.menu

  border: 10px

 

  .menu-item

    float: left


.menu-item

  line-height: 18px

  font-size:   14px

  

"External" element style in the context of its parent

.menu

  border: 10px

 

  .menu-item

    float: left

 

.menu-item

  line-height: 18px

  font-size:   14px

  

"External" element style in the context of its parent

.menu {

  border: 10px; }

 

.menu .menu-item {

  float: left; }

 

.menu-item {

  line-height: 18px;

  font-size:   14px; }

 

.foo

  display: table

  width:   100%

 

  .foo-bar

    display: table-row

 

.foo-bar

  .foo-bar-baz

    display: table-cell

 

.foo-bar-baz

  text-align:     center

  vertical-align: middle

.foo

  display: table

  width:   100%

 

 

 

 

.foo-bar

  display: table-row

 

 

.foo-bar-baz

  display:    table-cell

  text-align:     center

  vertical-align: middle

.foo

  display: table

  width:   100%

 

  .foo-bar

    display: table-row

 

.foo-bar

  .foo-bar-baz

    display: table-cell

 

.foo-bar-baz

  text-align:     center

  vertical-align: middle

.foo {

  display: table;

  width: 100%; }

 

. foo .foo-bar {

  display: table-row; }

 

 

.foo-bar .foo-bar-baz {

  display: table-cell; }

 

.foo-bar-baz {

  text-align: center;

  vertical-align: middle; }

.foo

  display: table

  width:   100%

 

  .foo-bar

    display: table-row

 

  .foo-bar-baz

    display:    table-cell

    text-align:     center

    vertical-align: middle

 

 

 

 

.foo-bar-baz

  background: red

.foo {

  display: table;

  width: 100%; }

 

.foo .foo-bar {

  display: table-row; }

 

.foo .foo-bar-baz {

  display: table-cell;

  text-align: center;

  vertical-align: middle; }

 

 

 

Grouping "external" styles under common context

 

.foo-bar-baz {

 background: red; }

.foo

  display: table

  width:   100%

 

  .foo-bar

    display: table-row

 

.foo-bar

  .foo-bar-baz

    display: table-cell

 

.foo-bar-baz

  text-align:     center

  vertical-align: middle

Too verbose! :(

Applying "internal" styles conditionally, based on parent state

.foo-baz

  font-weight: normal

 

  .foo.-active &

    font-weight: bold

.foo-baz {

  font-weight: normal; }

 

.foo.-active .foo-baz {

  font-weight: bold; }

.foo

  .foo-bar

  .foo-baz

    .foo-baz-quux._alpha

    .foo-baz-quux._beta

  .foo-zomg

.foo.-active

  .foo-bar

  .foo-baz

    .foo-baz-quux._alpha

    .foo-baz-quux._beta

  .foo-zomg

.foo.-active

  .foo-bar

  .foo-baz.-active

    .foo-baz-quux._alpha.-active

    .foo-baz-quux._beta.-active

  .foo-zomg

.foo.-active

  .foo-bar

  .foo-baz

    .foo-baz-quux._alpha

    .foo-baz-quux._beta

  .foo-zomg

External style

.foo-baz

  font-weight: normal

 

  .foo.-active &

    font-weight: bold

.foo-baz {

  font-weight: normal; }

 

.foo.-active .foo-baz {

  font-weight: bold; }

Internal style + modifier

.foo

  .foo-baz

    width: 10%

 

.foo-baz

  width: 50px

.foo .foo-baz {

  width: 10%; }

 

 

.foo-baz {

  width: 50px; }

Component example

.foo

  color: red

 

  .foo-baz

    width: 10%

 

 

 

.foo-baz

  width: 50px

 

  .foo.-active &

    font-weight: bold

.foo {

  color: red; }

 

.foo .foo-baz {

  width: 10%; }

 

 

 

.foo-baz {

  width: 50px; }

 

.foo.-active .foo-baz {

  font-weight: bold; }

.block
  .block-title
  .block-content

Styling a component differently depending on where it is used

Styling a component differently depending on where it is used

Bad :(

Not much better :/

.sidebar

  .block-title
    font-weight: bold

  .block-content
    border: 5px dashed black

block.sass

.articleList

  .block-title
    font-family: OpenSans

  .block-content
    background-color: deepskyblue

articleList.sass

sidebar.sass

.block-title

  .sidebar &
    font-weight: bold

  .articleList &
    font-family: OpenSans

 

.block-content

  .sidebar &
    border: 5px dashed black

  .articleList &
    background-color: deepskyblue

Styling a component differently depending on where it is used

block/

sidebar.sass

articleList.sass

=block-fancy

  .block-title

    font-weight: bold

  .block-content

    border: 5px dashed black
    

=block-cosmic

  .block-title

    font-family: OpenSans

  .block-content

    background-color: deepskyblue 

.sidebar

  +block-fancy

.articleList

  +block-cosmic

block.sass

.block

  font-weight: normal

block/block-mixins.sass

Polymorphic components

route/

.route-posts

  background: red

 

  .welcomeMessage

    float: left

route.sass

.route

  font-weight: normal

route/posts-index.sass

.route-postsIndex

  background: blue

 

  .companyLogo

    float: right

route/posts.sass

.route-postsPost

  background: green

 

  .whatever

    float: left

route/posts-post-index.sass

.route-postsPostIndex

  background: black

 

  .doYouKnowTheMuffinMan

    float: right

route/posts-post.sass

Thank you! ^_^

Andrey
Mikhaylov

github.com/lolmaus

goo.gl/8cV086

CSS codebase structuring

By Andrey Mikhaylov (lolmaus)

CSS codebase structuring

  • 1,388