javascript - Emotion CSS-in-JS - 如何添加基于组件 Prop 的条件 CSS?

标签 javascript css emotion

我想要一个组件,样式为 Emotion ,这需要最终控制样式的 Prop 。例如,考虑一个 GridCol 组件,它具有各种更改填充和宽度的 Prop (宽度可以在不同的视口(viewport)宽度之间更改)。

我想使用这样的 API:

<GridCol gutter size="2>

// or alternatively, like this:

<GridCol gutter size={{
  m: 2,
  l: 4
}}>

这里发生了三件事:

  • gutter 是一个 bool 属性,用于向列添加一些水平填充
  • size 属性可以是字符串或对象。如果它是一个字符串,我们只需添加几行 CSS 就可以了,但是,如果它是一个对象,我们需要插入一些基于在别处设置的断点对象的媒体查询。

Emotion's docs不清楚如何处理这种性质的样式,至少我还没有看到,所以我希望能找到一个通用的解决方案。

对于 gutter Prop ,它很简单:

const GridCol = props => styled('div')`
  display: block;
  box-sizing: border-box;
  flex: 1 0 0;
  min-width: 0;
  padding: ${props.gutter ? `0 10px` : '0'};
`

对于 size Prop ,它变得更加复杂,我希望生成的 CSS 看起来像这样:

const GridCol = props => styled('div')`
  display: block;
  box-sizing: border-box;
  flex: 1 0 0;
  min-width: 0;
  padding: ${props.gutter ? `0 10px` : '0'};

  /* styles here if  `size` is a string */
  width: 10%;

  /* styles here if  `size` is an object */
  @media screen and (min-width: 500px) {
      width: 20%;
  }


  @media screen and (min-width: 800px) {
      width: 30%;
  }


  @media screen and (min-width: 1100px) {
      width: 40%;
  }
`

width 值将由 prop 的键决定,它对应于 breakpoints 对象中的值,这部分很重要,但我不知道如何动态生成所需的 css。

我确定我可以添加更多信息,我已经做了一些尝试,但目前都没有用。我的感觉是我应该创建一个无状态功能组件,为每个条件生成 css,然后在最后加入 CSS。

最佳答案

这是一个很好的问题。首先,避免这种模式。

const GridCol = props => styled('div')`
  display: block;
  box-sizing: border-box;
  flex: 1 0 0;
  min-width: 0;
  padding: ${props.gutter ? `0 10px` : '0'};
`

在这个例子中,在每次渲染时都会创建一个新样式的组件,这对性能来说很糟糕。

任何表达式或插值都可以是函数。此函数将接收 2 个参数:propscontext

const GridCol = styled('div')`
  display: block;
  box-sizing: border-box;
  flex: 1 0 0;
  min-width: 0;
  padding: ${props => props.gutter ? `0 10px` : '0'};
`

至于您示例中的 size Prop ,我将使用以下模式。

import { css } from 'emotion'

const sizePartial = (props) => typeof props.size === 'string' ?
  css`width: 10%;` :
  css`
   @media screen and (min-width: 500px) {
      width: 20%;
   }


   @media screen and (min-width: 800px) {
      width: 30%;
   }


   @media screen and (min-width: 1100px) {
      width: 40%;
   }
 `

然后您可以像使用表达式中出现的任何其他函数一样使用部分函数。

const GridCol = styled('div')`
  display: block;
  box-sizing: border-box;
  flex: 1 0 0;
  min-width: 0;
  padding: ${props => props.gutter ? `0 10px` : '0'};
  ${sizePartial};
`

这是一个非常强大的模式,可用于在您的元素中组合可重用的动态样式。

如果您对利用此模式的其他库感兴趣,请查看 https://github.com/emotion-js/facepainthttps://github.com/jxnblk/styled-system

关于javascript - Emotion CSS-in-JS - 如何添加基于组件 Prop 的条件 CSS?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47512311/

相关文章:

javascript - 这两种 JavaScript 模式中哪一种更适合实例化对象?

html - CSS - 具有固定 Div 的背景图像

emotion - 什么时候使用样式组件 vs 什么时候在情感中使用 css prop?

javascript - 我怎样才能在 css-in-js Emotion 中通过自动生成的类名搜索代码?

javascript - 如何使用强大的 npm 将文件上传到谷歌云

javascript - innerHTML 仅插入 [object HTMLDivElement]

javascript - d3 zoom 无法像示例中那样工作

html - 在两行中显示 li 元素标题,以适应最大宽度

javascript - 表格中的输入导致表格宽度发生变化