css-in-js不能在纯html中使用,因其依赖js运行时、模块系统及特定库(如styled-components或@emotion/react),需经打包器处理模板字符串,并挂载到react等框架渲染流程中。

纯 HTML 文件里写 styled.button 或 css`...` 是无效的,根本不会生效——CSS-in-JS 不是 HTML 原生能力,它依赖 JS 运行时、模块系统和特定库共同协作。
为什么不能在 HTML 中直接用 CSS-in-JS
你把 styled.div 写进 <script></script> 标签里,浏览器会报 ReferenceError: styled is not defined。这不是语法写错了,而是缺少三样东西:
- 没引入
styled-components或@emotion/react这类库(仅靠<script src="..."></script>加载 CDN 版也不够,还缺 React 和 JSX 支持) - 没经过打包器(如 Vite/Webpack)处理 tagged template literals,
`background: ${color};`这种模板字符串在原生 JS 环境下只是普通字符串,不会被解析成样式规则 - 没挂载到 React/Vue 等框架的渲染流程中,CSS-in-JS 的样式注入逻辑(比如创建
<style></style>标签、生成唯一 class 名、绑定 props)全部发生在组件 render 阶段
大规模组件化项目里怎么组织 CSS-in-JS 结构
结构混乱是团队协作中最常见的性能与维护隐患。实际项目中,关键不是“能不能写”,而是“在哪写、怎么拆、谁负责”。常见有效做法:
- 每个组件文件内聚:React 组件 + 对应的
styled组件定义写在同一文件(如Button.jsx),避免跨文件跳转查样式 - 提取可复用样式逻辑到独立 hook 或工具函数,而不是到处复制
css`...`块;例如主题色计算统一走useThemeColor(),不散落在各处color: ${props => props.theme.primary} - 禁止在
index.js或布局组件里集中定义所有样式——这会快速演变成全局样式表,失去 CSS-in-JS 的局部作用域价值 - 按功能而非视觉拆分样式块:比如
inputBase、inputError、inputDisabled分开定义,而不是堆在一个InputStyled里用大量三元判断
styled-components 和 emotion 在结构实践上的关键差异
二者 API 相似,但结构约束和默认行为不同,直接影响大规模项目的可维护性:
-
styled-components强制要求使用组件名作为最终 class 前缀(如sc-a1b2c3),且不支持构建时提取 CSS 文件——这意味着 SSR 场景下必须搭配StyleSheetManager手动接管 style 注入,否则首屏无样式 -
@emotion/react默认启用css函数 +className注入,支持babel-plugin-emotion提前编译、自动提取静态样式到 CSS 文件,更适合需要 SEO 或强性能要求的项目 - emotion 的
Global组件适合收口全局重置样式(如normalize.css),而 styled-components 要求你手动 import 并用createGlobalStyle,多一层封装 - 两者都支持插件扩展,但 emotion 对 TypeScript 的 props 类型推导更稳定,尤其在嵌套泛型组件(如
asChild模式)下不易丢类型
真正容易被忽略的是:CSS-in-JS 的“结构”不是写法问题,而是模块边界意识。一个按钮组件如果同时包含主题逻辑、尺寸计算、动画定义、响应式断点和伪类状态,那它迟早会变成难以测试和复用的巨石——拆分依据永远是“变化原因”,而不是“看起来像一类”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











