原生CSS的问题
-
开发体验欠佳, 比如原生 CSS 不支持选择器的嵌套
// 选择器只能平铺,不能嵌套 .container .header .nav .title .text { color: blue; } .container .header .nav .box { color: blue; border: 1px solid grey; }
-
样式污染问题, 如果出现同样的类名,很容易造成不同的样式互相覆盖和污染
// a.css .container { color: red; } // b.css // 很有可能覆盖 a.css 的样式! .container { color: blue; }
-
浏览器兼容问题
- 为了兼容不同的浏览器,我们需要对一些属性(如 transition )加
上不同的浏览器前缀,比如 -webkit- 、 -moz- 、 -ms- 、 -o- ,意味着开发者要针对同一个样式属性写很多的冗余代码 - 打包后的代码体积问题。如果不用任何的 CSS 工程化方案,所有的 CSS 代码都将打包到产物中,即使有部分样式并没有在代码中使用,导致产物体积过大
- 为了兼容不同的浏览器,我们需要对一些属性(如 transition )加
常用的5种CSS解决方案
1 ) CSS 预处理器
- 主流的包括 Sass/Scss 、 Less 和 Stylus, 这些方案各自定义了一套语法,让 CSS 也能使用嵌套规则
- 甚至能像编程语言一样定义变量、写条件判断和循环语句,大大增强了样式语言的灵活性,解决原生 CSS 的开发体验问题
2 ) CSS Modules
- 能将 CSS 类名处理成哈希值,这样就可以避免同名的情况下样式污染的问题
3 )CSS 后处理器 PostCSS
- 用来解析和处理 CSS 代码,可以实现的功能非常丰富,比如将 px 转换为 rem 、根据目标浏览器情况自动加上类似于 --moz-- 、 -o- 的属性前缀等等
4 )CSS in JS 方案
- 主流的包括 emotion 、 styled-components 等等,顾名思义,这类方案可以实现直接在 JS 中写样式代码,基本包含 CSS 预处理器 和 CSS
Modules 的各项优点,非常灵活,解决了开发体验和全局样式污染的问题
5 )CSS 原子化框架
- 如 Tailwind CSS 、 Windi CSS ,通过类名来指定样式,大大简化
了样式写法,提高了样式开发的效率,主要解决了原生 CSS 开发体验的问题
稍作总结
- 各种方案没有孰优孰劣,各自解决的方案有重叠的部分,但也有一定的差异,大家可以根据自己项目的痛点来引入
CSS 预处理器
-
Vite 本身对 CSS 各种预处理器语言( Sass/Scss 、 Less 和 Stylus )做了内置支持。也就是说,即使你不经过任何的配置也可以直接使用各种 CSS 预处理器。我们以 Sass/Scss 为例,来具体感受一下 Vite 的 零配置 给我们带来的便利
-
由于 Vite 底层会调用 CSS 预处理器的官方库进行编译,而 Vite 为了实现按需加载,并没有内置这些工具库,而是让用户根据需要安装。因此,我们首先安装 Sass 的官方库,安装命令如下: $
pnpm i sass -D
-
然后,在上一节初始化后的项目中新建 src/components/Header 目录,并且分别新建 index.tsx 和 index.scss 文件,代码如下:
// index.tsx import './index.scss'; export function Header() { return <p className="header">This is Header</p> }; // index.scss .header { color: red; }
-
这样就完成了一个最简单的 demo 组件,接着我们在 App.tsx 应用这个组件:
import { Header } from "./components/Header"; function App() { return ( <div> <Header /> </div> ); } export default App;
-
现在你可以执行 pnpm run dev ,然后到浏览器上查看效果
-
内容比较简单,如果页面出现红色的文字部分,就说明 scss 文件中的样式已经成功生效
-
好,现在我们封装一个全局的主题色,新建 src/variable.scss 文件,内容如下:
// variable.scss $theme-color: red;
-
然后,我们在原来 Header 组件的样式中应用这个变量:
@import "../../variable"; .header { color: $theme-color; }
-
回到浏览器访问页面,可以看到样式依然生效。你可能会注意到,每次要使用 $themecolor 属性的时候我们都需要手动引入 variable.scss 文件,那有没有自动引入的方案呢?这就需要在 Vite 中进行一些自定义配置了,在配置文件中增加如下的内容: