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