一. CSS 发展
在书写 css 的时候经历了以下阶段:
- 手写源生 CSS
- 使用预处理器 Sass/Less
- 使用后处理器 PostCSS
- 使用 css modules
- 使用 css in js
<1> 手写原生 CSS
-
行内样式,即直接在 html 中的 style 属性里编写 css 代码。
-
内嵌样式,即在 html 中的 style 标签内编写 class,提供给当前页面使用。
-
导入样式,即在内联样式中 通过 @import 方法,导入其他样式,提供给当前页面使用。
-
外部样式,即使用 html 中的 link 标签,加载样式,提供给当前页面使用。
大多采用
内嵌样式
和外部样式
!!
行内样式的缺点:
- 权重较高,不利于覆盖修改
- 样式不能复用
- 不能进行缓存
导入样式@import的缺点:
- 会出现页面没有样式的情况:@import 声明指向的样式表并不会与页面其他资源并发加载,而是等页面所有资源加载完成后才开始下载。
<2> 使用预处理器 SCSS / Less
原生的 css 不支持变量,不支持嵌套,不支持父选择器等等,这些种种问题,催生出了像 sass/less 这样的预处理器。预处理器主要是强化了 css 的语法,弥补了上文说了这些问题,但本质上,打包出来的结果和原生的 css 都是一样的,只是对开发者友好,写起来更顺滑。
<3> 后处理器 PostCSS
postcss
可以称作为 css 界的 babel,它的实现原理是通过 ast 去分析我们的 css 代码,然后将分析的结果进行处理,从而衍生出了许多种处理 css 的使用场景。
使用场景有:
- 配合 stylelint 校验 css 语法
- 自动增加浏览器前缀 autoprefixer
- 编译 css next 的语法
<4> CSS 模块化
(1) CSS模块化解决的问题:**
- 不用考虑为元素的 class 命名重复问题
- 不用考虑层级结构问题
- common.css 过于庞大
(2) CSS 模块化的实现方式
-
采用 BEM 进行规范命名(通过起不冲突名、有层次结构的名解决)
-
CSS Modules
- CSS Modules 指的是我们像 import js 一样去引入我们的 css 代码,代码中的每一个类名都是引入对象的一个属性,通过这种方式,即可在使用时明确指定所引用的 css 样式。 - CSS Modules 在打包的时候会自动将类名转换成 hash 值,完全杜绝 css 类名冲突的问题 - `index.module.css` - import styles from './index.module.css' - <div class={styles.box}> - CSS Modules 不能直接使用,而是需要进行打包,一般通过配置 css-loader 中的 modules 属性即可完成 css modules 的配置。
-
CSS in JS
- 意思就是使用 js 语言写 css,完全不需要些单独的 css 文件,所有的 css 代码全部放在组件内部,以实现 css 的模块化。最出名的是 styled-components。
使用举例:
// 通过属性动态定义样式 const Button = styled.button`
background: ${props => (props.primary ? "palevioletred" : "white")};
color: ${props => (props.primary ? "white" : "palevioletred")};
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border: 2px solid palevioletred;
border-radius: 3px;
`;
// 样式复用
const TomatoButton = styled(Button)`
color: tomato; border-color: tomato;
`;