The End of Global CSS

Mark Dalgleish
May 20, 2015 · 7 min read

In other languages, it’s accepted that modifying the global
environment is something to be done rarely, if ever.

In the JavaScript community, thanks to tools like Browserify, Webpack and JSPM, it’s now expected that our code will consist of small modules, each encapsulating their explicit dependencies, exporting a minimal API.


require('./MyComponent.css');

require('./MyComponent.css');
import styles from './MyComponent.css';
:local(.foo) {
color: red;
}
:local(.bar) {
color: blue;
}
import styles from './MyComponent.css';import React, { Component } from 'react';export default class MyComponent extends Component {  render() {
return (
<div>
<div className={styles.foo}>Foo</div>
<div className={styles.bar}>Bar</div>
</div>
);
}
}

Writing maintainable CSS is now encouraged, not by careful adherence to a naming convention, but by style encapsulation during development.


:local(.foo) { … }
._1rJwx92-gmbvaLiDdzgXiJ { … }
loaders: [
...
{
test: /\.css$/,
loader: 'css?localIdentName=[name]__[local]___[hash:base64:5]'
}
]
.MyComponent__foo___1rJwx { … }
loader: 'css?localIdentName=' + (
process.env.NODE_ENV === 'development' ?
'[name]__[local]___[hash:base64:5]
' :
'[hash:base64:5]'
)

Now that Webpack has control of our class names, we can trivially
add support for minified classes in production.


:local(.backdrop) { … }:local(.root_isCollapsed .backdrop) { … }:local(.field) { … }:local(.field):focus { … }etc…

What if — instead of requiring a special syntax — our selectors were local by default, and global selectors were the opt-in exception?

What if we could write this instead?

.backdrop { … }.root_isCollapsed .backdrop { … }.field { … }.field:focus { … }
.panel :global .transition-active-enter { … }


In the future, we could start generating shared classes between components automatically, treating style re-use as an optimisation at compile time.


To get involved, make sure you see it with your own eyes by
checking out postcss-local-scope-example.

Once you’ve seen it in action, I think you’ll agree that it’s not just hyperbole — the days of global CSS are coming to an end. The future of CSS is local.



Addendum

24 May, 2015: The original ideas presented in postcss-local-scope have been accepted into Webpack by Tobias Koppers, meaning that the project is now deprecated. Support for CSS Modules — as they are tentatively known — are now available in css-loader via an opt-in module flag. I’ve created a working example of CSS Modules in css-loader to demonstrate their usage, including class inheritance to intelligently share common styles between components.


SEEK blog

At SEEK we’ve created a community of valued, talented…

Mark Dalgleish

Written by

CSS Modules co-creator, @MelbJS organiser, DesignOps Lead at @seekjobs.

SEEK blog

SEEK blog

At SEEK we’ve created a community of valued, talented, diverse individuals that really know their stuff. Enjoy our Product & Technical insights…

Mark Dalgleish

Written by

CSS Modules co-creator, @MelbJS organiser, DesignOps Lead at @seekjobs.

SEEK blog

SEEK blog

At SEEK we’ve created a community of valued, talented, diverse individuals that really know their stuff. Enjoy our Product & Technical insights…

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store