2023前端最流行6款零运行时CSS-in-JS 库
bigegpt 2024-09-24 07:35 4 浏览
大家好,很高兴又见面了,我是"高级前端?进阶?",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发,您的支持是我不断创作的动力。
CSS-in-JS 技术用于在同一文件中编写组件和样式,同时保持简单性和清晰度。
根据 styled-components 创建者 Max Stoiber 的说法,超过 60% 的 React 安装者还安装了 CSS-in-JS 库。 在 JavaScript 中编写 CSS 非常流行,尤其是在使用 React 或 Angular 等 JS 框架时。 但是许多库可用于简化编写 CSS-in-JS 的过程,本文将向大家介绍6款零运行时 CSS-in-JS 库。
什么是 CSS-in-JS
CSS-in-JS 是一种样式技术,使用 JavaScript 直接对组件进行样式设置,其使用变量来定义组件的 CSS。 该变量将包含所有 CSS 属性,确保组件与其指定的样式无缝衔接。
随着基于组件的样式变得越来越流行,CSS-in-JS 近年来也有所增加。 由于大多数现代 JavaScript 框架都是组件化,从而进一步推动 CSS-in-JS 的流行。 CSS 现已嫣然成为 JavaScript 的一个模块,可以在需要时自由定义和使用。
在类似 React 的现代框架中,开发者可以通过编写 CSS-in-JS 使用内联技术在 JavaScript 文件的 JSX 部分中编写 CSS。 但这种技术可能会令人困惑、可读性较差,并且可能会破坏代码流程。 通过库编写 CSS-in-JS 并不能取代 CSS 的模块化。
使用 CSS-in-JS
在 CSS-in-JS 中,开发者可以在变量中定义样式,然后通过用变量标签包装组件来设置组件样式。
styled 标签是从库中导入,创建一个具有预定义样式的 React 组件,然后在 HTML 标签中使用。 下面的示例使用 h1,根据定义的 CSS 属性进行自定义。 编码完成后,定义属性,如下所示:
const Title = styled.h1`
font-family: sans-serif;
font-size: 48px;
color: #f15f79;
`;
接下来,将内容包装在变量标签中:
const App = () => <Title>Hello world!</Title>;
这就是在大多数 CSS-in-JS 库中定义样式的方式。
使用 CSS-in-JS 的优点
使用 CSS-in-JS 具有以下优点:
- 轻松实现代码共享:使用 CSS-in-JS 共享代码更容易、更高效,因为其他人可以轻松理解代码,而无需尝试在项目中查找组件和样式
- 减少 DOM 负载:因为将 CSS 和组件定义在同一个文件中,所以组件的 CSS 仅在组件加载时才会加载,减少了虚拟 DOM 上不必要的负载
- 在 CSS 中使用 JavaScript:由于 CSS 是在 JavaScript 文件中定义的,因此可以使用复杂的 JavaScript 逻辑来定义 CSS 属性的值
- CSS 中更好的错误处理:由于 CSS 也会经历编译过程,因此会在编译过程中收到错误消息,从而可以轻松查找和解决 CSS 中潜在的错误
- 可移植性:将样式和组件放在同一个文件中可以轻松在其他项目中使用该组件
使用 CSS-in-JS 的缺点
使用 CSS-in-JS 有一些缺点,包括:
- 由于样式是在 JavaScript 文件中定义的,因此如果禁用 JavaScript,将会影响组件的样式
- 样式被双重解析,一次由库解析,然后在插入样式时由浏览器解析
- 传统上,当加载网页时,浏览器只是读取 CSS 并渲染。 当使用 CSS-in-JS 时,浏览器动态生成 CSS 样式标签,然后读取它并将其应用到网页,而读取和生成此内容会消耗性能时间
编译时和运行时 CSS-in-JS
编译时是指用高级、人类可读语言编写的代码被编译器转换为低级、机器可读代码,而运行时是指程序转换后的代码在最终用户的计算机上运行。
改善 CSS-in-JS 由于双重解析而导致的性能时间损失的解决方案之一是,库可以首先将 CSS-in-JS 块转换为单独的 CSS 文件。 然后,浏览器将读取这些样式并将其应用到网页,最终节省生成 style 标签时浪费的时间。 这称为零运行时 CSS-in-JS。 它对于性能至关重要的规模化或复杂的项目特别有用。
零运行时 CSS-in-JS 的方案
Linaria
Linaria 的编译时 CSS-in-JS 工具提供了介于纯 CSS 解决方案和运行时 CSS-in-JS 方法之间的中间解决方案,即编译时方案。
Linaria 具有以下特征:
- 在 JS 中编写 CSS,但运行时为零,CSS 在构建期间被提取到 CSS 文件
- 熟悉的 CSS 语法与 Sass 类似嵌套
- 将基于动态 prop 的样式与 React 绑定一起使用,在幕后使用 CSS 变量。即动态样式使用 CSS 变量,从而不需要任何运行时
- 使用 CSS 源映射轻松找到定义样式的位置便于调试
- 使用 stylelint 在 JS 中检查 CSS
- 使用 JavaScript 进行逻辑,无需 CSS 预处理器
- 可以选择使用任何 CSS 预处理器,例如 Sass 或 PostCSS
- 使用 @linaria/atomic 支持原子样式
总之,Linaria 在编译时生成 CSS 类并将其提取到单独的 CSS 文件中,而不是在运行时生成。 这使得可以避免运行时 CSS-in-JS 解决方案的性能损失,同时保留组件隔离和动态样式匹配的优势。
import { css } from '@linaria/core';
import { modularScale, hiDPI } from 'polished';
import fonts from './fonts';
// Write your styles in `css` tag
const header = css`
text-transform: uppercase;
font-family: ${fonts.heading};
font-size: ${modularScale(2)};
${hiDPI(1.5)} {
font-size: ${modularScale(2.5)};
}
`;
// Then use it as a class name
<h1 className={header}>Hello world</h1>;
使用 Linaria 的缺点主要包括以下两点:
- 难以实施:正确实施 Linaria 可能很困难,因为它需要设置 Babel
- 设置打包器:从 JS 文件中提取 CSS 需要使用打包器,例如 Rollup 或 webpack、Vite,有一定的技术门槛
下面是 Linaria 的完整的 Webpack 示例配置:
const webpack = require('webpack');
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const dev = process.env.NODE_ENV !== 'production';
module.exports = {
mode: dev ? 'development' : 'production',
devtool: 'source-map',
entry: {
app: './src/index',
},
output: {
path: path.resolve(__dirname, 'dist'),
publicPath: '/dist/',
filename: '[name].bundle.js',
},
optimization: {
noEmitOnErrors: true,
},
plugins: [
new webpack.DefinePlugin({
'process.env': { NODE_ENV: JSON.stringify(process.env.NODE_ENV) },
}),
new MiniCssExtractPlugin({ filename: 'styles.css' }),
// 将所有文件中的 CSS 提取到单个 styles.css 中
],
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{ loader: 'babel-loader' },
// 最终通过Babel处理
{
loader: '@linaria/webpack-loader',
options: { sourceMap: dev },
},
// 添加js文件的linaria的自定义loader
],
},
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
{
loader: 'css-loader',
options: { sourceMap: dev },
},
],
},
{
test: /\.(jpg|png|gif|woff|woff2|eot|ttf|svg)$/,
use: [{ loader: 'file-loader' }],
},
],
},
devServer: {
contentBase: [path.join(__dirname, 'public')],
historyApiFallback: true,
},
};
Astroturf
Astroturf 允许开发者在 JavaScript 文件中编写 CSS,而无需添加任何运行时层,并使用现有的 CSS 处理管道。
Astroturf 具有以下特征:
- 零运行时 CSS-in-JS: 获得与 CSS-in-JS 相同的许多好处,但不会失去需要特定于框架的 CSS 处理的灵活性,同时保持 CSS 完全静态,无需运行时样式解析。
- 使用现有工具 :Sass、PostCSS、Less 等工具依然可用 , 但仍将样式定义写入 JavaScript 文件中
- 整个组件位于单个文件中: 在模板文字中编写 CSS,然后像在单独的文件中一样使用
import React from 'react';
import { css } from 'astroturf';
const btn = css`
color: black;
border: 1px solid black;
background-color: white;
`;
export default function Button({ children }) {
return <button className={btn}>{children}</button>;
}
Astroturf 的缺点主要包括:
- 糟糕的文档:Astroturf 在 GitHub 上缺乏合适的自述文件。 它还缺乏贡献指南,并且文档很短,经常遗漏重要细节
- 实现:为了提取样式,Astroturf 需要 Rollup 或 webpack 等捆绑器,这可能很难实现
Reshadow
Reshadow 用 JavaScript 编写。 该库提供了许多功能,最值得注意的是为 React 等虚拟 DOM 框架提供了 Shadow DOM 开发人员体验,同时还支持 CSS-in-JS 语法。
Reshadow 的典型特征包括:
- 摆脱额外的抽象
- 以类似本机的方式为虚拟 DOM 编写独立的语义样式
- 匹配元素、组件和 prop 的样式
- 编译时样式处理和高效运行时
- 静态样式提取选项
- 静态分析
- 结合 css-in-js 和 css-modules 方法或选择更适合您的方法
- PostCSS 生态系统的所有优势
- 可互操作,支持将其与 React、Preact、Vue、htm 中的组件一起使用。
import styled, { css } from 'reshadow';
const styles = css`
button {
font-size: 16px;
cursor: pointer;
padding: 10px 15px;
border-radius: 20px;
border: 2px solid;
background-color: white;
color: darkorange;
}
`;
const Button = ({ children, ...props }) =>
styled(styles)(<button {...props}>{children}</button>);
Reshadow 的缺点包括:
- 文档和内容较差:网络上关于 Reshadow 的内容很少,而且文档也不是很全面。 因此,学习需要时间并且可能很困难
- 贡献者较少:Reshadow 的贡献者很少,这减慢了解决附加到其 GitHub 存储库的问题的过程
vanilla-extract
vanilla-extract 是 TypeScript 中的零运行时样式表。使用本地范围(locally scoped)的类名和 CSS 变量在 TypeScript(或 JavaScript)中编写样式,然后在构建时生成静态 CSS 文件。
基本上,它是“TypeScript 中的 CSS Modules”,但具有作用域 CSS 变量 等更多特性。
- 所有在构建时生成的样式 : 就像 Sass、Less 等。
- ? 对标准 CSS 的最小抽象。
- 可与任何前端框架配合使用,甚至无需任何前端框架。
- 本地范围的类名,就像 CSS module 一样。
- 本地范围的 CSS 变量、@keyframes 和 @font-face 规则。
- 高级主题系统,支持同步主题,而且没有全局变量
- 用于生成基于变量的计算表达式的实用程序。
- 通过 CSSType 实现类型安全样式。
- ?♂? 用于开发和测试的可选运行时版本。
- 用于动态运行时主题的可选 API。
// styles.css.ts
import { createTheme, style } from '@vanilla-extract/css';
export const [themeClass, vars] = createTheme({
color: {
brand: 'blue',
},
font: {
body: 'arial',
},
});
export const exampleStyle = style({
backgroundColor: vars.color.brand,
fontFamily: vars.font.body,
color: 'white',
padding: 10,
});
vanilla-extract 的缺点包括:
- 未积极维护:存在大量未解决的问题和 pull 请求,其中一些已经存在一年多了。
Treat
Treat 是可主题化、静态提取的 CSS-in-JS,运行时间接近于零。使用 Treat 时,样式在 .treat.js 或 .treat.ts 文件中声明。 Treat 执行 .treat.js 文件并在构建时生成所有 CSS 规则,仅打包生成的 CSS 样式。
如果使用主题功能,Treat 会在构建时生成所有 CSS 样式。 然后,当切换主题时,它会在运行时交换预先生成的类。
Treat 的特征可以总结为以下几点:
- Treat 在构建时执行的处理文件(例如 Button.treat.js)中用 JavaScript/TypeScript 编写样式。
- 所有 CSS 规则都是提前创建的,因此运行时非常轻量,只需要交换预先存在的类。 事实上,如果应用程序不使用主题,甚至根本不需要运行时。
- 所有 CSS 逻辑(包括其依赖项)都不会包含在最终 Bundle 中。
- 由于主题是通过生成多个类来实现的,因此支持旧版浏览器。
import { style } from 'treat';
export const buttonStyle = style({
backgroundColor: '#1e4db6',
color: '#fff',
padding: '10px 20px',
borderRadius: '5px',
border: 'none',
});
然后,可以将声明的样式导入到组件中,如下例所示。
import React from 'react';
import { buttonStyle } from './Button.treat';
export const Button = () => {
return <button className={buttonStyle}>Click me</button>;
};
Treat 的缺点包括:
- Treat 需要 webpack,这可能很难设置
- 缺少对前端框架的有限开箱即用支持
Goober
Goober 是一个流行的、轻量级的、零依赖包。 虽然它不是严格意义上的零运行时 CSS-in-JS 解决方案,但其内置的 extractCss 函数允许开发者提取静态 CSS 文件并将它们注入到 <head> 标记中,就像在零运行时 CSS-in- 中一样。
使用 Goober 的优点包括:
- 捆绑包大小:Goober 是轻量级的(约 1kb)
- 框架支持:Goober 与框架无关
该 API 的灵感来自于 emotion 的 styled 函数。意思是,您使用 tagName 调用它,它会返回该标签的 vDOM 组件。请注意,需要在使用样式函数之前运行安装程序。
import { h } from 'preact';
import { styled, setup } from 'goober';
// Should be called here, and just once
setup(h);
const Icon = styled('span')`
display: flex;
flex: 1;
color: red;
`;
const Button = styled('button')`
background: dodgerblue;
color: white;
border: ${Math.random()}px solid white;
&:focus,
&:hover {
padding: 1em;
}
.otherClass {
margin: 0;
}
${Icon} {
color: black;
}
`;
Goober 的缺点包括:
- 从技术上讲不是零运行时 CSS-in-JS 设置:它需要 Babel 或 webpack,这可能很难设置
- 对其他捆绑器的支持:Goober 没有对某些捆绑器进行开箱即用的集成
参考资料
https://github.com/callstack/linaria
https://blog.logrocket.com/comparing-top-zero-runtime-css-js-libraries/
https://github.com/astroturfcss/astroturf
https://github.com/yandex/reshadow
https://github.com/vanilla-extract-css/vanilla-extract
https://github.com/seek-oss/treat
https://github.com/cristianbote/goober
https://medium.com/@arnabroyy/21-best-javascript-and-css-library-in-2023-for-web-development-e6e6af939a1e
相关推荐
- 5分钟调色大片的方法(5分钟调色大片的方法有哪些)
-
哈喽大家好。在大家印象中一定觉得ps非常难学非常难。大家不要着急,小编的教学都是针对ps零基础的同学的,而且非常实用哦。只要大家跟着图文练习一两遍,保证大家立马学会~!好了,废话少说,下面开始我们今天...
- 闪白特效原来是这么用的(闪白特效怎么使用)
-
作者|高艳侠订阅|010-86092062闪白特效是影视作品中应用比较多的效果之一,那么具体该在哪些场景使用闪白特效?具体该如何操作?下面就以AdobePremiere(以下简称PR)为例,...
- ppt常用小图标去哪里找?3个矢量素材网站推荐!
-
ppt是一个注重可视化表达的演示载体,除了高清图片,ppt中另一类常用的素材是各种小图标,也叫矢量图标,巧妙运用小图标能提升整体美观度和表现力,那么ppt常用小图标去哪里找呢?为方便各位快速找到合适的...
- 有什么好用的截图录屏工具?试试这9款
-
经常有朋友反馈苦于缺乏截屏和录屏的趁手工具,本期我们分享几个相当好用的截屏和录屏工具,希望能帮到大家。ScreenToGifScreenToGif是一款免费且开源的录屏工具。此款工具最大的特点是可以...
- 配色苦手福音!专业快速色环配色PS插件
-
今天橘子老师给的大家介绍的是一款快速配色的插件,非常强大配色苦手福音来啦!(获取方式见文末)【插件介绍】配色在后期设计中占有主导地位,好的配色能让作品更加抢眼Coolorus这款专业的配色插件,能够...
- 如何用PS抠主体?(ps怎么抠主体)
-
1.主体法抠图-抠花苞和花梗导入一张荷花苞的照片,点击上图中顶部“选择”菜单栏,下拉单击“主体”。可以看到,只有花苞被选中,但是花梗并没有被选中。接下来单击上图中左侧工具栏的“快速选择工具”,上图中顶...
- 2799元的4K电视,有保障吗?(买4k电视机哪个品牌好)
-
在上一期《电脑报》的3·15专题报道中,我们揭露了一款不靠谱的42英寸4K智能电视——TCLD42A561U。这款售价2699元的4K智能电视不仅4K画质方面存在严重问题,而且各种功能和应用体验也不理...
- 苹果电脑的Touch Bar推出一段时间了 这款工具可以帮你开发适用于它的APP
-
距离苹果推出带有TouchBar的MacBookPro已经有一段时间了,除了那些像Adobe、Google和Microsoft大公司在开发适用于TouchBar的应用之外,其实还有很多独立的开...
- 如魔法般吸取颜色的桌灯(如魔法般吸取颜色的桌灯叫什么)
-
色彩为生活带来的感官刺激,逐渐被视为理所当然。一盏桌灯运用它的神奇力量,将隐藏于物件中的颜色逐一释放,成为装点环境的空间魔法师。ColorUp是一款可以改变颜色的吸色台灯,沿用传统灯泡的造型,融入了拾...
- 一篇文章带你用jquery mobile设计颜色拾取器
-
【一、项目背景】现实生活中,我们经常会遇到配色的问题,这个时候去百度一下RGB表。而RGB表只提供相对于的颜色的RGB值而没有可以验证的模块。我们可以通过jquerymobile去设计颜色的拾取器...
- ps拾色器快捷键是什么?(ps2019拾色器快捷键)
-
ps拾色器快捷键是什么?文章末尾有获取方式,按照以下步骤就能自动获得!学会制作PS特效需要一定程度的耐心和毅力。初学者可以从基本的工具和技术开始学习,逐渐提高他们的技能水平。同时,观看更多优秀的特效作...
- 免费开源的 Windows 截图录屏工具,支持 OCR 识别和滚动截图等
-
功能很强大、安装很小巧的免费截图、录屏工具,提供很多使用的工具来帮我么能解决问题,推荐给大家。关于ShareXShareX是一款免费的windows工具,起初是一个小巧的截图工具,经过多年的迭...
- 入门到精通系列PS教程:第13篇 · 拾色器、颜色问题说明及补充
-
入门到精通系列PS教程:第13篇·拾色器、颜色问题说明及补充作者|侯潇问题说明我的第12篇教程里,有个小问题没有说清楚。要说是错误,又不算是错误,只是没有说准确。写完那篇教程后,因为已经到了深...
- PS冷知识:用吸管工具吸取屏幕上的任意颜色
-
今天,我们给大家介绍PS中的一个冷知识:用吸管工具可以吸取屏幕上的任意颜色。其实,操作起来是非常简单的。大多数情况下,我们认为,PS的吸管工具只能吸取PS软件作图区域范围内的颜色,最多加上画布四周的...
- Windows 11 将提供内置颜色选择器工具
-
Windows11内置了颜色选择器,可以扫描并识别屏幕上的颜色并生成颜色代码。此外,微软还利用人工智能技术,让屏幕上的文本扫描和选择变得更加便捷。这两项功能均已在SnippingToolv1...
- 一周热门
- 最近发表
- 标签列表
-
- mybatiscollection (79)
- mqtt服务器 (88)
- keyerror (78)
- c#map (65)
- xftp6 (83)
- bt搜索 (75)
- c#var (76)
- xcode-select (66)
- mysql授权 (74)
- 下载测试 (70)
- linuxlink (65)
- pythonwget (67)
- androidinclude (65)
- libcrypto.so (74)
- linux安装minio (74)
- ubuntuunzip (67)
- vscode使用技巧 (83)
- secure-file-priv (67)
- vue阻止冒泡 (67)
- jquery跨域 (68)
- php写入文件 (73)
- kafkatools (66)
- mysql导出数据库 (66)
- jquery鼠标移入移出 (71)
- 取小数点后两位的函数 (73)