CSS in the Age of Components
Back at the dawn of time, CSS, once of the first standards from the W3C, came along to save us from table based layouts, spacer gifs, and the font tag. And there was much rejoicing.
But fast forward (nearly) 20 years, and we’ve long since run into some pretty significant limitations of CSS, particularly when building complex reusable components and sophisticated application like experiences.
Along the way, we’ve tried various approaches to modularising and otherwise thing the complex beast that is CSS, from OOCSS to BEM to SMACSS. Some developers have even abandoned style sheets altogether in favour of inline styles.
To make sense of this increasingly complex landscape, and to shine a light on the way forward, Glen Maddern and Mark Dalgleish will look at how modularisation, and local, rather than global CSS might just be the answer.
Mark – the end of global CSS
Going back to the beginning… CSS Zen Garden inspired so many of us. It said if we wrote semantic markup we could use lots of different style sheets with it – and demonstrated that it was true!
But then how does that translate to web apps? Global scope vs. maintainability… Lots of attempts to deal with this – OOCSS, SMACSS, BEM, SUIT, even inline styles. BEM is arguably the most common.
As we move into the age of components, this story gets more complicated. Web components, polymer, ng directives, react components… Mark is using React for slides but the principles are the point.
Components are not new. HTML has lots of built in components like date picker and even just the humble select input.
Canonical example of The Problem is the jQuery UI Datepicker, where just one component required an absolute pile of code.
Looking at tools – the canonical Gulp tutorial focuses on types of files; SASS wants to know about your styles and nothing else… etc. Web components go the other way and focus on the component. What does component-centric tooling look like?
Webpack is the current leader. It builds a single dependency tree. Instead of folders per asset type, you are encouraged to think about components.
Instead of:
- /css/foo.css
- /js/foo.js
You have
- /foo/foo.css
- /foo/foo.js
This is an important mindset regardless of specific toolset.
So how does this integrate with tools and methodologies we’ve been using previously?
Well components and BEM map together to the same thing. You have components/modules/whatever you wish to call them.
Local scope… a feature that quietly turned up in webpack. You could import a “styles” object into your JS. Then there’s special syntax in your css – :local(.selector) {} – which means the styles aren’t in global scope. Webpack creates unique hash class names – IDs in effect – and maps them to usage.
So what if local scope was the default? Push things to global only when we want to? They used PostCSS to create this custom transform, so the CSS they actually wrote was mostly normal CSS (with unusual effects when compiled).
This led to the CSS modules project.
Glen: part one – the rise of modular style
Going back to the beginning for Glen… in 2008 JS was all about namespaces and Chrome brought V8 to the market. Glen feels CSS needs the same kind of localised scope that people wanted for JS in 2008. NodeJS has the kinda-default way of handling dependencies with require().
For CSS we have Browserify trying to create a module system for CSS.
You can change the human interface of a language without needing to change the language.
CSS has been pushed forwards by frameworks – notably Sass, LESS, PostCSS – but none of these change the fact that CSS is inherently global.
Now they’re pushing Interoperable CSS. ICSS adds import and export blocks at the top of an otherwise normal CSS file. This lets a compiler rewrite the CSS to suit the machines; while keeping clean syntax for humans.
Part two – modular style
So what can you actually do with all this? What’s the actual value?
You can compile CSS for use in production – Glen showed you can even convert to emoji and really pack the bytes.
The class names used on @glenmaddern’s blog are quite… interesting. https://glenmaddern.com/articles/css-modules … #wd15
You can use mixin-style relationships in your CSS, so the link between styles is not the name of the class; it’s declared specifically within whatever class you wanted to write.
You can define an API in your CSS for your components to use.
So where could this go? Site-wide theming, publishing reusable components with CSS, non-JS platforms/environments.
Global scope relies on convention; modular CSS could give greater safety. For Glen if everything’s a component it’s easier to think about.