css样式管理 解析

8 阅读5分钟

内连样式

    <div style="color: brown">
      sdfasdfasdfasdfs
      <div style="color: aqua">apppppppp</div>
    </div>

内连样式 (内连样式优先级高)

  1. 优先级层级:!important > 行内样式 > ID > 类/属性/伪类 > 元素/伪元素 > 通用选择器。
  2. 内连样式只能写 简单的css。 伪元素(::before/::after)、媒体查询、hover/focus 等高级写法用不了

css文件单独写,不做任何处理(模块化处理) (那么这些css文件就是全局的css文件)(编译时)

全局的css文件,在项目里容器 类名冲突,导致样式覆盖。

css 全称:层叠样式表全局css文件中,如果有两个相同的类名后加载的css文件中的样式会覆盖前面相同类名的样式

css文件模块化

react项目

CSS Modules(最常用)Webpack 构建时自动给 class 名加哈希后缀,从而实现局部作用域。

  1. 文件命名:
Button.module.css
  1. CSS 内容:
.button {
  background-color: blue;
  color: white;
  padding: 8px 16px;
  border-radius: 4px;
}
  1. React 组件引入:
import styles from './Button.module.css';

export default function Button() {
  return <button className={styles.button}>提交</button>;
}
  • styles.button 会被打包工具(Webpack/Vite)处理成 唯一类名,如 Button_button__3XK2A
  • 避免了全局冲突

优点

  • 自动生成局部唯一类名,避免冲突
  • 保留 CSS 功能:伪类、媒体查询、嵌套(如果使用 PostCSS)
  • 可以和传统 CSS 共存

css in js (运行时样式)

允许你使用 JavaScript 来编写 CSS 样式。你不再将样式写在单独的 .css 文件中,而是将它们直接定义在组件的 JavaScript 文件里。

它不仅仅是把 CSS 字符串写在 JS 变量里,而是一整套由库(如 Styled Components, Emotion)提供的解决方案,这些库会在运行时或构建时,将你的 JavaScript 样式对象或模板字符串解析成真正的 CSS,并以一种高效的方式注入到 DOM 中。

核心思想:  将样式的作用域(Scope)限定在单个组件内,避免全局样式污染,并利用 JavaScript 的能力来创建动态、可复用、可维护的样式。

import React from 'react';
import styled from 'styled-components'; // 导入 styled  下载styled-components

// 1. 创建一个带样式的组件
//    styled.button 表示创建一个 <button> 元素
//    `` (模板字符串) 内部写的就是纯粹的 CSS 代码
const StyledButton = styled.button`
  background: transparent;
  border-radius: 3px;
  border: 2px solid palevioletred;
  color: palevioletred;
  margin: 0.5em 1em;
  padding: 0.25em 1em;
  cursor: pointer;

  /* 2. 利用 props 实现动态样式 */
  /* 如果该组件有 primary 这个 prop,就应用下面的样式 */
  background: ${props => (props.primary ? 'palevioletred' : 'transparent')};
  color: ${props => (props.primary ? 'white' : 'palevioletred')};
`;

// 3. 直接使用这个新创建的组件
const Button = ({ primary, children }) => {
  return <StyledButton primary={primary}>{children}</StyledButton>;
};

export default Button;

使用时:

codeJsx

<div>
  <Button>普通按钮</Button>
  <Button primary>主要按钮</Button>
</div>

发生了什么?

  1. styled-components 会为 StyledButton 组件生成一个唯一的、随机的 className(例如 sc-a1b2c3d4)。
  2. 它会将你写的 CSS 代码与这个唯一的 className 关联,并生成一个  标签插入到 HTML 的  中。
  3. 当你使用  时,styled-components 会检测到 primary 这个 prop,然后根据你定义的函数逻辑,动态计算出正确的 background 和 color 值,并应用到对应的 CSS 规则上

css in js 的优点

  1. 自动作用域隔离 (Scoped Styles)

    • 核心优势。  每个组件的样式都有唯一的类名,彻底解决了全局 CSS 命名冲突的问题。你再也不用担心修改一个组件的样式会意外影响到另一个组件。
  2. 组件化和高内聚性

    • 一个组件的所有逻辑、结构和样式都在同一个文件里。这使得组件更加独立、可移植和易于维护。当你阅读或修改一个组件时,所有相关代码都在一起。
  3. 动态样式变得极其简单

    • 可以直接在样式代码中访问组件的 props 和 state,用 JavaScript 逻辑来控制样式,比传统的手动切换 className 优雅得多。
  4. 无死代码 (Dead Code Elimination)

    • 样式是和组件绑定的。如果你删除了一个组件,它的样式也随之被删除。在大型项目中,这可以有效防止 CSS 文件因长期迭代而变得臃肿不堪。
  5. 利用 JavaScript 的生态系统

    • 你可以在样式中使用 JavaScript 变量、函数、逻辑运算等。可以轻松创建主题(Theming)、混入(Mixins)等高级功能。
  6. 自动添加浏览器前缀 (Vendor Prefixing)

    • 大多数 CSS-in-JS 库会自动处理 -webkit-、-moz- 等浏览器兼容性前缀,开发者无需关心。

缺点 (Cons)

  1. 性能开销 (Performance Overhead)

    • 运行时开销:库需要在浏览器端运行时解析 JavaScript,生成 CSS,并将其注入 DOM。这会占用一些 CPU 时间,可能影响应用的初始加载和渲染性能(FCP, TTI)。
    • 包体积增大 (Bundle Size) :你需要将 CSS-in-JS 库本身打包到你的应用中,增加了用户需要下载的 JavaScript 文件大小。
    • 注意:现代 CSS-in-JS 库(如 Emotion, Styled Components)已经做了大量优化。此外,还出现了  "零运行时 (Zero-Runtime)"  的 CSS-in-JS 库(如 Linaria, vanilla-extract),它们在构建时就将样式提取成静态的 CSS 文件,从而消除了运行时开销,是目前的一个发展趋势。
  2. 学习曲线

    • 需要学习一个新的库的 API 和范式,而不是直接写标准的 CSS。
  3. 工具链和生态系统

    • 虽然已经很成熟,但有时代码编辑器的语法高亮、自动补全、CSS Linter 等工具的支持不如原生 .css 或 .scss 文件那么完美。
    • 在浏览器开发者工具中调试时,看到的会是随机生成的类名(如 _a1b2c3d4),而不是有意义的名称,这给调试带来了一些不便(尽管可以通过 source maps 和库提供的 babel 插件来改善)。