🎨 CSS 演进史

一句话定性

CSS 本是为”给文档排版”而生的——它的设计假设是一篇有标题、段落、链接的静态文章。可历史把它推上了完全不同的战场:它被迫去承担应用级的复杂布局大型团队的工程化协作。CSS 三十年的演进史,本质上就是一个”文档语言”被反复改造、却又永远差一口气去做”应用语言”的挣扎史。


一、CSS 是什么 & 它诞生时的设计意图

1994 年,Håkon Wium Lie 在 CERN 提出 CSS 的构想;1996 年 W3C 发布 CSS1。它要解决的原始问题非常朴素:把”内容”和”样式”分开

在 CSS 之前,网页样式是靠 HTML 标签本身硬编码的(<font><center>tabletable)。结果是结构和表现死死纠缠,改个颜色要翻遍所有页面。CSS 的初心是一句极优雅的理念:

CSS 的原始世界观

HTML 负责”这是什么”(语义),CSS 负责”长什么样”(表现)。一篇文档的样式应该能被一张外部样式表统一描述、集中修改。

这个世界观对文档完美无缺。但它埋下了一个深远的前提假设:页面是一篇从上往下流动的文档(normal flow),而不是一个需要精确二维布局的应用界面。 这个假设,日后成了 CSS 一切痛苦的源头。


二、四个版本,一条暗线:从”排版文章”到”承载应用”

版本时间带来了什么暗含的时代压力
CSS11996字体、颜色、margin/padding、基础盒模型给静态文档上色
CSS2 / 2.11998 / 2011定位(position)、float、媒体类型、z-index网页开始想做”版式”,但没有真正的布局工具
CSS3(模块化)2011 起持续不再有”CSS3”这个整体版本,而是拆成几十个独立 模块:Flexbox、Grid、动画、过渡、媒体查询、box-sizing、自定义属性……移动互联网 + 响应式 + SPA,逼着 CSS 长出真正的布局能力
”CSS4”(并不存在)没有统一的 CSS4,标准化彻底转向逐模块独立演进:Container Queries、:has()、级联层 @layer、嵌套 &、子网格 Subgrid……应用化彻底定型,CSS 反过来”内化”了社区工具发明的能力

一个关键的认知:CSS3 之后再无"大版本"

CSS2.1 之后,W3C 放弃了”打包成一个大版本”的做法,改为每个特性作为独立模块各自演进、各自达到推荐标准。所谓”CSS3""CSS4”只是营销口径,工程上早已不存在。这种模块化标准化让 CSS 的进化从”十年一个大版本”变成”持续滚动交付”,是它能跟上前端爆炸式需求的制度性原因。

这条暗线可以一句话概括:CSS 的每一次重大进化,都不是它自己想进化,而是被时代的应用化浪潮逼出来的。 Flexbox 是被响应式逼的,Grid 是被复杂应用布局逼的,自定义属性是被组件化的主题需求逼的,Container Queries 是被组件复用逼的。


三、三大永恒痛点:理解 CSS 史的三把钥匙

CSS 三十年的所有故事,几乎都在围绕三个先天缺陷打转。理解了这三点,就理解了所有专题为什么存在。

痛点一:布局难(它从来不是为布局设计的)

CSS 最初根本没有布局系统。开发者要做一个”左侧导航 + 右侧内容”的两栏布局,只能去滥用本不该用于布局的工具:先是用 table(本意是数据表格),后是用 float(本意是文字绕图)。整整二十年,前端在用”歪招”做布局,直到 Flexbox(一维)和 Grid(二维)才给出专门为布局而生的工具。

这条主线太核心、太曲折,单独成篇 → 布局演进史

痛点二:无作用域(全局命名空间是原罪)

CSS 的选择器天生是全局的。任何一条 .title { color: red } 都会作用到全页面所有 .title。在一篇文档里这没问题,但在一个有几百个组件、几个团队协作的大型应用里,这是灾难:命名冲突、样式互相覆盖、specificity(优先级)战争、!important 滥用。

人类先用约定对抗它(命名规范、分层架构)→ CSS方法论; 后用工具消灭它(编译期生成唯一类名、把样式锁进组件)→ CSS-in-JS / 原子化CSS

痛点三:难复用(原生 CSS 没有抽象能力)

原生 CSS 长期没有变量、没有函数、没有 mixin、没有模块导入。一个品牌主色要在几百处重复写死,改一次主题要全局替换。开发者忍无可忍,在 CSS 之上发明了一整套预编译语言CSS预处理器;多年后,CSS 终于把变量(custom properties)等能力收编进原生标准

一个反复出现的模式:社区先发明,标准后收编

几乎每个痛点都遵循同一条路径:原生 CSS 缺能力 → 社区造工具/约定填补 → 工具验证了需求的真实性 → W3C 把它标准化进原生 CSS。预处理器的变量 → 原生 custom properties;预处理器的嵌套 → 原生 CSS Nesting;BEM 的分层意图 → 原生 @layer。CSS 的标准制定,某种意义上是在”追认社区的既成事实”。


四、整条因果链:CSS 工程化的全景

CSS 为文档而生(全局作用域 + 无布局 + 无复用)
        │
        ├──【布局线】table → float+clearfix → inline-block → Flexbox(2015)
        │            → Grid(2017)→ Container Queries(2023)→ Subgrid
        │            (从"滥用歪招"到"专为布局而生")          → [[布局演进史]]
        │
        ├──【作用域线】全局冲突 + specificity 战争
        │       │
        │       ├─ 用"约定"治理:OOCSS(2009)/ BEM / SMACSS / ITCSS  → [[CSS方法论]]
        │       │       └─(约定靠人自觉,规模一大就失守)
        │       │
        │       └─ 用"工具"消灭:
        │              CSS Modules(编译期局部作用域)
        │              → CSS-in-JS(把样式锁进组件)              → [[CSS-in-JS]]
        │              → 原子化 CSS(根本不命名,用 utility)      → [[原子化CSS]]
        │
        └──【复用线】无变量/嵌套/mixin
                └─ 预处理器 Sass(2006)/Less/Stylus 填补
                   → PostCSS 插件化成为基础设施
                   → 原生 custom properties 收编 → 预处理器降级为"可选" → [[CSS预处理器]]

        三条线在"组件化时代"汇流:样式必须与组件同生共死
        在"AI 时代"再次汇流:原子化 utility 最适合机器生成

五、当下格局:三条路线的并存与回摆

没有银弹,只有权衡

到 2026 年,CSS 工程化并没有收敛到唯一答案,而是形成了几条共存的路线,各自服务不同诉求:

路线代表解决的核心痛点当下处境
原生 + 现代 CSScustom properties、Grid、@layer:has()、Container Queries标准本身在补课越来越强,蚕食工具的存在理由
原子化Tailwind(2017)、UnoCSS无需命名 + 产物小 + 设计约束强势上升,尤其契合 AI 生成
零运行时 CSS-in-JSvanilla-extract、Linaria组件级作用域 + 类型安全,但无运行时开销运行时方案在 React RSC 冲击下向它回摆
运行时 CSS-in-JSstyled-components、Emotion动态样式 + 与 props 联动因 RSC 不兼容、性能开销而退潮

CSS 史的终极启示

CSS 的演进史,是一部”用错误的工具做对的事,然后慢慢造出对的工具”的历史。它告诉我们:当一项技术的实际用途远远超出其设计意图时,围绕它会长出一整片工具生态来弥补落差;而成熟的标准会缓慢地把这些社区智慧”收编”回自身。今天的 CSS,正在以前所未有的速度收编社区发明——这也意味着,许多曾经不可或缺的工具,正在变成”可选项”。


🔗 子专题:布局演进史 | CSS方法论 | CSS预处理器 | CSS-in-JS | 原子化CSS 🔗 相关:IE盒模型之争 | 渲染模式演进史 | 1995-2005 浏览器时代 | 2013-2018 SPA时代 | 2018-2023 工程化时代 | 2023-未来 AI时代