
- CSS Modules
- Inline Styles
- CSS in JS
Let’s start at the beginning…

Documents
— vs. —
Web Apps
Global scope
— vs —
Maintenance
- OOCSS
- SMACSS
- BEM
- SUIT
.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>
The Age
— of —
Components
- Backbone
- Angular’s directives
- Ember.Component
- Web components
- Polymer
React
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…
jQuery UI Date Picker
Our tools reflected this
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?
Webpack
require('./MyComponent.css');
export default () => (
  <div className="MyComponent">
    <div className="MyComponent__Icon">Icon</div>
    ...
  </div>
);
Simple interface
import MyComponent from 'MyComponent';
export default () => <MyComponent />;
Progressive
Single Page Apps
      - Server rendered CSS
- :visited, :before, :hover, :focus, etc.
- Media queries
- CSS animations
- Psuedo classes for non-JS interactions…?
.menu {
  transform: translateX(-100%);
  transition: all .3s ease;
}
.toggle:checked ~ .menu {
  transform: none
}
Late 2014…
“CSS has fundamental flaws at scale that can be solved by writing styles in JS.”
@vjeux — November 2014
MicheleBertoli/css-in-js

react-style
— by @andreypopp —
import StyleSheet from 'react-style';
const styles = StyleSheet.create({
    foo: {
      color: 'red',
      backgroundColor: 'white'
    }
});
export default () => (
  <div style={styles.foo}>
    Hello, world!
  </div>
);
but…
- 
            Media queries
- 
            CSS animations
- 
            Psuedo classes
And yet…
😍
      — How do we embrace the —
inline style mindset in regular CSS?
BEM
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”
Meanwhile…
Local Scope
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 { ... }
No more
naming collisions
      // 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
postcss-local-scope
— Turned .class into :local(.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
‘css-loader?module’
“Have you thought about writing a standard for CSS modules that others could implement?”
@markdalgleish — May 23, 2015
‘css-loader?modules’
- Class composition
- Values, i.e. shared constants






github.com/css-modules
- Webpack
- Browserify
- JSPM
- PostCSS
- Babel
Let’s rewind a little…
Why not CSS in JS?
- 
            Media queries
- 
            CSS animations
- 
            Psuedo classes
Inline styles
CSS in JS
— isn’t restricted to —
Inline Styles
Khan Academy
Aphrodite
Jamie Wong / Emily Eisenberg
import { StyleSheet } from 'aphrodite';
const styles = StyleSheet.create({
  field: {
    margin: '0 10px',
    ':focus': { outline: '2px solid blue' },
    '@media (min-width: 600px)': { margin: '0 20px' }
  }
});
import { css } from 'aphrodite';
export default () => (
  <div>
    <input className={css(styles.field)} />
  </div>
);
import { StyleSheetServer } from 'aphrodite';
var {html, css} = StyleSheetServer.renderStatic(() => {
    return ReactDOMServer.renderToString(return `
  <html>
    <head>
      <style data-aphrodite>${css.content}</style>
    </head>
    
    <body>
      <div id='app'>${html}</div>
      ...
    </body>
  </html>
`;
“We must deliver the absolute minimum amount of CSS necessary by only sending down CSS in use by components in the server-side rendered body”
Jamie Wong — March 2016
Personal
preference
      CSS Modules
— or —
CSS-in-JS…
What do these
approaches have
in common?
      First Class Styles
Locally define styles
— then —
Pass directly to elements
.foo { color: red }
import styles from './Component.css';
<div className={styles.foo} />
const styles = StyleSheet.create({
  foo: { color: 'red' }
});
<div style={styles.foo} />
We've been putting this into practice
for the past year...
      - 70 CSS files
- 782 rules
- 948 selectors
- 2,886 declarations
- 211 media queries
Our global CSS footprint?
/* http://meyerweb.com/eric/tools/css/reset/ 
   v2.0 | 20110126
   License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
  display: block;
}
body {
  line-height: 1;
}
ol, ul {
  list-style: none;
}
blockquote, q {
  quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
  content: '';
  content: none;
}
table {
  border-collapse: collapse;
  border-spacing: 0;
}html {
  font-family: @base-font-stack;
  font-size: unit(@base-font-size, px);
  background-color: @sk-background;
  box-sizing: border-box;
  min-height: 100%;
  overflow-y: auto;
}
*,
*:before,
*:after {
  font-family: inherit;
  box-sizing: inherit;
  -webkit-tap-highlight-color: rgba(0,0,0,0);
  -webkit-tap-highlight-color: transparent; /* For some Androids */
}
body {
  overflow-y: hidden;
}
input {
  margin: 0;
}
input[type=search]::-webkit-search-decoration {
  -webkit-appearance:none;
}
- Increased authoring speed
- Less fear of change
- Maintainable by default
- Faster debugging
- Simpler onboarding
Easier style guide extraction
But that’s a topic for another day…
👍
      😍😍😍
      