CSS Architecture
for large scale applications
Nikos Zinas
@nzinas
Frontend architect @ bestseller.com
Step 1
Create your
Coding styleguide
All code in any code-base should look like a single person typed it, no matter how many people contributed
- idiomatic.js
Create your Coding styleguide
Decide on your base style
- Tabs VS spaces
- Single VS Double quotes
- New lines & identation
- Brace format
- Commenting format
- CamelCase VS under_scores VS da-shes
No point arguing over these. You just need to pick one and stick to it.
Create your Coding styleguide
Aim for readbility
.rule-one, .rule-two {
/* Stuff */
}
.rule-one,
.rule-two {
/* Stuff */
}
VS
Create your Coding styleguide
Aim for readbility
VS
.rule-one {
color: blue; background: red; font-weight: bold;
}
.rule-one {
color: blue;
background: red;
font-weight: bold;
}
Create your Coding styleguide
Defining best practices
but first lets talk about
Specificity
Create your Coding styleguide
#main-navigation .item {
color: blue;
}
nav .items li.item[data-tag="has-submenu"] {
color: green;
}
<nav id="main-navigation">
<ul class="items">
<li class="item">First item</li>
<li class="item">Second item</li>
<li class="item" data-tag="has-submenu">Third item</li>
</ul>
</nav>
Specificity
Create your Coding styleguide
Specificity
Element selectors
Class and attribute selectors
Id selectors
Inline styles
!important
Create your Coding styleguide
High specificity is bad because...
nav .items li.item[data-tag="has-submenu"] {
color: green;
}
It hurts reusability
Create your Coding styleguide
High specificity is bad because...
nav .items li.item[data-tag="has-submenu"] {
color: green;
}
It's error prone
Create your Coding styleguide
High specificity is bad because...
#main-navigation .item {
color: blue;
}
It's hard to override
Create your Coding styleguide
Limit specificity
Don't use !important
Don't use inline styles
Don't use ids
Don't use long selectors
(max 3)
Don't overqualify
Create your Coding styleguide
Avoid descendant/child selectors
nav .items .item {
/* Bad */
}
nav > .items > .item {
/* Bad */
}
.nav-items {
/* Good */
}
.nav-item {
/* Good */
}
Create your Coding styleguide
Name your classes meaningfully
but don't be semantic for the sake of semantics
.redText {
border: 1px dotted green;
background: white;
}
Create your Coding styleguide
Separate your styles from your javascript hooks
.js-* works great
Step 2
Define your methodology
Define your methodology
SMACSS
Define your methodology
SMACSS
Separates rules in categories
- Base
- Layout
- Module
- State
- Theme
Define your methodology
OOCSS
Define your methodology
OOCSS
a CSS object is a repeating visual pattern, that can be abstracted into an independent snippet of HTML
Define your methodology
OOCSS
Separate structure and appearance
Container agnostic objects
Define your methodology
Atomic CSS
Define your methodology
Atomic CSS
Builds ecosystems
Composes pages out of components
Define your methodology
BEM
(Block Element Modifier)
Define your methodology
Block
A reusable component
Element
One piece of the component
Modifier
Different state for a component
or an element
BEM
(Block Element Modifier)
Define your methodology
BEM
(Block Element Modifier)
/* Block */
.car {}
/* Elements */
.car__door {}
.car__trunk {}
.car__wheel {}
/* Modifiers */
.car--cabrio {}
.car--cabrio .car__trunk {}
.car__wheel--17in {}
.car--cabrio .car__wheel--17in {}
Step 3
Use a preprocessor
Use a preprocessor
Use a preprocessor
Variables
/* Color definitions */
$gray: #333333;
$lightgray: #999999;
/* Base variables */
$headerColor: $gray;
$borderColor: $lightgray;
/* Base styles */
h1, h2, h3, h4, h5, h6 {
color: $headerColor;
}
Use a preprocessor
Mixins
/* Eliminate vendor prefixes */
.something-with-a-vertical-gradient {
@include background-image(linear-gradient($light-gray, $gray));
}
/* Calculate */
@mixin font-size($font-size, $line-height:true){
font-size:$font-size;
font-size:($font-size / $base-font-size)*1rem;
@if $line-height == true {
line-height:ceil($font-size / $base-line-height)
* ($base-line-height / $font-size);
}
}
.a-block-of-text {
@include font-size(12px);
}
/* Stay DRY */
.container-with-floated-children {
@include clearfix;
}
Use a preprocessor
Placeholders and extends
%btn {
padding: 10px;
border-radius: 5px;
display: inline-block;
cursor: pointer;
text-decoration: none;
}
.btn {
@extend %btn;
color: blue;
background: transparent;
}
.btn--success {
@extend %btn;
color: white;
background: green;
}
.btn--error {
@extend %btn;
color: white;
background: red;
}
Step 4
Create your styleguide
Create your styleguide
A living styleguide is a document containing all the modules and components of your application, fully functional and interactive
Create your styleguide
- Design consistency
- Easier testing
- Minimize code
- Communication
Why?
Step 6
Measure your results
Measure your results
cssstats.com
Measure your results
stylestats.org
Measure your results
csslint.net
Closing remarks
CSS is easy
to break
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
Step on the shoulders of giants
Thank you!
@nzinas
(Old) CSS Architecture for large scale applications
By Nikos Zinas
(Old) CSS Architecture for large scale applications
- 1,273