为什么 CSS 这么难学?

题主已经编程一年多了,先后学过Python Java ,写过爬虫若干、用Django写过网站一两个(套模板),拿pygame 也写过游戏,喜欢刷lee…
关注者
5,072
被浏览
1,543,737

306 个回答

对我来说,CSS 难学以及烦人是因为它「出乎我意料之外的复杂」且让我觉得「定位矛盾」


@方应杭 老师的答案我赞了:CSS 的属性互不正交,大量的依赖与耦合难以记忆。

@顾轶灵 @王成 说得也没错:CSS 的很多规则是贯彻整个体系的,而且都记在规范里了,是有规律的,你应该好好读文档而不是去瞎试。


CSS是一门正儿八经的编程语言,请拿出你学C++或者Java的态度对待它

但是问题就在这了,无论从我刚学习前端还是到现在,我都没有把 CSS 作为一门正儿八经的编程语言(而且显然它也不是),CSS 在我眼里一直就是一个布局、定义视觉样式用的 DSL,即「领域内语言」。

写 CSS 很有趣,CSS 中像继承、类、伪类这样的设计确实非常迎合程序员的思路,各种排列组合带来了很多表达上的灵活性。但如果可以选择,在生产环境里我更愿意像 iOS/Android/Windows 开发那样,把这门 DSL 作为 IDE WYSIWYG 编辑器的编译目标就可以了,当然你也可以直接编辑生成的代码,但我希望「对于同一种效果(语义),有比较确定的 CSS 表达方式(语法,或规则)」

因为我并不在 CSS 里处理数据结构,写算法、业务逻辑啊,我就是希望我能很精确得表达我想要的视觉效果就可以了。如果我需要更复杂的灵活性和控制,你可以用真正的编程语言来给我暴露 API,而不是在 CSS 里给我更多的「表达能力」


CSS 语言本身的表达能力对于布局 DSL 来说是过剩的,所以你仅仅用 CSS 的一个很小的子集就可以在 React Native 里搞定 iOS/Android 的布局了。你会发现各个社区(典型如 React)、团队都要花很多时间去找自己项目适合的那个 CSS 子集(so called 最佳实践)。而且 CSS 的这种复杂度其实还挺严重得影响了浏览器的渲染性能,很多优化变得很难做。

而 CSS 的表达能力对于编程语言来说又严重不够,一是语言特性不够,所以社区才会青睐 Less、Sass 这些编译到 CSS 的语言,然后 CSS 自己也在加不痛不痒的 Variable。二是 API 不够,就算你把规范读了,你会发现底层 CSSOM 的 Layout、Rendering 的东西你都只能强行用声明式的方式去 hack(比如用 transform 开新的 composition layer)而没有真正的 API 可以用,所以 W3C 才会去搞 Houdini 出来。

这种不上不下的感觉就让我觉得很「矛盾」,你既没法把 CSS 当一个很简单的布局标记语言去使用,又没办法把它作为一个像样的编程语言去学习和使用。


在写 CSS 和 debug CSS 的时候我经常处在一种「MD 就这样吧反正下次还要改」和「MD 这里凭什么是这样的我要研究下」的精分状态,可是明明我写 CSS 最有成就感的时候是看到漂亮的 UI 啊。

以上。

实名反对以上所有给css难学洗地的人(哈哈,终于又可以装回逼了,来吧,欢迎撕逼)

CSS难学,方应杭 @方应杭 的答案我很赞同。正交性,姑且不论这个其他行业的专业术语来形容好不好,但他表达的思想是非常正确的:设计api或者框架的时候,一定要注意一个api影响的范围足够小,尽量一个api只干一件事。

而CSS完美的破坏了这个规则。

就这样,还有一堆给CSS洗地的,我也是醉了。让我们来看段洗地的评论:“这些在CSS规范里都写的很清楚,并且是可以推导的”。规范写的再清楚,和CSS设计理念就出错有什么关联?要记住,任何编程工具都是为人服务的,他们是轮子,是工具,是为了让人提高生产效率的。一切和这个目的相矛盾的设计都是反人类的。这点上虽然我不赞成轮子哥的wpf的前景问题,但CSS像杂耍似的我很支持。CSS撸了一堆隐藏规则,为什么设计之初不尽量避免这种设计、做到望文生义,而是隐藏在那几千页的规范里?CSS是给人用来画UI的,不是让你先学个几千页规范的。这目的就搞错了。假如你是一个框架的设计者,你撸了一堆互相影响、可能各种潜规则的api,然后告诉接手的哥们,“我这里面潜规则很多,你先看看那几十页的文档”,你看看会不会被人打?

来看个方应杭的例子。Transform这玩意加上之后,fixed 定位的元素居然相对于父容器定位。我当然知道规范里肯定有写这条规则,也知道这么做的理由。但这不是洗地的理由。为什么设计的时候非要加上这条原则?如果不加这条原则是否会引发更大的麻烦?如果非要加上的话,是不是应该在名字上加点修饰词而不是光突突一个Transform?更进一步,这样设计会不会给浏览器实现起来带来性能上的开销?

其实我觉得用“潜规则”这词来代替“正交性”来形容可能更好些。CSS里面潜规则简直多如牛毛。比如margin、padding的默认值,基本BAT三家的的网页都是一开头就全部清0了。搞个傻了吧唧的默认值,除了给大家制造麻烦,以及让大家多查规范文档,不知道还有啥鸟用。还有“inline-block的基线是最后一行文字的底部,flex里面的基线是第一行文字的底部”、“只有一个元素属于inline或是inline-block水平,其身上的vertical-align属性才会起作用”等一堆堆的潜规则。不要说这些潜规则文档里都写了。好的设计架构务必做到望文生义,看名字能知道用法,而不是靠别人查文档。记忆这些潜规则终究是需要脑力负担的。你第一次学的时候记住了(当然也可能被坑过才记得),过段时间说不定忘记了呢?会不会又被坑一次?所以什么文档详细记载了、规则都是可推导之类的托词真不是CSS设计各种缺陷以及容易学的理由。

CSS的设计缺陷还体现在各种浏览器的兼容性上面。大家以为是因为浏览器兼容性问题导致CSS难学,其实事实是反过来也成立。CSS的各种潜规则已经导致了就算是chromium的开发人员也经常各种被坑的程度了。打开chromium.googlesource.com看下每天多少提交都是关于修复实现中完善各种潜规则带来的坑。有人说刚学css,不必考虑浏览器兼容性。但事实是你的产品要用到生产中就肯定会遇到兼容性问题。因为不光各种浏览器之间CSS实现方式不一样,浏览器不同版本之间实现方式和表现也不一样。这很大部分原因就是CSS里潜规则太多导致的。

利益相关:微信X5内核苦逼排版工,曾经每天各种改chromium的排版bug。

未完待续,想到了继续喷…

最后放波硬广:屌炸天的内核来袭,史上最小chromium内核miniblink!

小巧的魔改版blink,嵌入作为浏览服务组件的最佳选择。现在已经继续开更了。