emotion 7

New core, better defaults and amazing composition

The major changes:

New Core

The core is now powered by a forked version of Sunil Pai’s glamor. The bundle size cost? Only 1.7kb. We moved plugins and auto-prefixing from the run-time to the babel plugin which drastically reduced the size.

Inline Mode

Inline mode is now the default setting. Extract mode has been removed.

Extract Static

If you would like your static styles extracted you can enable the extractStatic option. This is limited to string based styles that have zero expressions.

Theming Removed

After listening to the community I decided to remove built-in theme support. If you need themes check out this 3 line guide.

Props Filtered

No more unknown props warnings.

In order to reduce the size of the white-list we removed the svg related props. If you are using emotion to style svgs we recommend omitting these props manually.


How does it work?

const blueText = css`
font-size: 12px;
font: ${theme.colors.blue[5]};
`

is compiled to.

const blueText = styled(
[],
[theme.colors.blue[5]],
function createEmotionStyledRules (x0) {
return [
{
fontSize: '12px',
font: x0
}
]
}
)

String based styles are converted to objects at compile time. Using plain javascript objects means we don’t have to use selector hacks to enable composition.

Predictable & Guilt-Free Composition

Lets imagine we have a set of base styles for elements.

const baseCss = css`
font-family: 'Oxygen', sans-serif;
color: ${theme.colors.gray[8]};
box-sizing: border-box;
`

If we want to use them in a component reference the styles in our components styles.

const Name = styled('h3')`
${baseCss};
font-size: 1.5rem;
`

Internals

It does not matter where you place these styles. They go exactly where you expect in the stylesheet.

This code

const boxCss = css`
color: blue;
${css`width: 96px; height: 96px;`};
background-color: white;
`

Is compiled to

const boxCss = css(
[],
[
css([], [], function createEmotionStyledRules () {
return [
{
width: '96px',
height: '96px'
}
]
})
],
function createEmotionStyledRules (x0) {
return [
{
color: 'blue',
$0: x0,
backgroundColor: 'white'
}
]
}
)

The result is reduced down to the following by the core.

{
color: 'blue',
width: '96px',
height: '96px'
backgroundColor: 'white'
}

Nesting

You can also nest these as far as you like.

const largeFont = css`font-size: 2rem`
const mq = css`
color: red;
@media(min-width: 420px) {
color: blue;
@media(min-width: 520px) {
color: green;
${largeFont};
}
}
`
const H1 = styled('h1')`
font-size: 1rem;
${mq};
color: green;
`

Composition Tricks

Use functions.

const margin = (top, right, bottom, left) => css`
margin-top: ${top};
margin-right: ${right};
margin-bottom: ${bottom};
margin-left: ${left};
`
const H1 = styled('h1')`
font-size: 4rem;
${margin(0, 'auto', 0, 'auto')};
`

Use objects

const flex = { display: 'flex' }
const Flex = styled('div')`
${flex};
`

Use functions that return objects

const display = ({ display = 'flex' }) => ({ display })
const Box = styled('div')`
${display};
`

Compose styled components

const display = ({display = 'flex'}) => ({display})

const column = props => css`flex-direction:${props.column ? 'column': 'row'}`

const Box = styled('div')`
${display};
${column};
`

const BlueBox = styled(Box)`
background: blue;
`

<BlueBox column />

Big thanks to Mitchell Hamilton for all of his help on this release. As I’ve said before his contributions are invaluable to this project.

You can try out v7 right now at https://emotion.sh

Thank you Peter Piekarczyk for editing this and keeping me from sounding like a redneck.