Senior Front-end developer at bet365.com
Author of the books:
Enduring CSS a.k.a. ECSS is an approach to authoring and maintaining style sheets for rapidly changing, long-lived web projects
I can't tell you ECSS is the way but it is a way
Tried and tested over a year by 20-30 developers
Styles a site generating a large portion of a £34 billion annual turnover
First wrote about ECSS in August 2014. Refining it ever since
The term is quite nebulous. Could be:
Medium.com The world isn't short of idealistic advice on how you should write CSS
But these approaches may not cater for the problems you have and the interfaces you need to build
Can anyone give me an example of a complex web-based UI?
There are probably only a handful of web UIs in the world that are this complex by necessity
To exemplify; the notion that all buttons could inherit styles from a common ancestor is simply unrealistic
What's wrong with OOCSS, SMACSS & BEM?
That doesn't mean they are solving your problems
Didn't suit because:
Logical conclusion
Responsive: What happens when the abstraction needs to do something different in a different scenario?
Iteration: When an element needs changing, it'll then need two touch points; template and style sheets
Didn't suit because:
.is-disabled {}
Much to take from BEM but didn't suit entirely:
--
which I associate with custom properties (and syntax highlighters can struggle with)
Nothing quite solved the problems I had
"Goodartistscoders copy, greatartistscoders steal"
Selector | Inline | ID | Class | Type |
---|---|---|---|---|
.widget | 0 | 0 | 1 | 0 |
aside#sidebar .widget | 0 | 1 | 1 | 1 |
.class-on-sidebar .widget | 0 | 0 | 2 | 0 |
"If you're having CSS problems I feel bad for you son, I got 99 problems but specificity ain't one."
The micro-namespace provides a context so we could have an entirely different object in a different context; free to mutate as needed
ECSS is the antithesis of OOCSS. Rather than abstract we isolate
We're used to grouping files by technology:
Instead we group by module:
Makes the removal of deprecated code far simpler
Easy code removal is important:
Two years ago I wrote a book where I was preaching DRY code, but after working on enduring projects (BBC News and theguardian.com responsive sites), it's "decoupling" that became more important to me. Say it with me: Kay Leeg Duh Loo Moh Pree Jon (silent N)
A user does something:
is-Suspended
is-Live
is-Busy
But now we have ARIA
Class handles aesthetics, aria-* handles state
Only just moving to using ARIA in this manner!.co-Button {
background-color: $color-button-passive;
&[aria-live="polite"] {
background-color: $color-button-selected;
}
}
Two touch-points for JavaScript: classes and attributes (rather than just one)
button.setAttribute("aria-disabled", "true");
Some older WebKit versions (e.g. Android stock browser 4.0.3) fail to recalculate styles on attribute changes. There are simple workarounds but it's something to be aware of
Blessed are those that follow these rules for they shall inherit sane style sheets
Amen
ECSS uses PostCSS to enable a Sass-like syntax and facilitate additional tooling*
*More on tooling shortly
.key-Selector {
width: 100%;
@media (min-width: $M) {
width: 50%;
}
.an-Override_Selector & {
color: $color-grey-33;
}
}
A key selector should only be found as the root of a rule once in the entire project: a single source of truth
An even specificity across rules allows for more manageable style sheets
Autoprefixer means you can author styles as intended
$size-full: 11px;
$size-half: 5.5px;
$size-quarter: 2.75px;
$size-double: 22px;
$size-treble: 33px;
$size-quadruple: 44px;
Variables serve large projects well by normalising sizing and colours
Better to think of variables as const
.med-Video {
position: relative;
background-color: $color-black;
font-size: $text13;
line-height: $text15;
/* At medium sizes we want to bump the text up */
@media (min-width: $M) {
font-size: $text15;
line-height: $text18;
}
/* Text and line height changes again at larger viewports */
@media (min-width: $L) {
font-size: $text18;
line-height: 1;
}
}
Errant px values that aren't pre-defined in the variables should serve as a red flag
Any non-standard values or browser specific hacks should be commented
Don't do this:
.rr-Outfit {
min-height: $size-quadruple;
background-image: url(data:image/gif;base64,iVBORw0KGgoAAAANSUh
EUgAAABAAAAAQCAMAAAAoLQ9TAAAAA3NCSVQICAjb4UgAAAAw1BMVEX///8AAAC
EhIQAAABYWFgAAAAAAAAAAAB6enomJiYAAAAiIiJ4eHgAAABiYmJgYGAAAACJiY
kAAAC0tLR/f3/IyMjHx8e/v7+vr6+fn5+ZmZmUlJSBgYFmZmYiIiIQEBAAAAD//
//w8PDv7+/i4uLh4eHf39/W1tbS0tLR0dHMzMzHx8fFxcXCwsK/v7+4uLi0tLSv
r6+rq6ulpaWfn5+ZmZmQkJCPj498fHxwcHBgYGBAQEAwMDAgICAfHx8QEBAAAAA
phWZmAAAAQXRSTlMAESIiMzNEVWZmZneIiKqqu8zM3d3u7u7u7u7u7u7u7u7///
//////////////////////////////////////wP/q/8AAAAJcEhZcwAACxIAAA
sSAdLdfvwAAAAVdEVYdENyZWF0aW9uIFRpbWUAMjEvNS8xMpVX8IQAAAAcdEVYd
FNvZnR3YXJlAEFkb2JlIEZpcmV3b3JrcyBDUzVxteM2AAAAw0lEQVQYlU2P6VLC
UAyFD1KvWFQ2F1ChnLLW2oIs1ZZC8/5PRW4rM+RH5uSbLCeARt2YO2Pq+I+aafU
AAAAAElFTkSuQmCC);
}
Instead do this:
.rr-Outfit {
min-height: $size-quadruple;
background-image: inline("/path/to/relevant-image.png");
}
Lean on tooling where it can provide a better authoring experience
Only move as far as necessary from standard CSS; makes static analysis easier
PostCSS facilitates incredible tools for CSS
An ECSS approach benefits from a number of tools in the PostCSS eco-system
Autoprefixer remains the gold standard for automatically adding any needed vendor prefixes
Use it!
Stylelint is a Node based linting tool for the static analysis of style sheets
var stylelintConfig = {
"rules": {
"color-hex-case": "lower",
"color-hex-length": "short",
"color-named": "never",
"color-no-invalid-hex": true,
"font-family-name-quotes": "always-where-required",
"font-weight-notation": "numeric",
"function-comma-newline-before": "never-multi-line",
"function-comma-newline-after": "never-multi-line",
"function-comma-space-after": "always",
"function-comma-space-before": "never",
"function-linear-gradient-no-nonstandard-direction": true,
"function-max-empty-lines": 0
}
};
I keep my full config here
Code QAs just got a whole lot easier!
Bonus: My esteemed colleague Peter Griffiths made a Sublime plugin to give you direct feedback in the editorcssnano is a modular CSS minifier. Use the features you want, switch off the ones you don't. Easy bolt-on to your PostCSS build
Devised a system, written extensive docs, briefed the team, added tooling
4 months later
.P2 .bb-ParticipantBettingBanner .ip-Participant_OppName {
padding-left: 11px;
margin-right: .5em;
@media (min-width: 640px) {
& .ip-Participant_OppName {
display: inline-block;
}
}
}
With many devs, conventions are difficult to enforce
Good will and documentation only get you so far
If there's a way to screw things up, people will find it
You need to continually refine your process
More rules!
This is not particular to ECSS. But if you're about to start on a similar journey, I hope some of what follows may be useful
Test and re-test the approach. Don't grab something 'off the shelf' and stick it into production
Ensure you document what didn't work
"Those who cannot remember the past are condemned to repeat it"
Be ready to adapt. We started with utility styles (e.g. u-w50) but found they caused more problems than they solved
There are many ways to solve these problems. Evaluate approaches against your own requirements
There's lot's more in the book: http://leanpub.com/enduringcss
Offer: $5 off
http://leanpub.com/enduringcss/c/slides
bet365 are hiring. Always happy to talk to talented developers