This is the seventh day of my participation in the More text Challenge. For details, see more text Challenge
Advantages of CSS in JS
CSS in JS has evolved into a mainstream solution for writing styles in React applications, and the well-known component library, Material UI, has been implemented using CSS in JS. There are two ways to implement CSS in JS: unique CSS selectors and inline styles. so
- Don’t worry about tedious Class naming conventions
- Don’t worry about styles being overwritten
- Convenient reuse of styles (styles are either JS objects or strings)
- Reduced redundant CSS code, extreme style load on demand
Emotion is one of the many implementations of CSS in JS. Here’s how to use it.
Note: The following introduction is fromEmotion Official document
Basic use of Emotion
Object Styles and String Styles
Emotion supports style definitions in both JS objects and JS strings.
Object Styles
/ * *@jsx jsx */
import { jsx } from '@emotion/react'
render(
<div
css={{
backgroundColor: 'hotpink', '&':hover': {
color: 'lightgreen'}}} >
This has a hotpink background.
</div>
)
Copy the code
String Styles
// this comment tells babel to convert jsx to calls to a function called jsx instead of React.createElement
/ * *@jsx jsx */
import { css, jsx } from '@emotion/react'
const color = 'darkgreen'
render(
<div
css={css`
background-color: hotpink;
&:hover {
color:The ${color};
}
`}
>
This has a hotpink background.
</div>
)
Copy the code
Add the style
Emotion has two ways of writing CSS: CSS-Prop and Styled Components.
css Prop
Click here to see how to open CSS Prop
String Styles sample
// this comment tells babel to convert jsx to calls to a function called jsx instead of React.createElement
/ * *@jsx jsx */
import { css, jsx } from '@emotion/react'
const color = 'darkgreen'
render(
<div
css={css`
background-color: hotpink;
&:hover {
color:The ${color};
}
`}
>
This has a hotpink background.
</div>
)
Copy the code
The @emotion/ React JSX is an enhanced react. CreateElement method that adds a CSS prop to the React element.
The Object Styles sample
/ * *@jsx jsx */
import { jsx } from '@emotion/react'
render(
<div
css={{
backgroundColor: 'hotpink', '&':hover': {
color: 'lightgreen'}}} >
This has a hotpink background.
</div>
)
Copy the code
For either Object Styles or String Styles, we can read the context js variable directly at the time the style is defined. This allows us to easily change the style.
Styled Components
Styled Components derive some of the built-in Components with HTML tags, and our syntax below allows the styling to be added.
import styled from '@emotion/styled'
let SomeComp = styled.div({
color: 'hotpink'
})
let AnotherComp = styled.div`
color: ${props => props.color};
`
render(
<SomeComp>
<AnotherComp color="green" />
</SomeComp>
)
Copy the code
Styles of Styled Components Components generated by Styled Components can also change style based on the incoming Props
import styled from '@emotion/styled'
const Button = styled.button`
color: ${props =>
props.primary ? 'hotpink' : 'turquoise'};
`
const Container = styled.div(props= > ({
display: 'flex'.flexDirection: props.column && 'column'
}))
render(
<Container column>
<Button>This is a regular button.</Button>
<Button primary>This is a primary button.</Button>
</Container>
)
Copy the code
For the Styled Components, there are also some less common uses. Click here to learn more.
Style reuse
In Emotion, we can declare common styles as variables and share them across different components.
/ * *@jsx jsx */
import { jsx, css } from '@emotion/react'
const base = css`
color: hotpink;
`
render(
<div
css={css`
${base};
background-color: #eee;
`}
>
This is hotpink.
</div>
)
Copy the code
The base style above can then be used with render. If we have other components that use the Base style, we can import the base variable to use it.
Style priority
/ * *@jsx jsx */
import { css, jsx } from '@emotion/react'
const danger = css`
color: red;
`
const base = css`
background-color: darkgreen;
color: turquoise;
`
render(
<div>
<div css={base}>This will be turquoise</div>
<div css={[danger, base]} >
This will be also be turquoise since the base styles
overwrite the danger styles.
</div>
<div css={[base, danger]} >This will be red</div>
</div>
)
Copy the code
When writing styles, it is inevitable that you will need to cover them. In this case, you can adjust the order of base and Danger to cover them as above (the later styles have higher priority).
Nested selectors
The Emotion style also supports CSS selectors.
Select and set the nodes within the component
/ * *@jsx jsx */
import { jsx, css } from '@emotion/react'
const paragraph = css`
color: turquoise;
a {
border-bottom: 1px solid currentColor;
cursor: pointer;
}
`
render(
<p css={paragraph}>
Some text.
<a>A link with a bottom border.</a>
</p>
)
Copy the code
When the component is a child, use & to select itself and set the style
/ * *@jsx jsx */
import { jsx, css } from '@emotion/react'
const paragraph = css`
color: turquoise;
header & {
color: green;
}
`
render(
<div>
<header>
<p css={paragraph}>
This is green since it's inside a header
</p>
</header>
<p css={paragraph}>
This is turquoise since it's not inside a header.
</p>
</div>
)
Copy the code
Media queries
/ * *@jsx jsx */
import { jsx, css } from '@emotion/react'
render(
<p
css={css`
font-size: 30px;
@media (min-width: 420px) {
font-size: 50px;
}
`}
>
Some text!
</p>
)
Copy the code
Click here to learn more about using multimedia queries
Global style
import { Global, css } from '@emotion/react'
render(
<div>
<Global
styles={css`
.some-class {
color: hotpink !important; } `} / >
<Global
styles={{
'.some-class': {
fontSize: 50.textAlign: 'center'}}} / >
<div className="some-class">This is hotpink now!</div>
</div>
)
Copy the code
Advanced usage
keyframes
/ * *@jsx jsx */
import { jsx, css, keyframes } from '@emotion/react'
const bounce = keyframes'from, 50%, 50%, 50%, to {transform: translate3d(0,0,0); } 40%, 43% { transform: translate3d(0, -30px, 0); } 70% { transform: translate3d(0, -15px, 0); } 90% { transform: translate3d(0,-4px,0); } `
render(
<div
css={css`
animation:The ${bounce} 1s ease infinite;
`}
>
some bouncing text!
</div>
)
Copy the code
The theme
ThemeProvider
import * as React from 'react'
import styled from '@emotion/styled'
import { ThemeProvider, withTheme } from '@emotion/react'
// object-style theme
const theme = {
backgroundColor: 'green'.color: 'red'
}
// function-style theme; note that if multiple <ThemeProvider> are used,
// the parent theme will be passed as a function argument
const adjustedTheme = ancestorTheme= > ({ ...ancestorTheme, color: 'blue' })
class Container extends React.Component {
render() {
return (
<ThemeProvider theme={theme}>
<ThemeProvider theme={adjustedTheme}>
<Text>Boom shaka laka!</Text>
</ThemeProvider>
</ThemeProvider>)}}Copy the code
withTheme
import * as PropTypes from 'prop-types'
import * as React from 'react'
import { withTheme } from '@emotion/react'
class TellMeTheColor extends React.Component {
render() {
return <div>The color is {this.props.theme.color}.</div>
}
}
TellMeTheColor.propTypes = {
theme: PropTypes.shape({
color: PropTypes.string
})
}
const TellMeTheColorWithTheme = withTheme(TellMeTheColor)
Copy the code
useTheme
/ * *@jsx jsx */
import { jsx, ThemeProvider, useTheme } from '@emotion/react'
import styled from '@emotion/styled'
const theme = {
colors: {
primary: 'hotpink'}}function SomeText(props) {
const theme = useTheme()
return <div css={{ color: theme.colors.primary }} {. props} / >
}
render(
<ThemeProvider theme={theme}>
<SomeText>some text</SomeText>
</ThemeProvider>
)
Copy the code
Open the CSS Prop
A CSS Prop can be used on any Dom element or component that supports className.
The CSS Prop needs to be implemented with babel-PRESET or JSX Pragma
babel-preset
.babelrc
{
"presets": ["@emotion/babel-preset-css-prop"]
}
Copy the code
If you are using the compatible React version (>=16.14.0) then you can opt into using the new JSX runtimes by using such configuration:
If React version >=16.14.0, you can use the following configuration to use the new JSX runtime.
{
"presets": [
[
"@babel/preset-react",
{ "runtime": "automatic", "importSource": "@emotion/react" }
]
],
"plugins": ["@emotion/babel-plugin"]
}
Copy the code
tsconfig.json
This is the configuration when compiling typescript with Babel
{
"compilerOptions": {...// "jsx": "react",
"jsxImportSource": "@emotion/react". }}Copy the code
JSX Pragma
Open a CSS Prop by adding a comment to the JSX transformation.
/ * *@jsx jsx */
import { jsx } from '@emotion/react'
Copy the code
/** @jsx JSX */ If it doesn’t work, try /** @jsximportSource @emotion/react */.
Click here for a detailed configuration document.
compatibility
Emotion supports all popular browsers, including Internet Explorer 11.
The resources
- CSS in JS
- The Emotion’s official website
- The pros and cons of CSS in JS The front end scholar needs to clear his mind so that he can conceive the picture
- Talk about the use of CSS-in-JS in the React project