zijiang 发表于 2023-10-3 19:29:53

为什么 CSS 这么难学?

题主已经编程一年多了,先后学过Python Java ,写过爬虫若干、用Django写过网站一两个(套模板),拿pygame 也写过游戏,喜欢刷leetcode …总体来说我觉得编程是一件很有趣的事情。
然而上个月开始系统学习HTML CSS JavaScript…都说HTML CSS 特别容易,可我学了两三个星期了,模仿个京东网站的静态页面还是感觉很难,尤其是布局这块。我是跟着w3school上学的,每个标签,每个属性可以说我都看的很仔细,但每次一到自己从零开始做一个页面的时候,我就会完全不知道从哪儿下手,一个下午下来一半都写不出来…我总结出来觉得难的原因如下:
1.很多时间都花在debug 上了,比如在CSS选择器中,div前面多加了一个点,然而浏览器完全允许这种行为啊,导致每次出错我都得扒着屏幕一块一块看哪儿错了,。写个代码让我有种吃屎一样的难受…
2.前有IE 6的不兼容,后有CSS 3大量属性的补充。让我感觉内容特别细、杂、多。
相反我倒觉得JavaScript 能学下去,毕竟是编程语言,以前接触的比较多,理解起来不难。
我想问一下,我这种情况属于正常吗?CSS 真的有网上说的这么简单吗?
另外,有支持语法报错的浏览器吗?

madein163 发表于 2023-10-3 19:30:44

第一,CSS 属性之间不是正交的,就算你很清楚你要做什么,也不是说你独立地把属性一个一个逐步设对了结果就是对的。你可能更改了一个属性后,另外一个已经设对了的属性现在就变得不对了。
第二,CSS 属性在设计出来时,参与制定标准的人以为这个属性会用做作某些用途,但实际使用时总有人发现已有的属性不能实现他们想要做的事情,于是通过一些奇技淫巧的方式把这个属性用做另外一些用途。你单独学习这个属性,你是不可能学会这些意料之外的用途的,为此你必须花时间学习别人发明出来的「设计模式」。
推荐两本这种奇技淫巧方面的书,你看看就明白了:
CSS Mastery如果说上面那本是老一代的奇技淫巧,那下面这本就是新一代的了:
CSS Secrets看完你就会明白我在说什么了。

supersmart 发表于 2023-10-3 19:31:20

CSS并不比其他编程语言更困难,说这个话大概是因为没有接触到真正困难的地方。因为大部分程序员做的都是最基础最简单的工作。
编程有两类不同的工作:一类是机械性的,把比较清晰的行为逻辑翻译成代码;另一类是创造性的,给你的信息是不足的,需要发挥创造力,补上不足的部分,完成整个项目。它可以包含难易程度各自不同的很多内容:
1. 根据接口设计算法
2. 根据功能设计相配合的接口和数据结构
3. 设计容纳现有功能及未来扩展的软件框架
4. 设计能达到预定目标、满足用户需求同时开发成本最小的的功能
创造性的工作天生是困难的,许多程序员最多只接触过1到2,甚至很多只是翻译一下业务逻辑,自然会以为编程就是比较简单,那是因为水平不够,复杂的工作都让别人替自己做了。即便是许多所谓架构师、产品经理,他们做3和4做的怎样,你们心里恐怕也有数。
说回CSS。如果说你写CSS的时候得到的信息跟写业务逻辑一样清楚,比如说:整个页面有三个框,采用浮动布局,左边和右边固定200px,最小高度是100vh,内容是中间框的子节点,padding是10px……那你也会觉得写CSS很容易,就是翻译一下嘛。问题在于写CSS的时候给的并不是这种清晰的描述,而是只有整个东西长什么样,至于具体每个元素如何排布、使用怎样的布局方式、如何设计选择器,都是需要自己精心设计的,自然就显得难了。
为什么整个东西长什么样不能直接翻译成CSS呢?很多人以为CSS是给DOM元素设置属性(attribute),其实CSS规定的并不是属性,而是行为(behavior),DOM里的每个元素都可以看成是一个独立的物体,按照CSS规定的方式运动,最后稳定下来的结果就是最终布局的结果。所以高票答案说CSS不正交,它当然不是正交的,因为它的设计就是要求协变,要求在其他元素做出调整的时候,即便本元素的样式没有发生任何变化,也可以跟着调整位置和大小,以适应新的内容,维持设计风格。
为什么CSS要设计成基于选择器和多种各异的behavior,而不像其他框架那样直接将显示样式绑定到每个元素呢?恰恰是因为正交性,因为CSS和DOM是正交的,这样DOM内容变化时,CSS可以规定一组不变的特性,从而以灵活的方式适应内容的改变。传统的GUI通常每个元素都有固定的位置和大小,要实现根据内容动态调整,就必须针对各种情况(如视口大小改变,内容改变)专门编写代码;WPF则有网格、流式、绝对三种不同的定位方式,与CSS有不少共同点,但是自适应的功能少了不少,也没有选择器的功能,这样动态生成的内容就需要更多的代码来调整。而CSS只要将DOM组织成特定的格式,就会自动启用相应的样式。WPF制作的界面毕竟变化比较少,大部分元素仍然是固定的,而网页通常要求更高的灵活性。

pbk8495 发表于 2023-10-3 19:31:42

实名反对以上所有给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的开发人员也经常各种被坑的程度了。打开https://chromium.googlesource.com/chromium/src/+log/看下每天多少提交都是关于修复实现中完善各种潜规则带来的坑。有人说刚学css,不必考虑浏览器兼容性。但事实是你的产品要用到生产中就肯定会遇到兼容性问题。因为不光各种浏览器之间CSS实现方式不一样,浏览器不同版本之间实现方式和表现也不一样。这很大部分原因就是CSS里潜规则太多导致的。
利益相关:微信X5内核苦逼排版工,曾经每天各种改chromium的排版bug。
未完待续,想到了继续喷…
最后放波硬广:屌炸天的内核来袭,史上最小chromium内核miniblink!
小巧的魔改版blink,嵌入作为浏览服务组件的最佳选择。现在已经继续开更了。

unitar 发表于 2023-10-3 19:32:18

对我来说,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 啊。
以上。

石磊 发表于 2023-10-3 19:32:46

CSS 需要记忆的东西稍多一些,但是仍有很多规则是贯穿整个体系的,没有方老师说得这么吓人。需要记忆的东西也是会总结归纳成套路的,并不用取笛卡尔积这样一个个试。按我的理解,有点像化学。
CSS 2.2 并没多长,而且很少有 ES 规范里的这么多形式化描述,只是大多数人静不下心读罢了。不看规范也可以看《CSS 权威指南》,大多数情况下掌握规则可以事半功倍。
没有足够的理论体系去指导实践,这样的实践是盲目且脆弱的。
--
CSS 要解决的问题这么复杂,API 能简洁到哪里去?作为一个声明式的 DSL 要同时兼顾灵活性、可访问性降、向后兼容、响应式、多媒介、文字排版、浏览器引擎实现难度和与 HTML 的正交性等等一系列问题,简单的一句样式声明背后必然隐藏了复杂的底层逻辑。逻辑是守恒的,DSL 本身就是用来简化计算的,如果它的 API 很简单,那无非是把复杂的布局、排版算法丢给开发者自己去解决。
简单、强大、灵活三者不可得兼呀。
页: [1]
查看完整版本: 为什么 CSS 这么难学?