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.
react2019 {
css-in-js: overflow
}
react2019::meta {
author: Nick Ribal;
date: August 2019;
}
Where & why CSS fails in the age of components & apps 💔
How CSS-in-JS can help us 😍
Overview of styled/Emotion 💅
Best practices in styled/Emotion ✨
Questions/demo ⚠
CSS is:
Powerful and ever improving
Flexible and styles the entire richness of the Web
Easy to start with
Hard to master
Sadly, I know only a couple of people in person who know CSS better than me 😭
CSS-in-JS is:
Not a replacement of CSS
Another way of authoring CSS
A decade of work, consulting and team leadeing of:
Content sites (SSR)
3rd party widgets
SPAs, client and isomorphic
Juggling all the above 🤹
Web:
Inline styles, CSS, Less, Sass, CSS modules, styled-components, Emotion
A few years of policing BEM 👮
React Native:
Bare styling, Emotion, RNW, Native Base
Modern CSS frameworks aren't interoperable
Each is like a country with its own language, concepts & conventions via classes, selectors and specificity
The result is incompatible monoliths:
.foo.foo { prop: value }
html .foo { prop: value }
.foo[class] { prop: value }
/* Temporary fix, I swear! */
.foo { prop: value !important }
Did you work on a content site?
No, really: with SSR, SEO and 1000's of URLs?
Did you need to style things dynamically?
Show me on the doll where the cascade touched you
Remember "web pages" and "information superhighway"?
We used to write websites and webpages
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.
Optimizations and
static analysis
Standardization, modularity and code reuse
We 💜 React because it's component model and API make a good DOM abstraction
Guess what? The same applies to styling!
Components - a good abstraction model
JSX - syntactic sugar to compose components
separation of concerns
!==
separation of technologies
styling!
They have NO semantic meaning
They are a means to an end
They are the vessel, not the message
They are painful to maintain and juggle when changing styling
String manipulation isn't fun
They are global (which CSS modules work around)
.primary {
color: red;
}
<button class="primary">
Text
</button>
import styled from '@emotion/styled'
const RedButton = styled.button`
color: red;
`
render(
<RedButton>My button</RedButton>
)
Examples are straight from the docs
All I want is a red button!!!!
<button class="css-ck1kby-RedButton">
My button
</button>
No, it is not inline styles! 😅
Isn't that just inline styles? 😱
.css-ck1kby-RedButton {
color: red;
}
The glue is abstracted away ✨
import styled from '@emotion/styled'
const Basic = ({ className }) => (
<div className={className}>Some text</div>
)
const Fancy = styled(Basic)`
color: hotpink;
`
render(<Fancy />)
Styling any component
As long as it accepts a className prop. So ANY component, really
import styled from '@emotion/styled'
const Section = styled.section`
background: #333;
`
const Aside = Section.withComponent('aside')
render(
<div>
<Section>A section</Section>
<Aside>Aside styled like Section</Aside>
</div>
)
const Child = styled.div`color: red;`
const Parent = styled.div`
${Child} {
color: green;
.global-css {
like-in: Sass;
scoped-like-in: css-modules;
}
}
`
render(<>
<Parent>
<Child>green, with nested .global-css</Child>
</Parent>
<Child>red</Child>
</>)
const Button = styled.button`
color: ${(props) =>
props.primary ? 'hotpink' : 'turquoise'};
`
// ^ will create two classes and toggle them
const Container = styled.div(props => ({
display: 'flex',
flexDirection: props.vertical && 'column',
}))
render(
<Container vertical>
<Button>This is turquoise</Button>
<Button primary>This is hotpink</Button>
</Container>
)
Dynamic styling? No problem!
import styled from '@emotion/styled'
import { css } from '@emotion/core'
const withColor = (props) => css`
color: ${props.color || 'currentColor'};
`
const H1 = styled.h1`
${withColor};
`
render(
<H1 color="lightgreen">
This is lightgreen
</H1>
)
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.