SO WHAT IS IT ? π π π
Emotion is a library made for writing CSS styles with JavaScript. It allows you to style apps quickly with string or object styles. The most amazing thing about this library – other than itβs size and performance – is the flexibility of use. It supports strings, objects and functions and makes all the composable goodness possible.
The way this library intertwines itself with your React components is really amazing and itβs a joy to work with.
Add css prop magic to your styles
Emotion gives us CSS prop support. The CSS
prop is similar to the style
prop available in other libraries but also adds support for nested selectors, media queries, and auto-prefixing.
This provides a concise and flexible API to style my React components. The CSS prop also accepts a function that is called with your theme as an argument allowing developers easy access to common and customizable values.
How do I get started? π€ π€ π€
First step is to add it via npm or yarn:
yarn add @emotion/core
Now you can just import it like so:
import { css } from '@emotion/core';
or install the @emotion/styled
package and import the styled prop like so:
import styled from '@emotion/styled'
Using it with React components
Any component or element that accepts a className
prop can also use the css prop. The styles supplied to the css prop are evaluated and the computed class name is applied to the prop.
1.Object Styles
The css prop accepts object styles directly and does not require an additional import. It needs camelCase instead of kebab-case, for example background-color would be backgroundColor
With the css prop
import { css } from '@emotion/core'; render( <div css={{ color: 'red', backgroundColor: 'gray', }} > This is red. </div>, );
With styled
import styled from '@emotion/styled'; const Button = styled.button( { color: 'red', }, props => ({ fontSize: props.fontSize, }), ); render(<Button fontSize={16}>This is a red button.</Button>);
Child Selectors
/* @jsx jsx */ import { css } from '@emotion/core'; render( <div css={{ color: 'blue', '& .name': { color: 'orange', }, }} > This is blue. <div className="name">This is orange</div> </div>, );
import { css } from '@emotion/core'; render( <div css={{ color: 'green', '@media(min-width: 420px)': { color: 'orange', }, }} > This is orange on a big screen and green on a small screen. </div>, );
For Numbers, Arrays, Fallbacks, Composition refer https://emotion.sh/docs/object-styles. π π π
- String Styles
To pass string styles, you must use css which is exported by @emotion/core
/** @jsx jsx */ import { css, jsx } from '@emotion/core'; const color = 'green'; render( <div css={css` background-color: pink; &:hover { color: ${color}; } `} > This has a pink background. </div>, );
- Style Precedence
Two things to keep in mind:
- Class names containing emotion styles from the className prop override css prop styles.
- Class names from sources other than emotion are ignored and appended to the computed emotion class name.
The precedence order may seem counter-intuitive, but it allows components with styles defined on the css prop to be customized via the className prop passed from the parent.
The P
component in this example has its default styles overridden in the headerComponent.
/** @jsx jsx */ import { jsx } from '@emotion/core'; const P = props => ( <p css={{ fontSize: 12, fontFamily: 'Sans-Serif', color: 'black', margin: 0, }} {...props} /> ); const headerComponent = props => ( <P css={{ fontSize: 14, color: 'red', }} {...props} // <- props contains the `className` prop /> );
Here is what happens to the originalΒ P
Β component:
.css-1 { font-size: 12px; font-family: sans-serif; color: black; margin: 0; }
and these are the styles applied when the headerComponent component is rendered:
.css-2 { font-size: 14px, color: red; }
Result
.css-result { - font-size: 12px; + font-family: 'sans-serif'; - color: black; + font-size: 14px, + color: red; + margin: 0; }
But how different is this from styled-components? π π π
Emotion does basically have all the features of styled-components but
The Difference is
Size difference via bundlephobia π’
Now isnβt that amazing! π