你需要知道的CSS-in-JS

2017 年 11 月 24 日 前端之巅 薛命灯 编译

什么是 CSS-in-JS?直接在.css 文件里写 CSS(CSS-in-CSS)不是挺好的吗,为什么还需要 CSS-in-JS?

说到这里,不得不提到组件化。因为有了组件化概念,就不再需要维护一大堆杂乱的样式。CSS-in-JS 在组件层面(而不是文档层面)对 CSS 进行了抽象。在项目中维护一个巨大的样式文件夹实在是一件让人感到头疼的事情,很多人不禁感叹,是否还有其他更好的办法?不用说,CSS-in-JS 在目前看来就是一个最佳解决方案。

当然,要继续使用 CSS-in-CSS 还是转向 CSS-in-JS 完全取决于开发者自己,最关键的是选择合适的工具来改进开发工作流,在提升生产力的同时也让开发变得更有趣。

什么是 CSS-in-JS?


JSS 对 CSS 进行了抽象,使用了 JavaScript,以声明和可维护的方式来描述样式。它是一个高性能、运行在服务器端的运行时 JS 到 CSS 编译器。它的核心部分与框架无关,经过压缩后只有 6KB,并可以通过插件 API 的方式进行扩展。

需要注意的是,内联样式和 CSS-in-JS 是完全不一样的!

内联样式

const textStyles = {
    color: white,
    backgroundColor: black
  }

<p style={textStyles}>inline style!</p>

在浏览器里,样式属性会被附加到 DOM 节点上:

<p style="color: white; backgrond-color: black;">inline style!</p>

CSS-in-JS

import styled from 'styled-components';

const Text = styled.div`
  color: white,
  background: black
`

<Text>Hello CSS-in-JS</Text>

在浏览器里,样式类会被附加到 DOM 节点上:

<style>
.hash136s21 {
  background-color: black;
  color: white;
}
</style>

<p class="hash136s21">Hello CSS-in-JS</p>

可以看出,CSS-in-JS 会附加整个<style>标签的内容,而内联样式只会把属性附加到 DOM 节点上。


这有什么实际意义?


并不是所有的 CSS 特性在 JavaScript 里都有与之对应的事件处理器,很多伪类选择器(如:disabled:before:nth-child)是不受支持的,当然也不支持在 html 和 body 标签上应用样式。

而 CSS-in-JS 可以发挥 CSS 所有的特性,因为它会生成实际的 CSS,这也就可以使用任意的选择器。一些包(如 jss、styled-components)甚至支持嵌套!


使用 CSS-in-JS 有什么好处?


使用 CSS-in-JS 至少有以下好处:

  • 面向组件——不再需要维护一大堆乱糟糟的样式,CSS-in-JS 在组件层面(而不是文档层面)对 CSS 进行了抽象。

  • CSS-in-JS 利用 JavaScript 生态系统的强大能力来增强 CSS。

  • “真正的规则隔离”——对选择器定义作用域还远远不够。如果没有显式定义,CSS 的属性就会自动继承自父元素,而使用 jss-isolate 插件就可以防止 JSS 规则继承属性。

  • 选择器作用域——CSS 只有一个全局的命名空间,所以是无法避免出现选择器冲突的。或许 BEM 这样的命名规范对单个项目来说能起到作用,但要与第三方代码集成时就不一定了。JSS 在将 JSON 编译成 CSS 时会自动生成唯一的类名。

  • 浏览器引擎前缀——CSS 规则自动添加了浏览器引擎前缀。

  • 代码共享——在 JS 和 CSS 之间共享常量和函数。

  • 只生成页面会用到的样式。

  • 移除无效代码。

  • CSS 单元测试。


CSS-in-JS 的不足


不过它也有一些不尽如人意的地方:

  • 学习曲线比较陡。

  • 引入新的依赖。

  • 新手难以将其应用在项目中,他们需要学习更多的东西。

  • 挑战现有标准(这个其实算不上是个缺陷)。

但从总体上看,优势还是远远盖过它的缺点。


最为流行的几个 CSS-in-JS 框架


下面介绍几个流行的 CSS-in-JS 框架,它们在 NPM 上的热度如下图:


看大图戳


下面主要展示它们的代码风格。

Styled Components

https://www.styled-components.com/

JSS-React

https://github.com/cssinjs/react-jss

glamorous

https://glamorous.rocks/

Radium

http://formidable.com/open-source/radium/

Aphrodite

https://github.com/Khan/aphrodite

Stylotron

在 Github 上甚至有个专门收集 CSS-in-JS 的项目:

https://github.com/tuchk4/awesome-css-in-js

你怎么看CSS-in-JS呢?你会使用上面这些项目吗?


前端之巅


「前端之巅」是 InfoQ 旗下关注前端技术的垂直社群,加入前端之巅学习群请关注「前端之巅」公众号后回复“加群”。投稿请发邮件到 editors@cn.infoq.com,注明“前端之巅投稿”。

活动推荐:

大前端时代正在降临,如何应对业务代码的维护迭代成本,终端碎片下,各互联网企业有何经验可寻?12 月 8-11 日,ArchSummit 全球架构师峰会即将于北京举行,我们想给你这个时代下来自大前端工程师最重要的经验值。目前大会 9 折报名最后一周,大会完整演讲目录,可识别下方二维码或点击 阅读原文 了解,期待和你一同进步!

登录查看更多
0

相关内容

层叠样式表(Cascading Style Sheet)是一种用来为结构化文档(如 HTML 文档或 XML 应用)添加样式(字体、间距和颜色等)的计算机语言。
TensorFlow 2.0 学习资源汇总
专知会员服务
66+阅读 · 2019年10月9日
2020年你应该知道的8种前端JavaScript趋势和工具
前端之巅
5+阅读 · 2019年6月9日
PHP使用Redis实现订阅发布与批量发送短信
安全优佳
7+阅读 · 2019年5月5日
使用 C# 和 Blazor 进行全栈开发
DotNet
6+阅读 · 2019年4月15日
PyTorch 1.0尝鲜版,这些改进你需要注意
专知
4+阅读 · 2018年10月3日
2018年7月份GitHub开源项目排行榜
算法与数据结构
15+阅读 · 2018年8月3日
在浏览器中使用tensorflow.js进行人脸识别的JavaScript API
人工智能头条
6+阅读 · 2018年7月2日
Scikit-learn玩得很熟了?这些功能你都知道吗?
大数据文摘
4+阅读 · 2018年5月13日
刚开始学编程?这几款小工具能让你事半功倍
浅谈浏览器 http 的缓存机制
前端大全
6+阅读 · 2018年1月21日
Vue.js 很好,但是比 Angular 或 React 更好吗?
程序猿
3+阅读 · 2017年8月27日
3D Deep Learning on Medical Images: A Review
Arxiv
12+阅读 · 2020年4月1日
Object detection on aerial imagery using CenterNet
Arxiv
6+阅读 · 2019年8月22日
Object Detection in 20 Years: A Survey
Arxiv
48+阅读 · 2019年5月13日
Arxiv
5+阅读 · 2018年10月23日
VIP会员
相关资讯
2020年你应该知道的8种前端JavaScript趋势和工具
前端之巅
5+阅读 · 2019年6月9日
PHP使用Redis实现订阅发布与批量发送短信
安全优佳
7+阅读 · 2019年5月5日
使用 C# 和 Blazor 进行全栈开发
DotNet
6+阅读 · 2019年4月15日
PyTorch 1.0尝鲜版,这些改进你需要注意
专知
4+阅读 · 2018年10月3日
2018年7月份GitHub开源项目排行榜
算法与数据结构
15+阅读 · 2018年8月3日
在浏览器中使用tensorflow.js进行人脸识别的JavaScript API
人工智能头条
6+阅读 · 2018年7月2日
Scikit-learn玩得很熟了?这些功能你都知道吗?
大数据文摘
4+阅读 · 2018年5月13日
刚开始学编程?这几款小工具能让你事半功倍
浅谈浏览器 http 的缓存机制
前端大全
6+阅读 · 2018年1月21日
Vue.js 很好,但是比 Angular 或 React 更好吗?
程序猿
3+阅读 · 2017年8月27日
Top
微信扫码咨询专知VIP会员