css 工具中的 CSS-in-JS_如何在 JavaScript 中书写 CSS

发布时间 - 2026-01-12 00:00:00    点击率:
CSS-in-JS 是用 JavaScript 函数或对象生成作用域隔离的 CSS 规则,非字符串拼接,而是通过库编译为带哈希的 class 名并注入 style 标签。

什么是 CSS-in-JS,它真在 JS 里写 CSS 吗

是的,但不是字符串拼接那种“写”。CSS-in-JS 是一种将样式逻辑与组件逻辑耦合的技术模式,核心是用 JavaScript 函数或对象生成可复用、作用域隔离的 CSS 规则。它不等于 element.style 内联样式,也不等于把 CSS 当字符串塞进 document.createElement('style')——而是通过库(如 styled-components@emotion/react)把样式定义编译成真实 class 名,并注入 标签。

用 styled-components 写一个带 props 的按钮组件

这是最典型的入门场景:需要根据 variantdisabled 动态切换样式。关键在于模板字符串里的插值语法和自动哈希类名机制。

import styled from 'styled-components';

const Button = styled.button` padding: 8px 16px; border: none; border-radius: 4px; background-color: ${props => props.variant === 'primary' ? '#007bff' : '#6c757d'}; color: white; cursor: ${props => props.disabled ? 'not-allowed' : 'pointer'};

&:hover:not(:disabled) { opacity: 0.9; } `;

// 使用

  • 插值必须用 ${...},且内部只能是函数(接收 props)或简单表达式;直接写字符串如 ${'red'} 会失效
  • 伪类、媒体查询可直接写,无需额外 API;但 :disabled 这类状态需配合 props 判断,因为 DOM 状态不会自动同步到样式函数
  • 生成的 class 名类似 sc-bdVaJa kJjQqA,确保样式不污染全局

@emotion/react 的 css prop 和 css 函数区别

两种主流写法,适用不同粒度:前者适合单个元素快速覆盖,后者适合提取可复用样式对象。

/** 方式一:css prop(需开启 babel 插件 @emotion/babel-plugin) */
import { jsx } from '@emotion/react';
/** @jsxImportSource @emotion/react */

color: blue; font-weight: bold; @media (min-width: 768px) { font-size: 18px; } } />

/* 方式二:css 函数 + className / import { css } from '@emotion/react';

const headingStyle = css margin: 0; line-height: 1.2; ;

标题

  • css 函数返回的是一个唯一 hash 字符串(如 css-1a2b3c),不是对象,不能直接当对象用
  • css prop 写法更紧凑,但要求 JSX 编译支持;若用 TypeScript,需补充 declare module '@emotion/react' 声明
  • 两种方式都支持主题变量:props => ({ colors }) => css`color: ${colors.text};`

为什么不能直接在 JS 里用对象写标准 CSS?

因为 CSS 属性名和 JS 对象键名规则冲突:比如 font-size 不能作属性名,background-image 需转为 backgroundImage;同时,纯对象无法表达嵌套(&)、伪类、媒体查询等 CSS 特性。

  • { 'font-size': '14px' } 这种写法只适用于 Object.assign(element.style, ...),属于内联样式,不支持选择器、伪类、优先级控制
  • 所有成熟 CSS-in-JS 库都在底层做了驼峰转换、自动加前缀、SSR 支持、服务端渲染时样式提取等——这些不是靠手写对象能解决的
  • 如果你只是想动态改几个样式,useState + style 属性已足够;只有需要组件级封装、主题、响应式、条件样式时,才值得引入 CSS-in-JS

CSS-in-JS 的真正门槛不在语法,而在理解「样式即函数」:它依赖运行时求值,意味着每次 props 变化都可能触发样式重新计算,过度嵌套插值或在 render 中创建新样式函数,容易引发性能问题。


# css  # react  # javascript  # java  # js  # typescript  # 工具  # qq  # 区别  # 作用域  # 为什么  # red 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 北京网站制作的公司有哪些,北京白云观官方网站?  Laravel如何实现多表关联模型定义_Laravel多对多关系及中间表数据存取【方法】  利用vue写todolist单页应用  阿里云高弹*务器配置方案|支持分布式架构与多节点部署  如何快速选择适合个人网站的云服务器配置?  Android自定义listview布局实现上拉加载下拉刷新功能  Linux网络带宽限制_tc配置实践解析【教程】  Laravel如何使用Eloquent进行子查询  Laravel如何处理异常和错误?(Handler示例)  小视频制作网站有哪些,有什么看国内小视频的网站,求推荐?  悟空识字如何进行跟读录音_悟空识字开启麦克风权限与录音  如何基于云服务器快速搭建网站及云盘系统?  在centOS 7安装mysql 5.7的详细教程  Laravel怎么连接多个数据库_Laravel多数据库连接配置  EditPlus 正则表达式 实战(3)  网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?  Win11怎么关闭专注助手 Win11关闭免打扰模式设置【操作】  Linux虚拟化技术教程_KVMQEMU虚拟机安装与调优  音乐网站服务器如何优化API响应速度?  Laravel如何使用Vite进行前端资源打包?(配置示例)  香港服务器网站卡顿?如何解决网络延迟与负载问题?  如何使用 Go 正则表达式精准提取括号内首个纯字母标识符(忽略数字与嵌套)  javascript事件捕获机制【深入分析IE和DOM中的事件模型】  html5源代码发行怎么设置权限_访问权限控制方法与实践【指南】  网站优化排名时,需要考虑哪些问题呢?  *服务器网站为何频现安全漏洞?  Java解压缩zip - 解压缩多个文件或文件夹实例  Laravel Eloquent性能优化技巧_Laravel N+1查询问题解决  如何用好域名打造高点击率的自主建站?  Laravel中的Facade(门面)到底是什么原理  如何实现javascript表单验证_正则表达式有哪些实用技巧  JavaScript常见的五种数组去重的方式  Laravel如何实现数据导出到CSV文件_Laravel原生流式输出大数据量CSV【方案】  Bootstrap CSS布局之列表  如何正确下载安装西数主机建站助手?  Android滚轮选择时间控件使用详解  Laravel怎么处理异常_Laravel自定义异常处理与错误页面教程  详解MySQL数据库的安装与密码配置  详解Huffman编码算法之Java实现  车管所网站制作流程,交警当场开简易程序处罚决定书,在交警网站查询不到怎么办?  laravel怎么为API路由添加签名中间件保护_laravel API路由签名中间件保护方法  新三国志曹操传主线渭水交兵攻略  Laravel观察者模式如何使用_Laravel Model Observer配置  装修招标网站设计制作流程,装修招标流程?  想要更高端的建设网站,这些原则一定要坚持!  php打包exe后无法访问网络共享_共享权限设置方法【教程】  免费网站制作appp,免费制作app哪个平台好?  Laravel Vite是做什么的_Laravel前端资源打包工具Vite配置与使用  HTML透明颜色代码怎么让下拉菜单透明_下拉菜单透明背景指南【技巧】  如何快速启动建站代理加盟业务?