CSS-in-JS 是一种将 CSS 样式与 JavaScript 代码结合的方法,它允许开发人员在 JavaScript 组件中编写和管理 CSS 样式。这种方法在许多现代前端框架和库(如 React、Vue 和 Angular)中变得越来越流行,因为它提供了一种组件化的方式来处理样式。
CSS-in-JS 的主要优点包括:
1、组件化:将样式与组件绑定在一起,使得组件更易于维护和重用。
2、动态样式:可以根据组件的状态和属性轻松地更改样式。
3、作用域样式:避免全局样式冲突,因为每个组件的样式都是局部的。
4、代码共享:可以在 JavaScript 和 CSS 之间共享变量和逻辑。
有许多流行的 CSS-in-JS 库,如 styled-components、emotion 和 JSS。这些库提供了创建和管理组件样式的工具和方法。虽然 CSS-in-JS 有很多优点,但它也有一些缺点,如性能问题(尤其是在服务器端渲染应用程序中)和学习曲线。因此,在选择是否使用 CSS-in-JS 时,需要权衡其优缺点。
Styled-components 应该是 CSS-in-JS 最热门的一个库了,到目前为止 github 的 star 数已经超过了27k。通过 styled-components,你可以使用 ES6 的标签模板字符串语法为需要 styled 的 Component 定义一系列 CSS 属性,当该组件的 JS 代码被解析执行的时候,styled-components 会动态生成一个 CSS 选择器,并把对应的 CSS 样式通过 style 标签的形式插入到 head 标签里面。动态生成的 CSS 选择器会有一小段哈希值来保证全局唯一性来避免样式发生冲突。
CSS-in-JS Playground 是一个可以快速尝试不同 CSS-in-JS 实现的网站,上面有一个简单的用 styled-components 实现表单的例子:
import React from 'react';
import styled from 'styled-components';
import Form from './form';
import Header from './header';
const Container = styled.main`
display: flex;
flex-direction: column;
min-height: 100%;
width: 100%;
background-color: #f6f9fc;
`;
const Stripe = styled.div`
height: 10vh;
overflow: hidden;
transform: skewY(-8deg);
transform-origin: 0;
background: linear-gradient(-150deg, rgba(255, 255, 255, 0) 40%, #ddecf7 70%);
`;
export default function Login() {
return (
<Container>
<Header />
<Stripe />
<Form fields={['email', 'phoneNumber']} />
</Container>
);
}
从上面的例子可以看出,styled-components 不需要你为需要设置样式的 DOM 节点设置一个样式名,使用完标签模板字符串定义后你会得到一个 styled 好的 Component,直接在 JSX 中使用这个 Component 就可以了。接着让我们打开 DevTools 查看一下生成的 CSS:
从上面 DevTools 可以看出 styled 的 Component 样式存在于 style 标签内,而且选择器名字是一串随机的哈希字符串,这样其实实现了局部 CSS 作用域的效果(scoping styles),各个组件的样式不会发生冲突。除了styled-components,采用唯一 CSS 选择器做法的实现还有:jss,emotion,glamorous 等。
“CSS-in-JS” 是指一种模式,其中 CSS 由 JavaScript 生成而不是在外部文件中定义。
注意此功能并不是 React 的一部分,而是由第三方库提供。React 对样式如何定义并没有明确态度;如果存在疑惑,比较好的方式是和平时一样,在一个单独的 *.css 文件定义你的样式,并且通过 className 指定它们。