扫一扫分享
在 TypeScript(或 JavaScript)中使用本地范围的类名和 css 变量编写样式,然后在构建时生成静态 CSS 文件。基本上,它是“ CSS Modules -in-TypeScript”,但具有范围内的 CSS 变量和 更多堆。
在构建时生成的所有样式 - 就像Sass、Less等。
对标准 CSS 的最小抽象。
局部范围的类名——就像CSS 模块一样。
局部范围的CSS变量,@keyframes和@font-face规则。
支持同步主题的高级主题系统。没有全局变量!
用于生成基于变量的calc表达式的工具。
通过CSSType 的类型安全样式。
用于开发和测试的可选运行时版本。
用于动态运行时主题的可选 api。
webpack 环境下,需要同时安装 @vanilla-extract/css 与 @vanilla-extract/webpack-plugin 插件:
yarn add @vanilla-extract/css @vanilla-extract/webpack-plugin
安装完成后,修改 Webpack 配置:
const { VanillaExtractPlugin } = require('@vanilla-extract/webpack-plugin')
module.exports = {
entry: './src/index.js',
// ....
plugins: [new VanillaExtractPlugin()]
};
这里可以看见,当我们使用 vanilla-extract 时,需要安装两个库:
@vanilla-extract/css :开发核心库,基于该库进行项目业务样式开发;
@vanilla-extract/webpack-plugin
webpack
vanilla-extract
这里只会对 vanilla-extract 比较核心的构建样式相关几个API提及,其他 API 可以直接前往官网查看。
import { style } from '@vanilla-extract/css';
export const parentClass = style({
background: 'red',
':hover': {
background: 'blue',
},
});
export const childClass = style({
selectors: {
'&:nth-child(2n)': {
background: '#fafafa',
},
[`${parentClass} &`]: {
color: 'pink',
},
},
});
import { childClass, parentClass } from './index.styles.css';
const Demo = () => (
<div className={parentClass}>
<div className={childClass}>DEMO1</div>
<div className={childClass}>DEMO2</div>
<div className={childClass}>DEMO3</div>
</div>
);
export default Demo;
这个简单的 demo 我相信,看几下就已经明白是怎么使用了。但是需要理解的地方是,为了提高可维护性, 「每个样式块只能针对某个元素(或者说是使用这个样式块的元素)」 。那么在上述代码里的 selectors 而言, 「其目标必须是」 ** & **(也就是自身元素)而不能是其他元素。例如: ${parentClass} &` 是OK的,但是 & div` 是不允许的。这样的设计,我觉得更是一种职责分离吧,每个样式块都针对某个元素,那么对于项目而言,样式的可维护性就大大提高了,相比于其他 css in js (styled-components)就不容易出现样式冗余的问题。对于一些特殊情况,比如:在写 styled-components 我们会利用其包裹 arco 组件(或是其他组件),然后对其内部元素样式进行覆写或是新增。
const StyledSelect = styled(Select)`
div {
color: red;
}
`
那么在 vanilla-extract 样式块里是不能直接做到的,因为每个样式块都是针对某个元素,是不能直接通过该样式块,直接对其兄弟元素、子元素进行样式调整。但是,对于这种情况,是可以使用另一个API globalStyle 进行开发。
顾名思义,就是全局样式API。但是因为本身 vanilla-extract 走 css module ,每个className都是独一无二,那么通过 globalStyle 来对其子元素进行样式调整覆盖完全是可行的。
import { style, globalStyle } from '@vanilla-extract/css';
export const parentClass = style({});
globalStyle(`${parentClass} > div`, {
color: 'red'
});
const Demo = () => (
<div className={parentClass}>
<Select/>
</div>
)
零运行时;
样式开发走Typescript安全类型;
style设计职责分离;(当然,styled-components也是可以的,只是完全取决于看开发者)
手机预览