CSS(18) -- css样式隔离(模块化)

59 阅读3分钟

一. 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; 
`;

2088.awebp