CSS in JS (JSS)库 Styled-components

2024-04-13 03:04

本文主要是介绍CSS in JS (JSS)库 Styled-components,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

#CSS in JS (JSS)

JSS 是什么

简单来说,一句话概括CSS in JS (JSS),就是"行内样式"(inline style)和"行内脚本"(inline script)。

因为,自从React出现以后,基于组件化的要求,强制把HTML、CSS、JavaScript捆绑在一起,在同一个文件里面,封装了结构、样式、以及逻辑。这虽然违背html发明初期的"关注点分离"的原则,但更有利于组件之间的隔离。而每个组件包含了所有需要用到的代码,不必依赖外部环境,组件之间没有耦合。所以,随着 React 的走红和组件模式深入人心,“关注点分离”原则越发淡出人们的视野,而React所带来的"关注点混合"的原则逐渐成为主流。

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都有属于框架自己的一套定义样式的方案。

JSS 的常见实现

由于React 对 CSS 的封装非常弱,导致出现了一系列的第三方库,用来加强 React 的 CSS 操作。它们统称为 CSS in JS,意思就是使用 JS 语言写 CSS。根据不完全统计,各种 CSS in JS 的库至少有47种。老实说,现在也看不出来,哪一个库会变成主流。

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选择器会有一小段哈希值来保证全局唯一性来避免样式发生冲突。

它既具备了 css-in-js 的模块化与参数化优点,又完全使用CSS的书写习惯,不会引起额外的学习成本。

Styled-components官网。

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 的好处

1. 局部样式 - Scoping Styles
CSS有一个被大家诟病的问题就是没有本地作用域,所有声明的样式都是全局的(global styles)。而CSS-in-JS会提供自动局部CSS作用域的功能,你为组件定义的样式会被限制在这个组件,而不会对其他组件的样式产生影响。

2. 避免无用的CSS样式堆积
进行过大型Web项目开发的同学应该都有经历过这个情景:在开发新的功能或者进行代码重构的时候,由于HTML代码和CSS样式之间没有显式的一一对应关系,我们很难辨认出项目中哪些CSS样式代码是有用的哪些是无用的,这就导致了我们不敢轻易删除代码中可能是无用的样式。这样随着时间的推移,项目中的CSS样式只会增加而不会减少(append-only stylesheets)。

而因为CSS-in-JS会把样式和组件绑定在一起,当这个组件要被删除掉的时候,直接把这些代码删除掉就好了,不用担心删掉的样式代码会对项目的其他组件样式产生影响。而且由于CSS是写在JavaScript里面的,我们还可以利用JS显式的变量定义,模块引用等语言特性来追踪样式的使用情况,这大大方便了我们对样式代码的更改或者重构。

3 Critical CSS
放在head标签内的CSS当然是越少越好,因为太多的内容会加大html的体积,所以我们一般把用户需要在首屏看到的(above the fold)页面要用到的最少CSS提取为Critical CSS。

CSS-in-JS通过增加一点加载的JS体积就可以避免另外发一次请求来获取其它的CSS文件。而且一些CSS-in-JS的实现(例如styled-components)对Critical CSS是自动支持的。

4. 基于状态的样式定义
CSS-in-JS可以根据组件的状态动态地生成样式。

5. 封装得更好的组件库
如果CSS是写在JS里面的,项目想要使用封装的组件库只需要进行简单的npm install就可以了,非常方便。

JSS 的坏处

1. 陡峭的学习曲线
首先CSS-in-JS是针对component-based的框架的,这就意味着要学习CSS-in-JS你必须得学习:component-based框架(例如React),JavaScript和CSS这三样技能。其次,即使你已经会用React,JavaScript和CSS来构建SPA应用,你还要学习某个CSS-in-JS实现(例如styled-components),以及学习一种全新的基于组件定义样式的思考问题方式。

2. 运行时消耗
由于大多数的CSS-in-JS的库都是在动态生成CSS的, 这就意味着会有一定的性能代价

3. 代码可读性差
大多数CSS-in-JS实现会通过生成唯一的CSS选择器来达到CSS局部作用域的效果。这些自动生成的选择器会大大降低代码的可读性,给开发人员debug造成一定的影响。

4. 没有统一的业界标准
CSS-in-JS只是一种技术思路而没有一个社区统一遵循的标准和规范,所以不同实现的语法和功能可能有很大的差异。

总结
CSS-in-JS有好处也有坏处,要不要使用完全取决于同学们自己的项目需求。例如在下面几种情况下你就不需要它:

前端开发的初学者: 由于CSS-in-JS的学习坡度很陡,刚开始学习Web开发的同学没必要学习,可能会有挫败感。
功能简单的静态页面:逻辑交互不复杂的网站没有必要使用CSS-in-JS。
注重样式可读性以及调试体验: CSS-in-JS动态生成的选择器很影响代码的可读性,可能会降低你的调试效率。
在我们的课程中,我们CSS-in-JS和普通的css我们都会使用,所以请同学们放心,进过本课程的学习,同学们基本上能掌握如何使用不同的方式来定义React的样式了。

这篇关于CSS in JS (JSS)库 Styled-components的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/898971

相关文章

Vue中组件之间传值的六种方式(完整版)

《Vue中组件之间传值的六种方式(完整版)》组件是vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用,针对不同的使用场景,如何选择行之有效的通信方式... 目录前言方法一、props/$emit1.父组件向子组件传值2.子组件向父组件传值(通过事件形式)方

css中的 vertical-align与line-height作用详解

《css中的vertical-align与line-height作用详解》:本文主要介绍了CSS中的`vertical-align`和`line-height`属性,包括它们的作用、适用元素、属性值、常见使用场景、常见问题及解决方案,详细内容请阅读本文,希望能对你有所帮助... 目录vertical-ali

浅析CSS 中z - index属性的作用及在什么情况下会失效

《浅析CSS中z-index属性的作用及在什么情况下会失效》z-index属性用于控制元素的堆叠顺序,值越大,元素越显示在上层,它需要元素具有定位属性(如relative、absolute、fi... 目录1. z-index 属性的作用2. z-index 失效的情况2.1 元素没有定位属性2.2 元素处

Python实现html转png的完美方案介绍

《Python实现html转png的完美方案介绍》这篇文章主要为大家详细介绍了如何使用Python实现html转png功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 1.增强稳定性与错误处理建议使用三层异常捕获结构:try: with sync_playwright(

Vue 调用摄像头扫描条码功能实现代码

《Vue调用摄像头扫描条码功能实现代码》本文介绍了如何使用Vue.js和jsQR库来实现调用摄像头并扫描条码的功能,通过安装依赖、获取摄像头视频流、解析条码等步骤,实现了从开始扫描到停止扫描的完整流... 目录实现步骤:代码实现1. 安装依赖2. vue 页面代码功能说明注意事项以下是一个基于 Vue.js

CSS @media print 使用详解

《CSS@mediaprint使用详解》:本文主要介绍了CSS中的打印媒体查询@mediaprint包括基本语法、常见使用场景和代码示例,如隐藏非必要元素、调整字体和颜色、处理链接的URL显示、分页控制、调整边距和背景等,还提供了测试方法和关键注意事项,并分享了进阶技巧,详细内容请阅读本文,希望能对你有所帮助...

Nginx实现前端灰度发布

《Nginx实现前端灰度发布》灰度发布是一种重要的策略,它允许我们在不影响所有用户的情况下,逐步推出新功能或更新,通过灰度发布,我们可以测试新版本的稳定性和性能,下面就来介绍一下前端灰度发布的使用,感... 目录前言一、基于权重的流量分配二、基于 Cookie 的分流三、基于请求头的分流四、基于请求参数的分

基于Canvas的Html5多时区动态时钟实战代码

《基于Canvas的Html5多时区动态时钟实战代码》:本文主要介绍了如何使用Canvas在HTML5上实现一个多时区动态时钟的web展示,通过Canvas的API,可以绘制出6个不同城市的时钟,并且这些时钟可以动态转动,每个时钟上都会标注出对应的24小时制时间,详细内容请阅读本文,希望能对你有所帮助...

HTML5 data-*自定义数据属性的示例代码

《HTML5data-*自定义数据属性的示例代码》HTML5的自定义数据属性(data-*)提供了一种标准化的方法在HTML元素上存储额外信息,可以通过JavaScript访问、修改和在CSS中使用... 目录引言基本概念使用自定义数据属性1. 在 html 中定义2. 通过 JavaScript 访问3.

CSS模拟 html 的 title 属性(鼠标悬浮显示提示文字效果)

《CSS模拟html的title属性(鼠标悬浮显示提示文字效果)》:本文主要介绍了如何使用CSS模拟HTML的title属性,通过鼠标悬浮显示提示文字效果,通过设置`.tipBox`和`.tipBox.tipContent`的样式,实现了提示内容的隐藏和显示,详细内容请阅读本文,希望能对你有所帮助... 效