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.
const TalkMeta = styled(Talk)`
author: 'Nick Ribal';
date: March/2020;
`
Where & why CSS fails in the age of components & apps 💔
Overview of styled/Emotion 💅
3 styles of using styled + utility classes based styling
Co-location | Component.style.js or separate styling object |
Logical props API | Visual props API: no styling |
Style components | Use selectors |
Style/use components | Use CSS/styled nesting |
Style components | Over abstraction |
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
After a decade of styling in various ways and platforms, I've settled on styled-components/Emotion as weapon of choice. However, with great power comes great responsibility. S-C can be used in a variety of ways. I'll present various approaches, their tradeoffs and my recommendations on how to harness the best of this awesome tech!
Front-end veteran, consultant and freelancer, who's armed with a decade of experience solving challenges on the Web platform for large Internet companies.