吴志勇的博客 吴志勇的博客
  • h5

    • HTML5&CSS3
  • scss

    • css预处理语言
  • JavaScript

    • JavaScript教程
    • Ajax
    • ES6教程
    • NodeJS
    • Typescript
  • 框架

    • Jquery
    • VUE
    • React
  • Swing专题
  • java基础
  • javaweb
  • 框架
  • 数据库
  • netty
  • 设计模式
  • 微服务及架构
  • 云原生
  • maven
  • 单元测试
工具
我的
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

吴志勇

......
  • h5

    • HTML5&CSS3
  • scss

    • css预处理语言
  • JavaScript

    • JavaScript教程
    • Ajax
    • ES6教程
    • NodeJS
    • Typescript
  • 框架

    • Jquery
    • VUE
    • React
  • Swing专题
  • java基础
  • javaweb
  • 框架
  • 数据库
  • netty
  • 设计模式
  • 微服务及架构
  • 云原生
  • maven
  • 单元测试
工具
我的
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • HTML5&CSS3

  • CSS预处理语言

  • JavaScript

  • nodejs

  • webpack

  • VUE

  • react

    • 01 【react入门】
    • 02 【面向组件编程】
    • 03 【事件处理】
    • 04 【生命周期】
    • 05 【条件渲染】
    • 06 【列表 & Key】
    • 07 【收集表单数据】
    • 08 【状态提升】
    • 09 【组合组件】
    • 10 【初始化脚手架】
    • 11 【react-router 5】
    • 12 【react高级指引(上)】
    • 13【react高级指引(下)】
    • 14【react-Hook (上)】
    • 15【react-Hook (下)】
    • 16 【react-router 6】
    • 17【redux】
    • 18 【Redux Toolkit】
    • 19 【RTK Query】
    • 20 【react中使用ts】
    • 21 【styled-components的使用】
    • 22 【在react中使用Emotion】
      • 1.CSS in JS 的优点
      • 2.Css Prop
        • 2.1 Babel Preset
        • 2.2 JSX 注释
        • 2.3 tsconfig.json
        • 2.4 Object Styles 和 String Styles
      • 3.Styled Components
        • 3.1 写一个带样式的组件
        • 3.2 通过参数控制样式
        • 3.3 通过传className创建组件
        • 3.4 创建与某个组件相同的样式
        • 3.5 嵌套写法
        • 3.5.1 ${子组件}
        • 3.5.2 对象(键值对)
        • 3.6 对象样式
        • 3.7 自定义 prop 转发
        • 3.8 动态样式
        • 3.9 as prop
        • 3.10 嵌套元素样式写法
      • 4.Composition
        • 4.1 样式复用
        • 4.2 样式优先级
      • 5.Object Styles
        • 5.1 使用 css props
        • 5.2 使用styled
        • 5.3 子选择器
        • 5.4 媒体查询
        • 5.5 Numbers
        • 5.6 Arrays
        • 5.7 用css
        • 5.8 Composition - 样式复用
      • 6.Nested Selectors
      • 7.Media Queries
      • 8.Global Styles
      • 9.Keyframes
      • 10.Attaching Props - 附加额外的属性
      • 11.Theming
        • 11.1 css prop
        • 11.2 styled
        • 11.3 useTheme hook
      • 12.TypeScript
        • 12.1 HTML/SVG elements
        • 12.2 定义 props 类型
        • 12.3 React Components
    • 23 【UmiJS入门】
    • 24 【UmiJS基础】
  • Typescript
  • 前端
  • react
wuzhiyong
2024-09-22

22 【在react中使用Emotion】

# 22 【在react中使用Emotion】

# 1.CSS in JS 的优点

CSS in JS (opens new window) 已逐渐发展为 React 应用中写样式的一个主流的方案,著名组件库 material-ui (opens new window) 也已经使用 CSS in JS 来实现。 CSS in JS 的实现方式有两种: 唯一CSS选择器和内联样式。因此

  1. 不用关心繁琐的 Class 命名规则
  2. 不用担心样式被覆盖
  3. 便利的样式复用(样式都是 js 对象或字符串)
  4. 减少冗余的 CSS 代码,极致的样式按需加载

Emotion (opens new window) 是 CSS in JS 的众多实现方案中的其中一个,下面介绍一下它的使用。

说明:以下的介绍都来自于Emotion官方文档 (opens new window)

安装

 npm i @emotion/styled @emotion/react
1

使用

Emotion (opens new window) 有两种写 CSS 的方式:css-prop (opens new window) 和 Styled Components (opens new window)。

# 2.Css Prop

添加预设或将杂注设置为注释后,React.createElement编译后的 jsx 代码将使用emotion 的函数而不是.jsx

# 2.1 Babel Preset

此方法不适用于创建 React App (opens new window) 或其他不允许自定义 Babel 配置的项目。 请改用 JSX 注释方法 (opens new window)。

.babelrc

{
  "presets": ["@emotion/babel-preset-css-prop"]
}
1
2
3

完整的@emotion/babel-preset-css-prop 文档 (opens new window)

If you are using the compatible React version (>=16.14.0) then you can opt into using the new JSX runtimes (opens new window) by using such configuration:

如果 React 版本 >=16.14.0 , 可以使用如下的配置来使用新的 jsx 运行时。

{
  "presets": [
    [
      "@babel/preset-react",
      { "runtime": "automatic", "importSource": "@emotion/react" }
    ]
  ],
  "plugins": ["@emotion/babel-plugin"]
}
1
2
3
4
5
6
7
8
9

# 2.2 JSX 注释

将jsx 注释设置在使用道具的源文件的顶部。 此选项最适合测试 prop 功能或在 babel 配置不可配置的项目(create-react-app、codesandbox 等)中。

/** @jsx jsx */
import { jsx } from '@emotion/react'
1
2

/** @jsx jsx */ 不生效的时候可以改为 /** @jsxImportSource @emotion/react */ 来尝试。

# 2.3 tsconfig.json

这里指的是使用 babel 编译 typescript (opens new window) 时的配置

{
  "compilerOptions": {
    ...
    // "jsx": "react",
    "jsxImportSource": "@emotion/react",
    ...
  }
}
1
2
3
4
5
6
7
8

# 2.4 Object Styles 和 String Styles

Emotion 支持 js 对象和 js 字符串两种形式的样式定义。

Object Styles

/** @jsx jsx */
import { jsx } from '@emotion/react'

render(
  <div
    css={{
      backgroundColor: 'hotpink',
      '&:hover': {
        color: 'lightgreen'
      }
    }}
  >
    This has a hotpink background.
  </div>
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

image-20221213124704208

Object Style Documentation (opens new window)

String Styles

要传递字符串样式,您必须使用 @emotion/react导出的css ,它可以用作标记模板文字 (opens new window),如下所示。

// 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: ${color};
      }
    `}
  >
    This has a hotpink background.
  </div>
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

image-20221213124738854

无论是Object Styles还是String Styles,我们都可以直接在定义样式的时候读取上下文的 js 变量,这个可以让我们很方便地更改样式。

# 3.Styled Components

Styled Components 基础用法 Styled Components 导出了一些带有 html 标签的内置组件。

# 3.1 写一个带样式的组件

styled和css非常相似,除了你用 html 标签或 React 组件调用它,然后用字符串样式的模板文字或对象样式的常规函数调用来调用它。

语法:styled.元素名样式

import styled from '@emotion/styled'
const Button = styled.button`
  color: turquoise;
`
render(<Button>This my button component.</Button>)
1
2
3
4
5

image-20221213205055196

# 3.2 通过参数控制样式

Styled Components 的 Props Styled Components 生成的组件也可以根据传入的 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>
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

image-20221213211843757

# 3.3 通过传className创建组件

语法:

styled( ({className}) => (<p className={className}>text</
p>) )`样式`
1
2

分析:相当于把样式通过className传递给了元素

import styled from '@emotion/styled'
const Basic = ({ className }) => (
  <div className={className}>Some text</div>
)
const Fancy = styled(Basic)`
  color: hotpink;
`
render(<Fancy />)
1
2
3
4
5
6
7
8

image-20221213212041581

# 3.4 创建与某个组件相同的样式

有时您想使用一个组件创建一些样式,然后再次将这些样式用于另一个组件,该方法可用于此目的。

语法:样式组件.withComponent('元素')

import styled from '@emotion/styled'
const Section = styled.section`
  background: #333;
  color: #fff;
`
// Aside样式跟Section样式相同
const Aside = Section.withComponent('aside')
render(
  <div>
    <Section>This is a section</Section>
    <Aside>This is an aside</Aside>
  </div>
)
1
2
3
4
5
6
7
8
9
10
11
12
13

image-20221213212523562

# 3.5 嵌套写法

# 3.5.1 ${子组件}

与styled-components (opens new window)类似,当使用@emotion/babel-plugin (opens new window)时,emotion允许emotion components像常规CSS选择器一样被嵌套。

语法:父组件 = styled.元素${子组件} {样式}

import styled from '@emotion/styled'

const Child = styled.div`
  color: red;
`

const Parent = styled.div`
  ${Child} {
    color: green;
  }
`

render(
  <div>
    <Parent>
      <Child>Green because I am inside a Parent</Child>
    </Parent>
    <Child>Red because I am not inside a Parent</Child>
  </div>
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

image-20221213212915098

# 3.5.2 对象(键值对)

组件选择器也可以与对象样式一起使用

语法:

父组件 = styled.元素(
    {
      [子组件]: {样式}
    }
)
1
2
3
4
5
import styled from '@emotion/styled'

const Child = styled.div({
  color: 'red'
})

const Parent = styled.div({
  [Child]: {
    color: 'green'
  }
})

render(
  <div>
    <Parent>
      <Child>green</Child>
    </Parent>
    <Child>red</Child>
  </div>
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

image-20221213213342914

# 3.6 对象样式

import styled from '@emotion/styled'
const H1 = styled.h1(
  {
    fontSize: 20
  },
  props => ({ color: props.color,  width:props.width })
)
render(<H1 color="lightgreen" width="200px">This is lightgreen.</H1>)
1
2
3
4
5
6
7
8

image-20221213214851893

# 3.7 自定义 prop 转发

默认情况下,Emotion 会将所有 props(theme除外)传递给自定义组件,并且仅传递作为字符串标签的有效 html 属性的 prop。可以通过传递自定义函数来自定义此设置。您还可以使用shouldForwardProp来过滤掉无效的 html 属性。

import isPropValid from '@emotion/is-prop-valid'
import styled from '@emotion/styled'

const H1 = styled('h1', {
  shouldForwardProp: prop => isPropValid(prop) && prop !== 'color'
})(props => ({
  color: props.color
}))

render(<H1 color="lightgreen">This is lightgreen.</H1>)
1
2
3
4
5
6
7
8
9
10

image-20221213215311231

# 3.8 动态样式

您可以创建基于 props 的动态样式,并在样式中使用它们。

import styled from '@emotion/styled'
import { css } from '@emotion/react'

const dynamicStyle = props =>
  css`
    color: ${props.color};
  `

const Container = styled.div`
  ${dynamicStyle};
`
render(<Container color="lightgreen">This is lightgreen.</Container>)
1
2
3
4
5
6
7
8
9
10
11
12

image-20221213220140864

# 3.9 as prop

要使用样式化组件中的样式但要更改呈现的元素,可以使用as prop。

import styled from '@emotion/styled'

const Button = styled.button`
  color: hotpink;
`

render(
  <Button as="a" href="https://github.com/emotion-js/emotion">
    Emotion on GitHub
  </Button>
)
1
2
3
4
5
6
7
8
9
10
11

image-20221213220134546

# 3.10 嵌套元素样式写法

我们可以使用以下方法嵌套选择器:&

import styled from '@emotion/styled'
const Example = styled('span')`
  color: lightgreen;
  & > a {
    color: hotpink;
  }
`
render(
  <Example>
    This is <a>nested</a>.
  </Example>
)
1
2
3
4
5
6
7
8
9
10
11
12

image-20221213220109366

# 4.Composition

组合是emotion中最强大、最有用的模式之一。您可以通过在另一个样式块中插入从css返回的值来组合样式。

# 4.1 样式复用

在 Emotion 中,我们可以把通用样式用变量声明,然后在不同的组件中共享。

import { css } from '@emotion/react'

const base = css`
  color: hotpink;
`

render(
  <div
    css={css`
      ${base};
      background-color: #eee;
    `}
  >
    This is hotpink.
  </div>
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

上面的 base 样式在 render 时被使用。如果我们有其它的组件用到 base 样式,我们也可以导入 base 这个变量来使用。

# 4.2 样式优先级

import { css } 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>
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

image-20221213221609976

写样式的时候难免会需要覆盖样式的情况,这时候我们可以像上面一样调整 base 和 danger 的先后顺序来覆盖(后面的样式优先级较高)。

# 5.Object Styles

带对象的写作风格是一种直接构建在emotion核心的强大模式。您可以使用camelCase来编写css属性,而不是像普通css那样使用kebab-case大小写,例如背景色将是backgroundColor。对象样式对于css属性特别有用,因为您不需要像字符串样式那样的css调用,但是对象样式也可以与样式一起使用。

# 5.1 使用 css props

render(
  <div
    css={{
      color: 'darkorchid',
      backgroundColor: 'lightgray'
    }}
  >
    This is darkorchid.
  </div>
)
1
2
3
4
5
6
7
8
9
10

image-20221213223856868

# 5.2 使用styled

import styled from '@emotion/styled'

const Button = styled.button(
  {
    color: 'darkorchid'
  },
  props => ({
    fontSize: props.fontSize
  })
)

render(<Button fontSize={16}>This is a darkorchid button.</Button>)
1
2
3
4
5
6
7
8
9
10
11
12

image-20221213224008883

# 5.3 子选择器

render(
  <div
    css={{
      color: 'darkorchid',
      '& .name': {
        color: 'orange'
      }
    }}
  >
    This is darkorchid.
    <div className="name">This is orange</div>
  </div>
)
1
2
3
4
5
6
7
8
9
10
11
12
13

image-20221213224107609

# 5.4 媒体查询

render(
  <div
    css={{
      color: 'darkorchid',
      '@media(min-width: 420px)': {
        color: 'orange'
      }
    }}
  >
    This is orange on a big screen and darkorchid on a small screen.
  </div>
)
1
2
3
4
5
6
7
8
9
10
11
12

image-20221213224217334

# 5.5 Numbers

render(
  <div
    css={{
      padding: 8,
      zIndex: 200
    }}
  >
    This has 8px of padding and a z-index of 200.
  </div>
)
1
2
3
4
5
6
7
8
9
10

image-20221213224256993

# 5.6 Arrays

嵌套数组被展平

render(
  <div
    css={[
      { color: 'darkorchid' },
      { backgroundColor: 'hotpink' },
      { padding: 8 }
    ]}
  >
    This is darkorchid with a hotpink background and 8px of padding.
  </div>
)
1
2
3
4
5
6
7
8
9
10
11

image-20221213224346539

# 5.7 用css

您也可以将css与对象样式一起使用。

import { css } from '@emotion/react'

const hotpink = css({
  color: 'hotpink'
})

render(
  <div>
    <p css={hotpink}>This is hotpink</p>
  </div>
)
1
2
3
4
5
6
7
8
9
10
11

image-20221213224458835

# 5.8 Composition - 样式复用

Learn more composition in Emotion (opens new window).

import { css } from '@emotion/react'

const hotpink = css({
  color: 'hotpink'
})

const hotpinkHoverOrFocus = css({
  '&:hover,&:focus': hotpink
})

const hotpinkWithBlackBackground = css(
  {
    backgroundColor: 'black',
    color: 'green'
  },
  hotpink
)

render(
  <div>
    <p css={hotpink}>This is hotpink</p>
    <button css={hotpinkHoverOrFocus}>This is hotpink on hover or focus</button>
    <p css={hotpinkWithBlackBackground}>
      This has a black background and is hotpink. Try moving where hotpink is in
      the css call and see if the color changes.
    </p>
  </div>
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

image-20221213224550509

# 6.Nested Selectors

有时,将选择器嵌套到当前类或 React 组件中的元素很有用。下面显示了带有元素选择器的示例。

import { 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>
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

image-20221213224756200

当组件是子组件时,使用 & 来选择自己并设置样式

import { 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>
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

image-20221213224813608

# 7.Media Queries

在emotion中使用媒体查询就像在常规 css 中使用媒体查询一样,只是您不必在块内指定选择器,您可以将 css 直接放在 css 块中。

import { css } from '@emotion/react'

render(
  <p
    css={css`
      font-size: 30px;
      @media (min-width: 420px) {
        font-size: 50px;
      }
    `}
  >
    Some text!
  </p>
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14

image-20221213225036540

# 8.Global Styles

有时您可能希望插入全局 css,例如resets 或 font faces。您可以使用该Global组件来执行此操作。它接受一个 stylesprop,该 prop 接受与css prop 相同的值,除了全局插入样式。当样式更改或全局组件卸载时,也会删除全局样式。

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>
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

image-20221213225321584

# 9.Keyframes

您可以使用@emotive/react中的keyframes来定义动画。keyframe接受css关键帧定义,并返回一个可以在样式中使用的对象。您可以像css一样使用字符串或对象。

import { css, keyframes } from '@emotion/react'

const bounce = keyframes`
  from, 20%, 53%, 80%, 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: ${bounce} 1s ease infinite;
    `}
  >
    some bouncing text!
  </div>
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

image-20221213225454209

# 10.Attaching Props - 附加额外的属性

一些 css-in-js 库提供了将 props 附加到组件的 API,而不是让我们自己的 API 来做到这一点,我们建议创建一个常规的 react 组件,使用 css prop 并像附加任何其他 React 组件一样附加 props。

请注意,如果 css 是通过 props 传递下来的,它将优先于组件中的 css。

import { css } from '@emotion/react'

const pinkInput = css`
  background-color: pink;
`
const RedPasswordInput = props => (
  <input
    type="password"
    css={css`
      background-color: red;
      display: block;
    `}
    {...props}
  />
)

render(
  <div>
    <RedPasswordInput placeholder="red" />
    <RedPasswordInput placeholder="pink" css={pinkInput} />
  </div>
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

image-20221213230119759

# 11.Theming

主题包含在@emotion/react中。 将ThemeProvider添加到应用程序的顶层,并在样式组件中使用props.theme访问主题,或者提供一个接受主题作为css属性的函数。

# 11.1 css prop

import { ThemeProvider } from '@emotion/react'

const theme = {
  colors: {
    primary: 'hotpink'
  }
}

render(
  <ThemeProvider theme={theme}>
    <div css={theme => ({ color: theme.colors.primary })}>some other text</div>
  </ThemeProvider>
)
1
2
3
4
5
6
7
8
9
10
11
12
13

image-20221213230310767

# 11.2 styled

import { ThemeProvider } from '@emotion/react'
import styled from '@emotion/styled'

const theme = {
  colors: {
    primary: 'hotpink'
  }
}

const SomeText = styled.div`
  color: ${props => props.theme.colors.primary};
`

render(
  <ThemeProvider theme={theme}>
    <SomeText>some text</SomeText>
  </ThemeProvider>
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

image-20221213230337193

# 11.3 useTheme hook

import { ThemeProvider, useTheme } from '@emotion/react'

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>
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

image-20221213230505784

# 12.TypeScript

Emotion包括@emotion/react and @emotion/styled的TypeScript定义。这些定义通过对象语法、HTML/SVG标记名和属性类型推断css属性的类型。

@emotion/react

这种方法使用好像比较麻烦,可以去看看官网

Emotion – Package Summaries (opens new window)

@emotion/styled与TypeScript配合使用,无需任何额外配置。

# 12.1 HTML/SVG elements

import styled from '@emotion/styled'

const Link = styled('a')`
  color: red;
`

const Icon = styled('svg')`
  stroke: green;
`

const App = () => <Link href="#">Click me</Link>
1
2
3
4
5
6
7
8
9
10
11

import styled from '@emotion/styled';

const NotALink = styled('div')`
  color: red;
`;

const App = () => (
  <NotALink href="#">Click me</NotALink>
            ^^^^^^^^ Property 'href' does not exist [...]
);
1
2
3
4
5
6
7
8
9
10

withComponent

import styled from '@emotion/styled'

const NotALink = styled('div')`
  color: red;
`

const Link = NotALink.withComponent('a')

const App = () => <Link href="#">Click me</Link>

// No errors!
1
2
3
4
5
6
7
8
9
10
11

# 12.2 定义 props 类型

您可以定义styled components props 的类型。

import styled from '@emotion/styled'

type ImageProps = {
  src: string
  width: number
}

// Using a css block
const Image0 = styled.div<ImageProps>`
  width: ${props => props.width};
  background: url(${props => props.src}) center center;
  background-size: contain;
`
const Image0 = styled('div')<ImageProps>`
  width: ${props => props.width};
  background: url(${props => props.src}) center center;
  background-size: contain;
`

// Or with object styles
const Image1 = styled('div')<ImageProps>(
  {
    backgroundSize: 'contain'
  },
  props => ({
    width: props.width,
    background: `url(${props.src}) center center`
  })
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 12.3 React Components

Emotion还可以设置React组件的样式,并根据预期推断组件 props。

import React, { FC } from 'react'
import styled from '@emotion/styled'

interface ComponentProps {
  className?: string
  label: string
}

const Component: FC<ComponentProps> = ({ label, className }) => (
  <div className={className}>{label}</div>
)

const StyledComponent0 = styled(Component)`
  color: ${props => (props.label === 'Important' ? 'red' : 'green')};
`

const StyledComponent1 = styled(Component)({
  color: 'red'
})

const App = () => (
  <div>
    <StyledComponent0 label="Important" />
    <StyledComponent1 label="Yea! No need to re-type this label prop." />
  </div>
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
上次更新: 2024-09-30 01:09:25

← 21 【styled-components的使用】 23 【UmiJS入门】→

Copyright © 2020-2025 wuzhiyong
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式