react前端开发那些事儿

传统Css与Css-in-JS方案的区别在哪?

2021-10-22  本文已影响0人  又菜又爱分享的小肖

传统Css的缺陷

1. 缺乏模块组织

传统的 JS 和 CSS 都没有模块的概念,后来在 JS 界陆续有了 CommonJS 和 ECMAScript Module,CSS-in-JS 可以用模块化的方式组织 CSS,依托于 JS 的模块化方案,比如:

import styled from '@emotion/styled'

export const Button = styled.button`
  color: turquoise;
`
2. 缺乏作用域

传统的 CSS 只有一个全局作用域,比如说一个 class 可以匹配全局的任意元素。随着项目成长,CSS 会变得越来越难以组织,从此导致类名冲突, 样式冲突。CSS-in-JS 可以通过生成独特的选择符,来实现作用域的效果:

const css = styleBlock => {
  const className = someHash(styleBlock);
  const styleEl = document.createElement('style');
  styleEl.textContent = `
    .${className} {
      ${styleBlock}
    }
  `;
  document.head.appendChild(styleEl);
  return className;
};
const className = css(`
  color: red;
  padding: 20px;
`); // 'c23j4'
3. 隐式依赖, 让样式难以追踪

比如这个css样式:

.target .name h1 {
  color: red
}

body #container h1 {
  color: green
}
<!doctype html>
<html lang="en">
<body>
  <div id='container'>
   <div class='target'>
     <div class='name'>
       <h1>我是啥颜色?</h1>
     </div>
   </div>
  </div>
</body>
</html>

那么这个 h1 元素最终显式为什么颜色?加入你想要追踪这个影响这个 h1 的样式,怎么追踪?
而 CSS-in-JS 的方案就简单直接、易于追踪:

export const Title = styled.h1`
  color: green;
`
<Title>
  我是啥颜色?
</Title>
4. 没有变量

传统的 CSS 规则里没有变量,但是在 CSS-in-JS 中可以方便地控制变量:

const Container = styled.div(props => ({
  display: 'flex',
  flexDirection: props.column && 'column'
}))
5. Css选择器与HTML元素耦合
.target .name h1 {
  color: red
}

body #container h1 {
  color: green
}
<!doctype html>
<html lang="en">
<body>
  <div id='container'>
   <div class='target'>
     <div class='name'>
       <h1>我是啥颜色?</h1>
     </div>
   </div>
  </div>
</body>
</html>

如果你想把 h1 改成 h2,必须要同时改动 CSS 和 HTML。而在 CSS-in-JS 中,HTML 和 CSS 是结合在一起的,易于修改。

Emotion 介绍

Emotion 是目前最受欢迎的 CSS-in-JS 库之一,它还对 React 作了很好的适应,可以方便地创建 styled component,也支持写行内样式:

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

render(
  <div
    css={{
      backgroundColor: 'hotpink',
      '&:hover': {
        color: 'lightgreen'
      }
    }}
  >
    This has a hotpink background.
  </div>
)

这种写法比起 React 自带的 style 的写法功能更强大,比如可以处理级联、伪类等 style 处理的不了的情况:

<span style={{ color: "red" }}>{keyword}</span>
上一篇下一篇

猜你喜欢

热点阅读