The End
— of —
Global CSS
Let’s start at the beginning…
Documents
— vs. —
Web Apps
Global scope
— vs —
Maintenance
- OOCSS
- SMACSS
- BEM
- SUIT
- Inline styles!
.Block__Element--Modifier { ... }
<div class="page my-page">
<header class="header">
<h1 class="heading header__heading">...</h1>
</header>
<article class="post">
<header class="post__header">
<h1 class="heading post__heading">Hello World</h1>
</header>
<section class="post__content">...</section>
</article>
<footer class="footer">...</footer>
</div>
CSS at scale feels
Completely different
“How do we scale interfaces better?”
The Age
— of —
Components
- Web components
- Polymer
- Angular’s directives
Components are nothing new
<select>
<option>...</option>
<option>...</option>
<option>...</option>
</select>
<input type="date" />
CSS and images
— are —
private to a component
Unless you use third-party components…
gulp.task('js', function() {
return gulp.src('src/js/index.js')
.pipe(browserify());
});
gulp.task('css', function() {
return gulp.src('src/styles/index.scss')
.pipe(sass());
});
gulp.task('images', function() { ... });
@import "vendor/normalize";
@import "config/colors";
@import "config/media_queries";
@import "modules/btn";
@import "modules/dropdown";
@import "modules/header";
@import "utilities/align";
@import "utilities/clearfix";
Tooling
— for the —
component age?
components/
MyComponent/
MyComponent.js
MyComponent.css
icon.svg
require('./MyComponent.css');
export default () => (
<div className="MyComponent">
<div className="MyComponent__Icon">Icon</div>
...
</div>
);
.MyComponent__Icon {
background-image: url('icon.svg');
}
Traversing different file types
- style-loader
- css-loader
- postcss-loader
- less-loader
- sass-loader
- url-loader
// webpack.config.js:
loaders: [{
test: /\.css$/,
loader: 'style-loader!css-loader!postcss-loader')
},{
test: /\.svg$/,
loader: 'url-loader?mimetype=image/svg+xml'
},{
test: /\.js$/,
loader: 'babel-loader'
}]
import MyComponent from 'MyComponent';
export default () => <MyComponent />;
A block
— is —
a component
“Never use a block outside
a component of the same name”
components/
MyComponent/
MyComponent.js
MyComponent.css
icon.svg
.MyComponent__foo { ... }
.MyComponent__bar { ... }
.MyComponent__bar--expanded { ... }
“Block, Element, Modifying Your JavaScript Components”
require('./MyComponent.css');
// becomes...
import styles from './MyComponent.css';
What does ‘styles’
evaluate to?
First, let’s look at the CSS…
:local(.header) { ... }
:local(.footer) { ... }
import styles from './MyComponent.css';
export default () => (
<div>
<div className={styles.header}>...</div>
<div className={styles.footer}>...</div>
</div>
);
:local(.header) { ... }
:local(.footer) { ... }
Becomes:
/* Globally unique classes */
._1rJwx92-gmbvaLiDdzgXiJ { ... }
._ah6Hch-gjsAdSE53CxzaEs { ... }
// Styles object:
{
'header': '_1rJwx92-gmbvaLiDdzgXiJ',
'footer': '_ah6Hch-gjsAdSE53CxzaEs'
}
loader: 'css?localIdentName=[name]__[local]'
.MyComponent__foo { ... }
.MyComponent__bar { ... }
:local(.field) { ... }
:local(.field):focus { ... }
:local(.backdrop) { ... }
:local(.root_isCollapsed) :local(.backdrop) { ... }
:local(.panel) .transition-active-enter { ... }
“What if locally scoped
CSS was the default?”
.backdrop { ... }
.root_isCollapsed .backdrop { ... }
.field { ... }
.field:focus { ... }
.panel :global .transition-active-enter { ... }
postcss-local-scope
— Turned .class into :local(.class), :global(.class) into .class —
The End
— of —
Global CSS
“I hope it’s ok if I integrate your postcss-local-scope module into the css-loader”
@sokra — May 24, 2015
“In the future, we could start generating shared classes between components automatically, treating style re-use as an optimisation at compile time.”
One-to-one mapping
{
'foo': 'MyComponent__foo'
}
One-to-many mapping?
{
'foo': 'class_1 class_2 class_3'
}
.foo {
composes: heading from './typography.css';
composes: box from './layout.css';
color: red;
}
/* typography.css */
.heading { ... }
/* layout.css */
.box { ... }
{
'foo': `MyComponent__foo
Typography__heading
Layout__box`
}
“Have you thought about writing a standard for CSS modules that others could implement?”
@markdalgleish — May 23, 2015
- React
- Mercury
- Angular
- Backbone
- VanillaJS
- Webpack
- Browserify
- JSPM
- Your build tool?
“This looks complicated…”
Each component is a miniature
CSS Zen Garden
Smarter tools
— not —
Stricter methodologies
Let’s make Big CSS
— feel like —
Small CSS