Nick Ribal
Front-end veteran, consultant and freelancer, who's armed with a decade of experience solving challenges on the Web platform for large Internet companies.
topic {
css-in-js: overflow;
}
topic::meta {
author: Nick Ribal;
date: June 2017;
}
I ♥ CSS! I know (in person) only one guy who knows CSS better than me
This is not a "WUT CSS SUCKS LOL!!!" talk
I've worked on:
Content sites
3rd party widgets hosted on others sites
Client-side applications
Integrations of all of the above
This talk is meant to make people consider new practices - not replace CSS
Examples of CSS ecosystem FAIL
Why it's like that
The long history (in front-end terms, lol) of css-in-js
Correlation to evolution of modern HTML authoring
How css-in-js solves CSS ecosystem deficiencies
css-in-js features which you can't have otherwise
Examples of popular css-in-js libraries
3a. Use simple <link rel=stylesheet href=hardcoded-CDN.css> just for the reset. Bad practices: another request, not an actual package you manage, not self-hosted
CSS workflow is stuck in document mode: not modular, not interoperable, not scopable, optimizations aren't built-in
1. Start new project
2. Add CSS reset/normalize
3. ???
4. PROFIT!!!
3b. Copy/paste into your CSS
4. ಠ_ಠ ???
3c. Use complex tooling to do achieve something fundamentally basic (CSS packages in npm are scarce and inconsistent)
Modern CSS frameworks aren't interoperable
Each is like a country: has it's own language, concepts, conventions, supporting different browser versions
This results in incompatible monoliths, negating basic software development best practices: code sharing, modularity, reuse and huge variance in how the same features are implemented
In November 2014, Christopher "vjeux" Chedeau, who is working on React and React Native at Facebook, gave a thought-provoking talk titled "CSS in JS".
He outlined the problems of CSS at scale and later showed how they solved those at Facebook. They were able to solve most, but in return had to add a lot of additional tooling.
Then he introduced a complete new approach to handle those issues without any actual extra work. Using inline styles. It seemed crazy, but just worked magically.
// Remember jQuery plugins?
$('select').select2()
// SPA frameworks via template engines
var TitleView = Backbone.View.extend({
template: _.template('<h1><%=text%></h1>')
// Or Pug, Mustache, Handlebars, etc
})
// Modern components
function Title({ text, className, }){
return (
<h1 { ...{ className } }>{ text }</h1>
)
}
But that's a good GREAT thing!
Since we acknowledge CSS's shortcomings in the modern web
And smart people are coming up with new approaches to tackle these problems all the time!
Optimizations and
static analysis
Standardization, modularity and code reuse
/* toast.css */
.message { font-weight: bold; }
.success { color: green; }
.fail { color: red; }
import {
message, success, fail,
} from './toast.css'
function Toast(isSuccess, text){
const statusClass = isSuccess ? success : fail
const toastProps = {
className: [message, statusClass].join(' ')
}
return <div { ...toastProps }>{ text }</div>
}
import jss from 'jss'
import preset from 'jss-preset-default'
import color from 'color'
// One time setup with plugins and settings
jss.setup(preset())
// Create or compose your CSS
const styles = {
button: {
fontSize: 12,
'&:hover': { // CSS pseudo-classes
background: 'blue'
}
},
ctaButton: {
extend: 'button', // mixins
'&:hover': {
background: // Runtime JS colors
color('blue').darken(0.3).hex()
}
},
'@media (min-width: 1024px)': {
// CSS media queries
button: {
width: 200
}
}
}
// Attach stylesheet to DOM (or SSR)
const {classes} =
jss.createStyleSheet(styles).attach()
// Render your HTML with generated classes
document.body.innerHTML = `
<button class="${classes.button}">
Button
</button>
<button class="${classes.ctaButton}">
CTA Button
</button>
`
import {h1} from 'styled-components'
const Title = h1`
font-family: Comic Sans MS;
color: blue;
`
// Usage
<Title>Hello World!</Title>
Why even bother with class names?
They are merely an implementation detail
// a styled component
import {
StyleSheet, css,
} from 'aphrodite'
const styles = StyleSheet.create({
title: { ... }
})
function Heading(props){
const headingProps = {
...props,
className: css(styles.title)
}
return <h1 { ...headingProps } />
)
// SSR with critical CSS inlined
import { StyleSheetServer } from 'aphrodite'
const { html, css } = StyleSheetServer.renderStatic(
() => ReactDOMServer.renderToString(<App/>)
)
// Send in response body
const criticalCss = `
<style data-aphrodite>
${css.content}
</style>
`
With so many choices, each with a variety features and tradeoffs
I have no idea which ones will become popular ¯\_(ツ)_/¯
You should try these for yourself and draw your own conclusions!
By Nick Ribal
While JS and HTML have progressed incredibly in recent years, CSS is the last bastion of old-school web development which we all love to hate. CSS-in-JS is the latest attempt at solving this hard problem. If it succeeds, CSS-in-JS will fast-forward CSS into the modern era. Moreover, it will revolutionize how we compose, maintain, share and optimize styling across the modern web, native apps and collaborate with designers and product people. I will present an overview of the history, evolution, challenges, current solutions and benefits in this exciting landscape!
Front-end veteran, consultant and freelancer, who's armed with a decade of experience solving challenges on the Web platform for large Internet companies.