许多网络开发者在GitHub上寻找可以贡献的资源库。当他们找到一个令人兴奋的项目并开始贡献时,他们面临的一个共同挑战是找到某个特定组件的样式的定义位置,尤其是在一个较大的项目中。
幸运的是,有一个简单的解决方案:网络开发者应该在同一个文件中定义组件和样式。我们可以使用CSS-in-JS语法技术,在同一个文件中编写组件和样式,而不需要太复杂。
根据样式组件创建者Max Stoiber的说法,超过60%的React安装也安装了CSS-in-JS库。在JS中编写CSS是非常流行的,尤其是在使用React或Angular这样的JS框架时。有许多库可以简化你在JS中编写CSS的过程。
什么是CSS-in-JS?
那么,到底什么是CSS-in-JS?它是一种造型技术,即用JavaScript来对组件进行造型。我们使用变量来定义组件的CSS。变量将包含所有的CSS属性,而内容将被包裹在组件中,所以它也将拥有所有定义的CSS属性。
近来,随着基于组件的造型变得越来越流行,CSS-in-JS的使用也在增加。另外,大多数现代的JavaScript框架都是基于组件的,这也促进了CSS-in-JS的使用。由于这个原因,CSS现在已经成为JavaScript的一个模块,可以在必要时定义和使用。
在React这样的现代框架中,你可以使用内联技术,在.js文件的JSX部分编写CSS-in-JS。但这种技术会让人困惑,可读性较差,而且会破坏代码的流程。在通过库编写CSS-in-JS时,它不能取代CSS的模块化。
使用CSS-in-JS
当我们使用CSS-in-JS时,我们在一个变量中定义样式,我们可以通过将组件包裹在变量标签中来使用它们的样式。
styled 标签是从库中导入的。它创建了一个已经定义了一些样式的React组件。它的后面是你想使用它的HTML标签名称--在下面的例子中,我们使用h1 。h1 标签将根据定义的CSS属性进行定制。编码之后,我们再定义属性,像这样。
const Title = styled.h1`
font-family: sans-serif;
font-size: 48px;
color: #f15f79;
`;
接下来,我们把内容包在变量标签内。
const App = () => {
return(
<Title>
Hello world!
</Title>
)
;
Viola!这就是你在大多数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有几个缺点。其中有几个是。
- 因为样式是在
.js文件中定义的,如果JavaScript被禁用,它将影响组件的样式。 - 样式要经过两次解析,一次是由库解析,另一次是由浏览器在插入样式时解析。
- 传统上,当我们加载一个网页时,浏览器只是读取CSS并应用它。当使用CSS-in-JS时,浏览器会动态地生成一个CSS样式标签,然后读取并应用到网页上。读取和生成会花费性能时间
使用零运行时间的CSS-in-JS
改善因重复解析而损失的性能时间的解决方案之一是,库应首先将CSS-in-JS块转换为一个单独的.css文件。然后,浏览器会读取并将这些样式应用到网页上,最终节省通常在生成样式标签时浪费的运行时间。这被称为零运行时间的CSS-in-JS。它对性能至关重要的规模化或复杂的项目特别有用。
零运行时间意味着你用CSS-in-JS的语法编写你的样式,但产生的是CSS,就像任何其他预处理器所做的那样。
-CSS-Tricks
为了实现零运行时间的CSS-in-JS,你可以利用各种库。这里有一些流行的库可以考虑。
Linaria

Linaria是最流行的零运行时库,它是用TypeScript编写的。它有超过7.1K的GitHub星级和260个GitHub分叉。它是我个人最喜欢使用的,因为它有易于使用的语法,并且与几乎所有现代框架兼容。Linaria将CSS-in-JS转换为一个单独的.css文件,同时为生产创建构建。
它提供了许多功能,包括以下内容。
- 基于道具的动态样式:你可以使用道具来定义CSS属性的值
- CSS SourceMap:在大型项目中,可能很难找到组件的样式定义位置。如果在编写CSS时定义了CSS SourceMap,
true,它将在开发工具中显示生成的CSS的类名的来源 - 对CSS进行提示:stylelint将帮助你避免任何CSS错误,并在你的样式中强制执行约定。
- 逻辑的JavaScript:你可以在编写CSS时使用JavaScript逻辑。
下面是如何在你的机器上安装它。
npm install @linaria/core @linaria/react @linaria/babel-preset @linaria/shaker
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,这可能很难设置
- 插件支持。Linaria并没有为Rust提供高质量的插件支持
蝗蝗虫:Astroturf

Astroturf是由4Catalyzer开发的,在GitHub上有超过2000颗星。它是Linaria的一个很好的替代品。Astroturf通过保持CSS完全静态化,不进行运行时解析,帮助你实现零运行时。你可以通过Astroturf的范围样式表、React以及使用props和组件变体等多种方式来编写CSS-in-JS。你可以看到这里的实现。
主要特点包括。
- 灵活性:有些框架只适用于某些CSS处理,但Astroturf很灵活,与大多数框架兼容
- 支持道具:它支持React的道具功能,可以根据道具来设计组件的样式
- 使用你现有的工具:你可以使用Sass和PostCSS来编写JavaScript中的样式定义。
下面是如何开始的。
npm i astroturf
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的劣势
- 糟糕的文档:它在GitHub上缺乏一个合适的readme。它也缺乏贡献指南,而且文档很短,经常遗漏重要细节
- 实施:为了提取样式,Astroturf需要捆绑一个CSS解析器,如rollup或webpack,这可能很难实现。
阴影(Reshadow

Reshadow由Artur Kenzhaev开发,在GitHub上有340多颗星。它是用JavaScript编写的,提供了许多功能,如虚拟DOM-like React的shadow DOM开发者体验,其中之一是在JS中编写CSS。
Reshadow提供了以下好处。
- PostCSS的好处:你将拥有PostCSS的所有好处,可以自动进行常规的CSS操作
- 静态样式。Reshadow提供了一个静态样式提取选项,将你所有的CSS-in-JS提取到一个单一的.css文件中。
- CSS模块:你可以使用一个CSS模块来定义CSS,就像我们在JavaScript中一样
下面是安装方法。
npm install --save reshadow
import {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需要时间,而且可能很困难。
- 贡献者较少:Reshadow的贡献者非常少,这阻碍了解决附在GitHub仓库上的问题的进程。
结论
零运行时间的CSS-in-JS提供了许多好处,特别是当开发者为多个大型项目做出贡献时。CSS-in-JS的未来是相当光明的,尤其是当它涉及到Web开发和现代框架时。我希望你在启动你的下一个项目时能加入这些库中的一个。
The postComparing the top zero-runtime CSS-in-JS librariesappeared first onLogRocket Blog.