01|人人都在喊 CSS3,可谁也说不清 CSS3 到底是什么
Acid2、Acid3 把浏览器厂商抽得不轻之后,前端圈迎来了一段很热闹的日子。
新东西开始一波接一波往外冒:
圆角、阴影、渐变、变形、过渡、动画、多列、弹性布局……
到处都在喊一个词:
CSS3。
问题是,这个词从一开始就带着一点虚。
因为 CSS3 从来不是一个像 CSS1、CSS2 那样完整打包、统一发售的大版本。
W3C 后来自己都专门写文解释过:CSS 从 Level 2 之后就改成了模块化路线。 简单说,就是不再试图写一本巨厚总谱,而是把 Selectors、Backgrounds and Borders、Transforms、Fonts 这些内容拆成一份份小规范,各写各的,各走各的进度。
这么做的原因,其实第三篇已经埋过伏笔了。
大家都被 CSS2 那种“什么都想管,结果什么都落不稳”的经历吓怕了。
于是 CSS 工作组做了一个很务实的决定:
别再整包发货了,能成熟一块,就先放一块出来。
这是工程上非常理性的选择。
可一旦到了开发者世界,事情就开始变得喜感。
因为大家嘴里还在说“CSS3 来了”,实际面对的却是一锅有的模块半熟,有的模块刚下锅,有的模块连锅盖都没掀开的大杂烩。
从这一刻起,前端开始进入一个很奇妙的阶段:
名义上在学同一门技术,实际上每个人学到的可能都不是同一个版本。
02|模块化救了规范,也害苦了叙事
模块化本身没错。
站在 W3C 的角度,它简直是不得不走的一步。Selectors 可以先推进,Backgrounds and Borders 可以先稳定,Grid 这种难啃的骨头可以晚点来,彼此不用捆死在同一辆车上。
这套方法后来甚至被总结成了一种明确的工作思路。你去看 CSS Working Group 关于模块与快照的说明,会看到一句非常核心的话:CSS 之后的“级别”不再是整门语言统一升级,而是各模块各自升级。
工程师听了点头。
市场和媒体却开始发懵。
因为他们最爱的问题永远是:
“所以,CSS3 到底什么时候发布?”
这个问题,W3C 根本没法正面回答。
不是不想答,是没有那个时刻。
于是接下来很多年里,出现了一种很荒诞的景象:
规范世界在说:“没有单一的 CSS3。”
教程世界在说:“今天教你十个 CSS3 炫酷技巧。”
营销世界在说:“我们的浏览器全面支持 CSS3。”
而开发者夹在中间,只能一边点头,一边打开兼容性表格,心里嘀咕:
“你说的这个 CSS3,到底指哪一块?”
这还只是第一层混乱。
真正让前端开始像扫雷的,是第二层。
03|前缀本来是安全带,后来变成了绊马索
-webkit-、-moz-、-ms-、-o-。
今天的前端看到这些前缀,大多会想起老旧代码和兼容地狱。可它们刚出现时,初衷并不坏。
厂商前缀本来的意思很简单:
“这个特性我先试着做,但还不保证最后标准就长这样,所以先别把正式名字占了。”
这是一个很典型的工程师式妥协。既想让新能力早点出来给大家试,又怕未来规范一改,生产代码全炸。于是先加个自家前缀,意思是:实验品,谨慎食用。
这个思路在纸面上很体面。
可一进生产环境,人类就开始照旧干人类最擅长的事:
明知是实验品,偏要拿去正式上线。
于是教程开始写:
-webkit-border-radius: 8px;
作者们写着写着就懒了,只写一个最常见的;项目赶着上线,也懒得补全;浏览器厂商一看,站点都在用,只好继续兼容。
到这一步,前缀已经不再是“实验警示牌”,而更像一种奇怪的行话:
谁市场份额大,谁的实验语法就更像事实标准。
这件事后面会炸。
而且会炸得非常难看。
04|Flexbox:一代前端的考古现场
如果你想知道那几年 CSS3 到底有多乱,最好的样本不是别的,就是 Flexbox。
它的历史简直像三版不同剧本硬拍成一部连续剧。
2009 年 7 月 23 日,第一份公开的 Flexbox 工作草案出来了。那时候的写法还不是 display: flex,而是 display: box,搭配一堆 box-* 属性,比如 box-flex、box-pack、box-orient。
后来规范又改了一轮,进入一种很尴尬的中间形态,写法开始变成 display: flexbox。
再后来,才慢慢长成今天大家熟悉的:
display: flex;
站在规范编辑那边,这完全说得过去。早期设计不满意,算法要重做,语义要收紧,当然得改。
可站在开发者这边,体验就非常魔幻。
你搜到一篇 2010 年的教程,写的是一套。
你搜到一篇 2011 年的文章,写的是另一套。
你看 2012 年的示例,又是一套。
三篇都说自己在教 Flexbox。
这时候你终于会明白,为什么那几年很多前端打开博客第一反应不是“我学到了”,而是:
“等一下,这篇文章写的是哪朝哪代的 Flexbox?”
这就是前缀和模块化联手制造的经典事故。
浏览器为了抢跑,先实现一版。
规范为了修正,再改一版。
教程为了蹭热度,立刻把第一版写进生产。
等第二版出来时,全世界都在帮第一版收尸。
05|2012:前缀终于把自己养成了危机
前缀问题真正大爆炸,是 2012 年。
这场戏的背景很简单:移动端 WebKit 当时势头太猛。Safari、Chrome、Android 浏览器,一路把 -webkit- 前缀送成了网页世界最常见的那一个。
结果就是,很多站点和教程开始只写 -webkit-。
写着写着,事情就变味了。
不是“某个实验特性先在 WebKit 里可用”。
而是“你不是 WebKit,你看起来就像不支持这个 Web”。
这已经不是语法问题了,是生态绑架。
2012 年 2 月,CSS Working Group 在巴黎面对面会议和后续电话会上,专门讨论了这件事。W3C 那篇后来题目长得吓人的官方博客总结,第一句就把问题摊开了:移动端 WebKit 的垄断压力,已经逼得其他引擎开始考虑要不要去实现 -webkit- 前缀。
这话的荒唐之处,今天看依然很清楚。
本来前缀是为了避免各家实验实现互相撞车。
结果走到最后,大家居然在认真讨论:
“要不我们也支持竞争对手的实验前缀吧,不然用户会以为我们不行。”
这和当年 IE 私货把别人逼得跟着兼容,有一种非常难堪的历史既视感。
所以当时很多人会说:开放 Web 差点又走回 IE6 的老路。
这不是夸张。
因为逻辑真的一模一样:
谁份额大,谁的非标准写法就开始像标准。
06|这一回,连 W3C 自己都急了
前缀危机最有意思的地方,是它不再只是社区在骂。
连 CSSWG 自己都急了。
那篇 2012-02-19 的官方博客总结里,口气并不轻松。它明确说,这个话题争得很激烈,各方不但意见不一样,连彼此的立场细节都还没完全消化清楚。博客还提到:Mozilla、Opera、Microsoft 至少在“确实出了大问题”这件事上是一致的。
后面的讨论方案也很能说明当时的乱局:
- 要不要给某些特性提速
- 要不要更早去掉前缀
- 要不要同时保留前缀和无前缀写法
- 要不要把别家的前缀当成 alias 兼容掉
你仔细品一下,会发现这已经不是“如何设计一个新属性”了。
这是在收拾一场已经蔓延到生产环境的事故。
而事故的元凶,并不神秘:
教程图省事,作者图省事,浏览器图抢跑,规范图渐进。每一方都只偷了一点懒,最后整条生态一起埋单。
到了 2012 年 8 月,CSSWG 又专门讨论 experimental features policy,试图把前缀这件事重新管起来,至少别再让“实验中”直接等于“线上默认写法”。
这一步来得很晚,但总算来了。
07|所以那几年为什么前端像在扫雷?
现在把这些线重新拎一遍,答案就很清楚了。
不是前端突然变笨了。
也不是 CSS3 天生就邪门。
而是那几年里,几股力量同时在往不同方向拉:
- 规范为了避免 CSS2 重演,改成模块化
- 厂商为了抢新能力,靠前缀先上
- 教程和博客为了追热点,把实验语法写成“今天就能用”
- 市场又把这一切统称成一个看似清楚、实际很糊的词:CSS3
最后落到开发者手里,就变成了一块大型雷区。
你看到一个新特性,很兴奋。
然后你会问四个问题:
哪版规范?哪家实现?要不要前缀?这篇教程是不是已经过时了?
这就是那一代前端的日常。
所以第五篇真正想讲的,不是“CSS3 有多酷”,而是:
为什么一门看起来越成功、越热闹的技术,反而会在最红的时候把使用者逼得最狼狈。
如果你只记一句,那就记这句:
CSS3 最混乱的时候,不是因为它不流行,而正是因为它太流行了。
编者注(事实核对):CSS Level 2 之后采用模块化路线,见 W3C 关于 modules/snapshots 的说明、CSS Snapshot 2007 及相关历史文章;“没有单一 CSS3 发布时刻”的说法可由这些材料与 Bert Bos 关于 “CSS X” 的博客互证。厂商前缀 的背景与 2012 -webkit- 危机,主要据 CSSWG Wiki: Vendor Prefixes、2012-02-19 CSS WG Blog 及同期报道。文中关于 Flexbox 三阶段语法(display: box / display: flexbox / display: flex)的概括,依据 2009 W3C Working Draft 及后来的历史整理与兼容性回顾。将前缀问题概括为“安全带变绊马索”,属写作性比喻,不是规范原文表述。
关键人物速览
- Bert Bos:后期负责解释“CSS 为什么不再按整包版本升级”的关键历史叙述者之一。你今天对“没有单一 CSS3”这件事的理解,很多都得从他的说明开始。
- Elika Etemad(fantasai):CSSWG 长期核心编辑与解释者。关于模块化为什么会演变成今天这样,她的文章是理解这段历史的重要入口。
- Tab Atkins Jr.:后期很多 CSS 模块的重要编辑,尤其在 Flexbox、Grid 等路线里存在感很强。第五篇里那种“规范不断重写”的感觉,和他这代编辑风格关系很大。
- Daniel Glazman:在模块化和前缀混乱逐步失控时,既是工作组内部角色,也是后来危机篇里的公开发声者。
参考与延伸阅读
W3C:Levels, snapshots, modules…
https://www.w3.org/Style/2011/CSS-process.en.htmlfantasai:CSS WG — Modularization
https://fantasai.inkedblade.net/weblog/2011/inside-csswg/modulesW3C:CSS Snapshot 2007(Beijing)
http://www.w3.org/TR/css-beijing/Bert Bos:‘CSS X’
https://www.w3.org/blog/2020/css-x/CSSWG Wiki:Vendor Prefixes
https://wiki.csswg.org/spec/vendor-prefixesCSS WG Blog:-webkit- Discussions(2012-02-19)
https://www.w3.org/blog/CSS/2012/02/19/resolutions-24/CSS WG Blog:Experimental Features Policy(2012-08-30)
https://www.w3.org/blog/CSS/2012/08/30/resolutions-53/Flexbox 2009 Working Draft
https://www.w3.org/TR/2009/WD-css3-flexbox-20090723CSS-Tricks:Old Flexbox and New Flexbox
https://css-tricks.com/old-flexbox-and-new-flexbox/MDN:Backwards compatibility of Flexbox
https://mdn2.netlify.app/en-us/docs/web/css/css_flexible_box_layout/backwards_compatibility_of_flexbox/
下篇预告:2012 年前缀危机,差点把开放 Web 拖回 IE6 时代。