内连样式
<div style="color: brown">
sdfasdfasdfasdfs
<div style="color: aqua">apppppppp</div>
</div>
内连样式 (内连样式优先级高)
- 优先级层级:!important > 行内样式 > ID > 类/属性/伪类 > 元素/伪元素 > 通用选择器。
- 内连样式只能写 简单的css。 伪元素(
::before/::after)、媒体查询、hover/focus 等高级写法用不了
css文件单独写,不做任何处理(模块化处理) (那么这些css文件就是全局的css文件)(编译时)
全局的css文件,在项目里容器 类名冲突,导致样式覆盖。
css 全称:层叠样式表,全局css文件中,如果有两个相同的类名,后加载的css文件中的样式会覆盖前面相同类名的样式
css文件模块化
react项目里
CSS Modules(最常用)Webpack 构建时自动给 class 名加哈希后缀,从而实现局部作用域。
- 文件命名:
Button.module.css
- CSS 内容:
.button {
background-color: blue;
color: white;
padding: 8px 16px;
border-radius: 4px;
}
- 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>
发生了什么?
- styled-components 会为 StyledButton 组件生成一个唯一的、随机的 className(例如 sc-a1b2c3d4)。
- 它会将你写的 CSS 代码与这个唯一的 className 关联,并生成一个 标签插入到 HTML 的 中。
- 当你使用 时,styled-components 会检测到 primary 这个 prop,然后根据你定义的函数逻辑,动态计算出正确的 background 和 color 值,并应用到对应的 CSS 规则上
css in js 的优点
-
自动作用域隔离 (Scoped Styles)
- 核心优势。 每个组件的样式都有唯一的类名,彻底解决了全局 CSS 命名冲突的问题。你再也不用担心修改一个组件的样式会意外影响到另一个组件。
-
组件化和高内聚性
- 一个组件的所有逻辑、结构和样式都在同一个文件里。这使得组件更加独立、可移植和易于维护。当你阅读或修改一个组件时,所有相关代码都在一起。
-
动态样式变得极其简单
- 可以直接在样式代码中访问组件的 props 和 state,用 JavaScript 逻辑来控制样式,比传统的手动切换 className 优雅得多。
-
无死代码 (Dead Code Elimination)
- 样式是和组件绑定的。如果你删除了一个组件,它的样式也随之被删除。在大型项目中,这可以有效防止 CSS 文件因长期迭代而变得臃肿不堪。
-
利用 JavaScript 的生态系统
- 你可以在样式中使用 JavaScript 变量、函数、逻辑运算等。可以轻松创建主题(Theming)、混入(Mixins)等高级功能。
-
自动添加浏览器前缀 (Vendor Prefixing)
- 大多数 CSS-in-JS 库会自动处理 -webkit-、-moz- 等浏览器兼容性前缀,开发者无需关心。
缺点 (Cons)
-
性能开销 (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 文件,从而消除了运行时开销,是目前的一个发展趋势。
-
学习曲线
- 需要学习一个新的库的 API 和范式,而不是直接写标准的 CSS。
-
工具链和生态系统
- 虽然已经很成熟,但有时代码编辑器的语法高亮、自动补全、CSS Linter 等工具的支持不如原生 .css 或 .scss 文件那么完美。
- 在浏览器开发者工具中调试时,看到的会是随机生成的类名(如 _a1b2c3d4),而不是有意义的名称,这给调试带来了一些不便(尽管可以通过 source maps 和库提供的 babel 插件来改善)。