CSS in JS (JSS)
JSS 是什么
简单来说,一句话概括CSS in JS (JSS),就是"行内样式"(inline style)和"行内脚本"(inline script)。
因为,自从React出现以后,基于组件化的要求,强制把HTML、CSS、JavaScript捆绑在一起,在同一个文件里面,封装了结构、样式、以及逻辑。这虽然违背html发明初期的"关注点分离"的原则,但更有利于组件之间的隔离。而每个组件包含了所有需要用到的代码,不必依赖外部环境,组件之间没有耦合。所以,随着 React 的走红和组件模式深入人心,“关注点分离”原则越发淡出人们的视野,而React所带来的"关注点混合"的原则逐渐成为主流。[1]
React 对 CSS 封装非常简单,就是沿用了 DOM 的 style 属性对象。CSS-in-JS是一种技术(technique),而不是一个具体的库实现(library)。简单来说CSS-in-JS就是将应用的CSS样式写在JavaScript文件里面,而不是独立为一些.css,.scss或者less之类的文件,这样你就可以在CSS中使用一些属于JS的诸如模块声明,变量定义,函数调用和条件判断等语言特性来提供灵活的可扩展的样式定义。值得一提的是,虽然CSS-in-JS不是一种很新的技术,可是它在国内普及度好像并不是很高,它当初的出现是因为一些component-based的Web框架(例如React,Vue和Angular)的逐渐流行,使得开发者也想将组件的CSS样式也一块封装到组件中去以解决原生CSS写法的一系列问题。还有就是CSS-in-JS在React社区的热度是最高的,这是因为React本身不会管用户怎么去为组件定义样式的问题,而Vue和Angular都有属于框架自己的一套定义样式的方案。[2]
JSS 的常见实现
由于React 对 CSS 的封装非常弱,导致出现了一系列的第三方库,用来加强 React 的 CSS 操作。它们统称为 CSS in JS,意思就是使用 JS 语言写 CSS。根据不完全统计,各种 CSS in JS 的库至少有47种。老实说,现在也看不出来,哪一个库会变成主流。[1]
1. Styled-components
缺点:
- 必须使用Styled-components预定义的语法糖,如
styled.div("...") - 语法糖对css的封装居然使用的是string,而使用string也就意味着我们将会失去一切可能的对象化操作css的机会。这与差不多10年前
AngularJS 1.x时代对 html 的处理方法如出一辙,不得不说这种方式似乎是在开历史的倒车。
不过,Styled-components 应该是CSS-in-JS最热门的一个库了,到目前为止github的star数已经超过了30k了。通过styled-components,你可以使用ES6的标签模板字符串语法(Tagged Templates)为需要styled的Component定义一系列CSS属性,当该组件的JS代码被解析执行的时候,styled-components会动态生成一个CSS选择器,并把对应的CSS样式通过style标签的形式插入到head标签里面。动态生成的CSS选择器会有一小段哈希值来保证全局唯一性来避免样式发生冲突。[2]
它既具备了 css-in-js 的模块化与参数化优点,又完全使用CSS的书写习惯,不会引起额外的学习成本[3]。
2. CSS module
import style from './index.css'
<div className={style.app}>
需要额外配置,ts环境需要配置*.d.ts的类型声明文件
declare module "*.css" {
const css: {
[key: string]: string //约定:导出key所在的对象,原始的类名和内容都会和转化为这个对象
};
export default css;
}
JSS 的好处
p.s. 接下来内容均转自 知乎/进击的大葱/CSS in JS的好与坏。
1. 局部样式 - Scoping Styles
CSS有一个被大家诟病的问题就是没有本地作用域,所有声明的样式都是全局的(global styles)。而CSS-in-JS会提供自动局部CSS作用域的功能,你为组件定义的样式会被限制在这个组件,而不会对其他组件的样式产生影响。[2]
2. 避免无用的CSS样式堆积
进行过大型Web项目开发的同学应该都有经历过这个情景:在开发新的功能或者进行代码重构的时候,由于HTML代码和CSS样式之间没有显式的一一对应关系,我们很难辨认出项目中哪些CSS样式代码是有用的哪些是无用的,这就导致了我们不敢轻易删除代码中可能是无用的样式。这样随着时间的推移,项目中的CSS样式只会增加而不会减少(append-only stylesheets)。
而因为CSS-in-JS会把样式和组件绑定在一起,当这个组件要被删除掉的时候,直接把这些代码删除掉就好了,不用担心删掉的样式代码会对项目的其他组件样式产生影响。而且由于CSS是写在JavaScript里面的,我们还可以利用JS显式的变量定义,模块引用等语言特性来追踪样式的使用情况,这大大方便了我们对样式代码的更改或者重构。[2]
3 Critical CSS
放在head标签内的CSS当然是越少越好,因为太多的内容会加大html的体积,所以我们一般把用户需要在首屏看到的(above the fold)页面要用到的最少CSS提取为Critical CSS。
CSS-in-JS通过增加一点加载的JS体积就可以避免另外发一次请求来获取其它的CSS文件。而且一些CSS-in-JS的实现(例如styled-components)对Critical CSS是自动支持的。[2]
4. 基于状态的样式定义
CSS-in-JS可以根据组件的状态动态地生成样式。[2]
5. 封装得更好的组件库
如果CSS是写在JS里面的,项目想要使用封装的组件库只需要进行简单的npm install就可以了,非常方便。[2]
JSS 的坏处
p.s. 接下来内容均转自 知乎/进击的大葱/CSS in JS的好与坏。
1. 陡峭的学习曲线
首先CSS-in-JS是针对component-based的框架的,这就意味着要学习CSS-in-JS你必须得学习:component-based框架(例如React),JavaScript和CSS这三样技能。其次,即使你已经会用React,JavaScript和CSS来构建SPA应用,你还要学习某个CSS-in-JS实现(例如styled-components),以及学习一种全新的基于组件定义样式的思考问题方式。[2]
2. 运行时消耗
由于大多数的CSS-in-JS的库都是在动态生成CSS的, 这就意味着会有一定的性能代价[2]
3. 代码可读性差
大多数CSS-in-JS实现会通过生成唯一的CSS选择器来达到CSS局部作用域的效果。这些自动生成的选择器会大大降低代码的可读性,给开发人员debug造成一定的影响。[2]
4. 没有统一的业界标准
CSS-in-JS只是一种技术思路而没有一个社区统一遵循的标准和规范,所以不同实现的语法和功能可能有很大的差异。[2]
总结
CSS-in-JS有好处也有坏处,要不要使用完全取决于同学们自己的项目需求。例如在下面几种情况下你就不需要它:
- 前端开发的初学者: 由于CSS-in-JS的学习坡度很陡,刚开始学习Web开发的同学没必要学习,可能会有挫败感。
- 功能简单的静态页面:逻辑交互不复杂的网站没有必要使用CSS-in-JS。
- 注重样式可读性以及调试体验: CSS-in-JS动态生成的选择器很影响代码的可读性,可能会降低你的调试效率。
在我们的课程中,我们CSS-in-JS和普通的css我们都会使用,所以请同学们放心,进过本课程的学习,同学们基本上能掌握如何使用不同的方式来定义React的样式了。
参考文献
- [1] 阮一峰的网络日志/CSS in JS 简介
- [2] 知乎/进击的大葱/CSS in JS的好与坏
- [3] Styled Components: Enforcing Best Practices In Component-Based Systems
- [3] JSS
- [4] wikipedia
CSS in JS (JSS)的更多相关文章
- 了解CSS in JS(JSS)以及在React项目中配置并使用JSS
目录 认识JSS 什么是JSS JSS 的常见实现 JSS 的好处与坏处 好处 坏处 使用模块化CSS实现JSS 安装插件 在React项目中的tsconfig.json中添加配置 vscode项目中 ...
- JQuery 加载 CSS、JS 文件
JS 方式加载 CSS.JS 文件: //加载 css 文件 function includeCss(filename) { var head = document.getElementsByTagN ...
- grunt自定义任务——合并压缩css和js
npm文档:www.npmjs.com grunt基础教程:http://www.gruntjs.net/docs/getting-started/ http://www.w3cplus.com/to ...
- 来,一起让我们越来越懒,面向CSS、JS未来编程。(9.28已更新)
2016.10.29更新 本文存在大量的错误,仅供参考. 不知不觉在前端领域马上一个年头就要过去了,然而再看看自己的代码,果然够烂,那么为什么代码一直没有用面向对象的思维去写CSS呢?首先有两点:一点 ...
- 如何判断一个DOM元素正在动画,一个CSS“阻塞”JS的例子
一般情况下CSS不会直接影响JS的程序逻辑,但是以CSS实现动画的话,这个便不太确定了,这个故事发生在与UED迁移全局样式的过程. 曾经我有一段实现弹出层隐藏动画的代码是这个样子的: if (this ...
- Asp.net 后台添加CSS、JS、Meta标签
Asp.net 后台添加CSS.JS.Meta标签的写法,我这里写成函数方便以后使用.如果函数放在页面类中, Page参数也可以不要. 首先导入命名空间 using System.Web.UI.Htm ...
- django 关于html、css、js 目录位置
项目目录: project/ ---------------init.py ---------------views.py ---------------settings.py ----------- ...
- CI模板加载css和js
1.需求 ci无法加载css和js文件. 2.解决 删除..htaccess文件. 在config目录下配置base_url,并传给页面 $base_url = $this->config-&g ...
- HTML、CSS、JS对unicode字符的不同处理
unicode字符的不同表示法 unicode字符在html.css和js中的表示方法均不相同,下面分别作介绍. 原文发表于这里 css表示法 首先来一段很常见的bootstrap的字体图标代码: . ...
- 关于webStrom-11.1配置less且自动生成.css和自动压缩为.min.css/.min.js
网上看过很多配置思路,自己总结了以下, 就把我个人配置的顺序以及材料分享下,webstrom以下简称WB 1.配置less需要安装nodejs,自行安装.因为要用到npm.我是直接把npm解压到C盘根 ...
随机推荐
- Redis Stream实现全部节点机器推送消息
背景 有时候,在微服务时代,我们需要对全部的机器节点进行通知.在常规情况下,一个请求经过负载均衡只有一个机器可以收到.那么,如何能让全部的机器都收到同样的请求呢?需要借助消息队列的监听机制,让每个节点 ...
- Edge浏览器相关
Ctrl+T 新建页面 Ctrl+W 关闭页面 不可复制的页面,前加read: 若是不可访问 变read://http:// 阅读可翻译,也可有图片字典 还可用插件: 截图软件:Snipaste 微 ...
- 浙大版《C语言程序设计(第3版)》题目集 练习3-3 统计学生平均成绩与及格人数 (15 分)
练习3-3 统计学生平均成绩与及格人数 (15 分) 本题要求编写程序,计算学生们的平均成绩,并统计及格(成绩不低于60分)的人数.题目保证输入与输出均在整型范围内. 输入格式: 输入在第一行中给出非 ...
- Springboot项目记录1配置环境
一.电脑商城项目: 项目功能:登录,注册,热销商品,用户管理(密码,个人信息,头像,收货地址).购物车(展示.增加.删除).订单模块. 二.开发顺序: 注册.登录.用户管理.购物车.商品.订单模块 三 ...
- 终端命令mix
Jdk(1.7) java -version Maven是否安装 mvn -v MySQL(5.7) mysql -uroot -p /Users/zhanzhanyunjiu/Documents/a ...
- nginx中proxy_set_header Host $host的作用
nginx配置upstream负载均衡后请求400,配置proxy_set_header Host $host成功.请问这是什么原理? proxy_set_header Host $host有什么作用 ...
- elasticsearch的Kibana基本操作
幂等(idempotent.idempotence)是一个数学与计算机学概念,常见于抽象代数中. 在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同.幂等函数,或幂等方法,是 ...
- 十大经典排序之快速排序(C++实现)
快速排序 通过一趟排序将待排序列分割成两部分,其中一部分记录的关键字均比另一部分记录的关键字小.之后分别对这两部分记录继续进行排序,以达到整个序列有序的目的. 思路: (1)选择基准:从数列中挑出一个 ...
- linux学习之vi
vi 删除当前行dd 删除当前行及下面内容 dG 删除第2行到第3行2d 3d 删除指定行,删除第5行 5dd 删除当前行以下3行 d3
- web自动化测试—Firefox安装与配置
web自动化测试-Firefox安装与配置 下一步 下一步 下一步 下一步 下一步 下一步 下一步 下一步 下一步设置不更新 下一步添加插件 下一步 下一步 下一步 下一步立即重启 下一步查看插件 在 ...