了解 CSS 是前端开发的精髓

有无数文章都在说明为什么开发人员不应该过于关注框架,而应该学习理解底层语言。但我认为,除了框架来来去去之外,我们很少能找到很好的理由。对我来说,主要原因是不同的:如果你不了解一种语言的底层机制,你就无法成为前端开发高手。

如今,常见的堆栈是 React 以及语言和框架本身之间的无数层。作为样式设计方法的 CSS 并非原生使用,而是通过 JavaScript 工具将其转化为原生 CSS。对于 JavaScript,我们如今使用 TypeScript 编写一种有主见的框架语言组合,而 TypeScript 本身最终又会被翻译成本地 JavaScript。虽然我们都知道这些工具和语言的舒适性,但如果了解浏览器的生态系统,很多事情都会变得更容易:

  • 无需安装调试浏览器扩展,就能更轻松地在国外环境中调试 JavaScript 错误
  • 调试 CSS
  • 编写自定义 CSS(迄今为止,我看到的每个项目都需要自定义 CSS)
  • 了解错误发生的原因,这些错误可能无法在本地发现,只能在客户端浏览器中发现

在过去几年中,我遇到过各种情况,TypeScript 开发人员(他们自称)找到我,问我能否在 CSS 方面帮他们一把。我本以为能解决一个复杂的问题,但对我来说–我对 CSS 非常了解–这总是一个简单、直接的解决方案或代码片段:

  • 一个多彩的页脚栏不应该是一张图片,它是一个简单的 CSS 背景多级渐变,只需要一行代码。无需缩放图片或创建 SVG,只需 CSS 即可。
  • 为输入框自定义图标?出于保护隐私的考虑,在某些情况下添加伪类并不容易。不过,有很多简单的解决方案,没必要再加入一个臃肿的 npm 依赖项,因为没人明白它的作用。
  • Webfonts:  开发者:我们不能再添加另一种网络字体样式了,我们已经提供了 4MB 的网络字体。
    • → 我:好吧,为什么不把它作为可变字体提供呢?
    • → 开发人员:哦,这是什么?
    • → 看看吧,我们现在可以异步加载 218kb,只有一个文件,而且里面有我们现在和将来需要的所有样式。

 

如今,人们可以写出很棒的 React 和 TypeScript 代码。大多数情况下,人们会使用 MUI、Tailwind 等组件库来设计样式。然而,几乎没有人能够判断代码库中的 CSS 是好还是差得很远。它被我们的工具链神奇地应用到 HTML 中,而我们却很难理解为什么网站会越来越慢。

我在十年前学到的大部分性能基础知识在今天仍然是最实用的。然而,大多数开发人员并不了解它们,因为我们使用的是 create-react-web-app 或类似的东西。将 Cloudflare 放在顶部,以提高性能并降低成本。是的,这对您的网站和小项目都有用。

当公司要求为其客户提供一个提供实时数据的网络仪表盘时,他们的期望是不同的:它应该是一个强大、运行良好且易于维护的应用程序。这意味着我们需要将开发人员的经验(React、TypeScript 和所有小助手)与浏览器和网络工作原理的知识结合起来。只有这样,我们才能提高性能、编写可访问的代码、以适当和安全的方式加载动态数据,并在出现问题时提供后备功能。

在服务发生事故等紧急情况下,我经常看到这样两种人的区别:一种人很清楚该从哪里着手,开始调试并继续前进;另一种人则慌乱地试图找出问题所在,希望通过重启或重新安装依赖关系重新部署能让服务起死回生。

而这意味着最终又会如此: 如果你了解 CSS,你也就了解了样式框架。如果你了解 JavaScript,TypeScript 对你来说也不是什么大问题。这样,你就可以成为高级或主管。

本文文字及图片出自 Knowing CSS is mastery to Frontend Development

你也许感兴趣的:

共有 206 条讨论

  1. 我不同意这里的许多评论。CSS 并不复杂。它是样式化 HTML 元素的好方法。

    在编写 CSS 时,有一些流行的抽象方法,例如 Tailwind。虽然我确实看到它误导了很多人。当你不懂 CSS 但又想制作网页时,不妨使用模板。如果你想深入定制样式,就需要了解 CSS。Tailwind 只是一个预定义实用工具类的集合,你会过度使用这些工具类,在使用过程中会破坏一些简洁的代码原则,但你无需自己编写所有的实用工具类,就能得到一个看起来不错的网站,这对大型团队项目很有帮助。

    这个问题有了一些改进,比如 DaisyUI。

    但无论如何,它们都需要对 CSS 有一定的了解。如果你对 CSS 有一定的了解,那么更上一层楼,学习如何编写可扩展的 CSS 并不难。在每个现代框架中,拥有全局和范围样式的简单要求都是必然的。

    这也是我创建现代可扩展 HTML 和 CSS 编写指南的部分原因:https://webdev.bryanhogan.com/。

    – Tailwind(哇,网站太慢了):https://tailwindcss.com/

    – DaisyUI: https://daisyui.com/

    – 某些现代框架,如 Astro:https://astro.build/

    1. 来自 daisyui.com:

       尾风 CSS 提供低级实用类,通常只包含一条 CSS 规则。
        daisyUI 类由多条 CSS 规则组合而成,这些规则按用户界面的每个部分进行语义命名。
      

      因此,简单地说,Tailwind 将 css 属性-值对作为类名重新实现,而 daisyui 则将 css 类名重新实现。

      似乎整个舞蹈就是为了避免

       class=“btn” style="font-color: #3e3”
      

      因此,与上面不同的是,现在可以通过类覆盖样式,如

       class="btn font-color-3e3”  
      

      (或 tailwind 提供的任何内置类)。这些间接的层级是否值得,现代 css 是否仍然需要?我记得我们之所以使用 css 框架和 BEM,是因为很难对 css 进行范围化。

      1. > 我记得我们之所以使用 css 框架和 BEM,是因为很难对 css 施加作用域。

        我怀疑这反映了一个文化问题,即在许多组织中,没有人真正愿意创建或坚持系统化的设计。

        随着网站规模的扩大,对 CSS 进行范围划分并非易事,但也远非难事。

        Tailwind 对各处具体细节的定位就是 “放弃 ”的解决方案–停止试图让组织和文化去做他们不想做的工作。

        编辑:我还认为,大多数开发工具都存在反馈循环不畅的问题。当人们谈论 “我不想查每个类的含义 ”之类的事情时,他们说的是代码组件化的一个现实情况,即开发环境中的样式/语义/标记/逻辑等多个维度,通常无法支持开发过程中的交互式、可读性和相互关联的反馈。也许有一些解决方法,但比起将样式/语义/标记归结为一个单一维度,围绕着一种一致的、受限的用户界面领域语言(你最多可以在一周内将其添加到简历中),这些方法更复杂、更不为人所知,也更不可替代。这对目前构建前端的主流 “文化 ”更为友好。

        1. > Tailwind 对具体细节的定位是 “放弃 ”的解决方案

          是的,这就是为什么我真正好奇的是,是否仍然需要采用核方法,或者说现在的 css 变量、@scope 和其他什么东西可以解决过去的问题。

          因为 Tailwind 引入的问题似乎是 CSS 试图解决的,而现在 DaisyUI 试图解决 Tailwind 的问题。

          我们现在是否已经到了这样一个地步:开发人员对基础知识了解不够,在思想上被困在他们所知道的工具上?还是老问题仍未解决?

          1. > 因为尾风似乎引入了 CSS 想要解决的问题

            > 我们现在是否已经到了这样的地步:开发人员对基础知识了解不够,在思想上还停留在他们所熟悉的工具上?还是老问题仍未解决?

            您应该阅读 https://tailwindcss.com/docs/styling-with-utility-classes。有经验的开发人员之所以使用 Tailwind,是因为它能解决 CSS 方面的实际问题,而这些问题在你参与复杂网站、复杂设计和/或大型团队工作之前是很难理解的。人们常常把Tailwind的用户说成是不懂CSS的人,但事实并非如此。

            普通的 CSS 对于简单的设计和基于文档的网站来说没有问题,但层叠样式、特殊性以及样式在文件之间的传播方式等,都会成为日后发展和维护的噩梦。CSS 的发明并没有考虑到我们现在需要编写的复杂响应式用户界面和设计,因此传统方式不能很好地扩展也就不足为奇了。

            你是否处理过 Java/OOP 代码,这些代码中分布着大量复杂而脆弱的继承树,你根本无法确定哪段代码覆盖了哪段代码,也不知道如何在不破坏其他代码的情况下进行修改?这与上述情况并无二致,但人们会盲目地捍卫传统的 CSS 方法,因为这些缺陷尚未被广泛接受。

            1. 我并不否认 Tailwind,CSS 在样式的范围界定方面存在问题。从那时起,我们就有了 BEM。现在,CSS 已经逐渐解决了这个问题。

              因此,问题在于 Tailwind 现在是否已经成为一种过时的方法。尤其是当 DaisyUI 试图在 Jenga 塔上再添一块积木的时候。

              1. > 从这里我们进入 BEM

                这里的问题/限制仍然是:现在我不得不给我所有的 div 起冗长的名字,CSS 也是冗长的,响应式 CSS 非常冗长,你不能轻松地将不同类的样式组合在一起(比如从其他地方添加阴影或文本样式,而每种样式都需要多行 CSS),样式在 HTML 和 CSS 文件之间分割,这减慢了编辑和调试的速度,很难保持样式/间距/大小的一致性,除非你(冗长地)在所有地方使用变量。

                所有这些因素加在一起,使得编写和维护 CSS 的过程既耗费精力又令人沮丧,尤其是当你想快速修改设计时,你还不太确定它应该是什么样子。

                我不是 DaisyUI 的用户,但 Tailwind 与标准 CSS 和 BEM 相比仍有很多优点。

                > 为 Jenga 塔再添一块积木。

                同样,为什么不直接在 HTML 上编写样式呢?对网站进行大量的重新样式化总是需要修改 HTML 和 CSS,并添加只用于样式化的 div。BEM 主要是承认层叠和特殊性是要避免的 CSS 特性,那么为什么要止步于此?

          2. 是的,没错。

            在我看来,真正学习 CSS 一直是大多数开始从事其他工作的开发人员长期以来想要避免的事情。我怀疑这只是在挠痒痒,感觉更像是配置而非编程。当然,一旦抽象层成为既定开发文化的关键,那么抽象层的回报机会可能会比抽象层下的层更多。不过,我不确定 Tailwind 或 DaisyUI 的风格设计是否足以锁定这一点。

            我猜 css vars、@scope 等确实能解决一些问题。我还猜测,要解决大多数技术表达/组织问题,还需要与完整的本地混合组件相当的东西,但我不确定 css vars 是否能解决这些问题。另外,组织文化中的各种因素往往会低估前端设计和工程中的各种领域(我猜这在很大程度上可以归结为以转换为导向的修修补补的动机和公认的产品利益相关者对自行车的自豪感)。

            1.  > 我还猜测,要解决大多数技术表达/组织问题,需要与完整的原生 mixins 相当的东西,而我不确定 css vars 能否实现这一点。
              

              你说是原生的,但同时 CSS 预处理器能否填补这一空白呢?如果 @layer 和 @scope 可以解决 BEM 之前的问题,我想我们就可以了。

               > 再加上组织文化中的各种因素,我们往往会低估前端设计和工程中的各种领域。
              

              是的,如果人们只是不想重用,而想快速破解一些东西,比如

               <button class=“class_6447823468”>按钮
              

              那么,我想它更像是一个解决组织/技能问题的工具。

              我只是不明白,在一个大中型网站中,如何通过 Tailwind 这样的工具来实现和执行一致、可维护的风格。难道人们要以质量、一致性和自由度为代价,换取一套可能应用不一致的有限设计代币?

              我不得不承认,我已经很久没有使用过 css 了,而大家对 Tailwind 的热情又让我怀疑我是否缺乏了解。

                1. 我只想说,谢谢你的这篇文章 — 我之前没有看到过它,它有效地触及了我对 Tailwind 的一些实际批评,以及一些我尚未阐明的批评。

                  我真的很高兴它能将网络工艺的背景带入其中,我认为这两者是相关的。正如我在其他讨论中提到的,Tailwind 的吸引力有相当一部分可能来自于它与商业网站开发文化的 “纹理 ”相吻合的方式,而商业网站开发文化本身是由产品管理文化驱动的,以转换指标为导向(通常采用不确定的 A/B 测试),并对骑自行车的人给予奖励。工匠精神或系统化设计的好处不太明显,因此设计方向和前端任务往往是一次性的逐屏设计,而且非常粗糙。语义是事后的想法,大多数利益相关者都看不到,系统化的尝试往往被视为与业务目标无关,甚至是障碍。

                  尾风公司就这样放弃了。给企业及其代理商他们想要的东西,完成你的任务清单,然后去其他地方关心质量的微妙之处。

                  1. 我在这篇文章中没有详细论述这个问题,但在我写完这篇文章后的一段时间里,我真正认识到了一个事实,那就是很多开发人员并不把前端视为 “真正的 ”编程。

                    这些开发人员来自各行各业,后端、移动等等,但都对前端网络抱有一致的蔑视。他们认为前端是需要完成的工作,不需要多费口舌,这样就能回到 “真正 ”的编程中去。

                    因此,任何会拖慢 “完成工作 ”进程的事情都会被视为愚蠢的负担。学习 JS 可以获得小小的通行证(也有很多批评,有些是合理的,有些是令人厌烦的,还有些是不公正的),因为它至少拥有 “真正 ”编程语言的外衣,而 HTML 又足够简单,你可以在一个下午内学会所需的大部分内容。但 CSS 就不一样了。它不是真正的编程语言,也不简单。它实际上相当复杂,过去甚至更难。

                    因此,我们一次又一次地看到,这些工具旨在成为解决这一问题的灵丹妙药。ExtJS、Bootstrap、BEM、Tailwind……这样的工具层出不穷。它们都试图让可怜的开发者不必真正学会使用手头的工具。

                    我不想用 “木匠不知道如何使用锤子,所以用石头代替 ”这个老掉牙的比喻,因为这对 Tailwind 这样的工具来说是一种伤害,因为它们本身就是令人印象深刻的工程壮举。恰恰相反,一个通常习惯于使用金属板的人,却被委以建造房屋框架的重任。他使用钉锤来钉钉子,只要他只是把钉子钉进木头里,效果就足够好了。但是,当他需要移除一些木棍,以便在原先有墙钉的地方开辟一个新门洞时,他突然发现自己的锤子末端没有爪子可以把钉子拔出来,于是他不得不使用螺丝刀和钳子。

                    这就是尾风。钉锤 你可以用它编写前端。但一旦你要修改任何已经写好的东西,你就会面临它的限制。因此,你会发现自己正在通过模板或项目中的任何模拟工具,将 bg-blue-300 调出并替换为 bg-purple-300,也许使用一些查找和替换功能来帮助完成这一过程,但你知道自己不能完全依赖它,因为有些 blue-300 的东西你想保持蓝色,而有些则不想。

              1. 根据我的经验,在大大小小的项目中使用 Tailwind 差不多有 5 年时间了,它的扩展性相当不错。你只需按照作者的建议去做:将样式封装在组件中,而不是 CSS 类中。

                现在看来,这并不像听起来那么灵验。像按钮和下拉菜单这样的标准组件很快就能解决,而那些总是出现在这里或那里的不寻常组件则更容易引人注目。不过,这也是我使用 BEM/Bootstrap/whatever 之前的经验。

              2. css 预处理器就是 CSS 模块,是的,它解决了现在的范围界定问题

        2. 对我来说,这一直都不是一个技术问题,而更多的是产品设计部分的素材永远都不够一致,以至于你无法用一个一致的 CSS 文件来驱动整个网站。

          1. 是的,这就是我所说的 “不要再试图让组织和文化去做他们不想做的工作 ”或 “放弃吧”。

            我确实认为,有些工具存在缺陷,这可能会改变所需的投资,进而改变组织的前景,而且尾风方法也存在一些技术缺陷,这可能会让类似的替代方案物有所值。但这需要一个拥有大量空闲时间、经验和非同寻常的洞察力的团队来完成。也许还需要一定的影响力才能使其落地。

            与此同时,Tailwind 代表了一个貌似可以接受的局部最大值,它与更大范围的网络开发实践和文化中的许多其他东西不谋而合。

            需要明确的是,我的评估是描述性的,而不是规范性的。Tailwind 在功能上适应了主流商业网络开发文化中的功能障碍,而不是一种有价值理想的表达。

        3. 如果认为问题出在人们不知道如何架构一个好的 CSS 解决方案,那就有失偏颇了。现实情况是,项目在整个生命周期中需要多人维护。OCSS 只会带来技术债务和限制,更不用说臃肿的 CSS 文件了。这篇文章很好地解释了为什么 OCSS 是糟糕的 https://www.fcss.club/manifesto,以及为什么功能 CSS 或原子 CSS 从短期和长期来看都更好 https://www.fcss.club/why。尾风只会带来更多复杂性。

      2. 不是 font-color 3e3,而是 font-red-300。这是一个重要的区别,因为第二个区别尊重了你的美术团队花费大量时间建立的设计系统。通过使用他们的语言,你可以将应用程序中使用的样式集规范化,而不是单独、重复地对十六进制值进行硬编码。

        其次,如果考虑到 lg: 和 hover: 等伪选择器,尾风的真正威力会更加明显。

    2. 对于我这个开发人员来说,bootstrap 或 daisyui 这种级别的东西很有意义。

      但与我共事过的设计师们–在这里我真的要尊重他们的专业意见–在我称之为 “标志性 ”的网站或页面上,他们似乎经常受到固定设计结构的限制。当然,对于不是那么重要/可见的东西,这些通用系统已经足够好用了。但对于其他内容来说,他们有自己想要实现的特定愿景,而通过类似 daisyui 和 bootstrap 这样的系统来实现这些愿景(对我来说),要比直接使用 css 或使用像 tailwind 提供的实用工具类要费事得多(对我来说)。

      我认为现实情况是,开发人员正在使用 html、css 和 js 构建应用级组件。自然而然地,你就会想找一些东西来减轻工作负担,因此你就会使用中间层的抽象概念来工作。daisyui 和 tailwind 都是这样的抽象概念,因此从高层来看,并没有什么区别或争论。很明显,当您确定不想要/不需要尾风的额外灵活性时,您就会选择 daisyui,而当您有疑问时,您就会选择尾风。由于您将拥有一个应用程序级的组件库,因此无论采用哪种方式都不是什么大问题,只是开发和维护这些组件的过程是否愉快的问题。

      1. 最近我只使用 bootstrap 网格,对此我很满意。

    3. 可悲的现实是,年轻人忙于学习 JS,而后台开发人员却不了解它。在过去 6 年中,我还没有从与我共事的前端开发人员那里学到新的 CSS 模式。同样,我曾在一些团队中工作过,他们做出了落后的决定,选择了死工具,而不是接受新的 CSS 模式。我认为我必须向安娜-图多(Ana Tudo)、莱亚-维鲁(Lea Verou)和雷切尔-安德鲁(Rachel Andrew)学习,因为他们做了足够多的宣传工作,让我的技能与时俱进。

    4. 我认为,CSS之所以受到如此多的抨击是不公平的,因为人们经常会在做其他工作时遇到它。而这些开发人员可能并没有接触过 windows/macos/ios/android 应用开发。

      1. 我几乎遇到过所有这些问题,而 css 仍然是列表中最糟糕的问题。它简直是每分钟 wtf/gfy 最高的。几乎无法调试、前后不一致、来自设计、语焉不详的垃圾。

        1. 尤其是在很长一段时间里,所有人们认为应该很容易做到的事情都很难做到,比如垂直居中、网格/柔性布局之前的布局、在一个地方改变样式而不意外破坏 html 的其他部分。还有很多关于浏览器怪癖的部落知识,例如如何清除浮动 div、选择器优先级、边距如何折叠等,这些都是非基本的复杂性,在你最没有时间处理的时候,这些复杂性就会咬你的屁股。

          1. 没错。从某种意义上说,Css 是一种魔法,你根本无法理解它。看看这个:https://stackoverflow.com/a/19719427,你可以通过调整溢出、浮动或位置来 “调整 ”折叠边距。没错!想象一下,通过踩刹车或关闭收音机来调整你的座位。

            在使用隐藏功能时,唯一的区别可能就是在父级高度固定的情况下,隐藏内容会带来意想不到的后果

            这是 css 社区的基本原理。它可以 “完美 ”运行,但要确保没有指定高度。还有,不要更改容器类型。随着时间的推移,这一切会越来越依赖于其他黑客,直到你的布局变成一个由黑客和横截面假设组成的结,遍布整个 “代码库”。

            然后,你就应该用它来制作完全隔离的、无泄漏的组件。我的意思是,你做不到,但这里有一个黑客技术可以让它们合在一起。我的意思是,在这种特殊情况下,感谢上帝,容器的位置已经是绝对的了。

            1. > 看看这个:https://stackoverflow.com/a/19719427,你可以通过调整溢出、浮动或位置来 “调整 ”折叠边距。没错!想象一下,通过踩刹车或关闭收音机来调整座椅。

              这里看似复杂,是因为人们拒绝学习框模型,所以他们学习各种咒语,猜测他们需要做什么:https://developer.mozilla.org/en-US/docs/Learn_web_developme…

            2. C 语言的神奇之处在于,当我懒得学习它时,我就无法理解它。

              1. 谢谢你没有贴出 “拳击模型 ”的链接。它每次都被贴出来,就好像是 web/css 发明了拳击、填充、间距和边框,而其他人都是一窍不通的菜鸟。这清楚地表明,人们甚至无法理解问题所在,也无法理解 css 人员对布局的怪异思考方式有多深。在这里,一切都是无法独立站直的拐杖组合。

                没错,C 语言也是一堆垃圾。我用它编了 15 年的程序。

        2. 同意。没有静态类型。一切都是全局的。在其他页面上,你很容易不小心破坏一个你不知道的东西。这只是一个脆弱的堆栈。迄今为止,Tailwind 是我最喜欢的处理所有这些问题的创可贴。完美吗?不,但它是我近 25 年专业工作中使用过的最好的东西。

          1. 你在说什么?CSS 是静态类型的。它有一个相当严格、定义明确的模式。

            1. 我不知道 gp 是什么意思,但 CSS 缺乏所谓的 “选择器会计”。你永远不知道哪些部分会影响哪些内容,以及它们是否会影响任何内容。因为它不是导入/使用样式或类,而是通过选择器将样式强加给一组不可预测的节点。除此之外,每个名称都是全局的。

              这与每一种现代语言形成了鲜明对比,无论是否声明式语言,都需要将其明确导入到块/块/组件等中才能获得效果。

              如果 css 是 C 语言,它可以在类型定义之后的函数中的每个 int 变量中添加 “unsigned”(无符号)。这是 “面向方面编程 ”的一部分,简单地说,这被认为是一种荒谬的坏做法。

            2. 大多数 CSS 确实是静态类型的(属性具有静态类型的有效值)。但引入自定义属性和 IACVT 后,情况就不一样了。

    5. 我还没来得及阅读所有的评论,所以这可能已经在后面提到过了,但是–在我看来,掌握 CSS(vanilla)对于理解浏览器如何呈现内容至关重要,而这本身对于理解如何构建内容(并进而编写浏览器 JavaScript)也至关重要。

      学习它吧!这是值得的。它还能让 Tailwind 和所有这些抽象概念更容易掌握。

      附注:Sass(SCSS)的功能非常强大。也学习一下吧!

    6. 我从未领会过 Tailwind 的魅力,从 style=“” 到 classname=“” 几乎是 1 对 1 的映射,他们只是让术语更容易记忆而已。

      Tailwind 是一个很好的例子,说明良好的营销如何帮助你赢得市场,即使替代品是免费的,即使市场已经很拥挤,即使你的产品是垃圾。营销制胜。

      编辑:我经常使用 Tailwind。最近,我在一个 Next.JS 项目中将 v3 升级到了 v4,这本是一件不费吹灰之力的事,结果却耗费了四个小时。我不能花那么多时间只为确保 “background-color: red”(背景色:红色)仍能正常工作,这简直太滑稽了。因此,我正在从我的项目中删除它。

      1. 我也是这么想的,直到我真正试用了 tailwind。现在我真的很喜欢它。

        不过和其他东西一样,它也有优点和缺点。尝试对基本组件进行样式设计是非常痛苦的。比如想象一下你公司的主要 “按钮 ”元素。它有 8 种不同的尺寸、两侧的可选图标、动画、样式,每种都需要支持不同的颜色组合。Tailwind在这方面做得很糟糕。你的按钮上到处都是巨大的意大利面类球,让人难以理解。

        但是,对于 “胶水 ”样式来说,它简直太神奇了。把这些组件放在一起,给它们留出间距,甚至制作没有很多条件属性的简单组件?这真的很棒。你可以直接从标记符中快速、一致地创建样式,不必为每一个小东西都考虑类名,而且只需看看 jsx,你就能想象出东西的样子。

        我还记得它流行起来时的疯狂炒作,它真的让我望而却步。很长一段时间我都没有尝试过。现在我的代码库里没有它,我很怀念它!我不是非常怀念它,但它是一个不错的 QOL 升级。

        1. > 你可以直接从标记符中快速、一致地创建样式,不必为每一个小东西都考虑类名,而且只看 jsx 就能想象出东西的样子。

          我还是不明白它比在元素上放置 style= 任何东西要好在哪里。

          1. > 我还是不明白,在元素上加上 style= whatever 会带来什么。

            你不能为暗色模式和亮色模式分别设置一个样式。将这些属性从样式移到类中,可以将它们与媒体查询和状态结合起来。

            1. 在我看来,父母的评论者并不主张这样做。

              他们说

              > 想象一下你公司的主 “按钮 ”元素。它有 8 种不同的尺寸、两侧的可选图标、动画、样式,每种都需要支持不同的颜色组合。Tailwind在这方面就惨了。你会在按钮上看到巨大的意大利面类球,而且非常难以理解。

              在我看来,他们也不会用 Tailwind 来处理暗模式/亮模式的事情。但我可能理解错了

            2. 听起来你是在说,我们需要考虑类在反映具体呈现之外的考虑时所具有的灵活性和衔接性。

          2. 就在今天,我帮助了一位大三学生,他问我如何才能移动工具栏上的按钮。他正在与一些使用 JSP 制作的传统网络应用程序作斗争,这些程序几乎在所有地方都使用了样式=“XXX ”的东西。最糟糕的是……几乎所有东西都使用 “position: absolute ”来布局。

            试着维护一下那个恐怖的网络应用程序吧。

            PD:那个网络应用程序被前同事称为 “技术破产”。

        2. > 想象一下贵公司的主 “按钮 ”元素。它有 8 种不同的尺寸、两侧可选的图标、动画、样式,每种都需要支持不同的颜色组合。Tailwind 在这方面就惨了。你会在按钮上看到巨大的意大利面类球,而且非常难以理解。

          .brand-btn {}

          .brand-btn–inverted {}

          .brand-btn–icon-right {}

          .brand-btn–smaln {}

          .brand-btn–smaller {}

          .brand-btn–big {}

          <button class=”brand-btn brand-btn–icon-right brand-btn–small brand-btn–inverted” />

          不过,很少需要太多带有品牌徽标的相同按钮组合。

          1. 我们的开发已经离不开组件了。

            你可以拥有一个包含所有情况、类型安全的漂亮组件,并应用一些实用类来生成更易于维护的代码。

        3. 如果你为元素设计了很多 “自定义 ”样式,为什么不能轻松编写一个 CSS 类并赋予元素该类呢?为什么 Tailwind 会更好?我不也是在 Tailwind 中编写定义,然后将这些类赋值给我的元素吗?我不明白这有什么好处。

          1. 这正是我为具有大量自定义样式的元素所做的工作!

            我想我没有解释清楚,但对于像按钮这样的东西,我使用的是普通的 css 模块。尾风则是所有的粘合剂。根据我的经验,你在开发功能时写的大部分 css 都是胶水。

      2. 同意。尾风是个可恶的东西。

        它最大的问题在于它是一个漏洞百出的抽象。这些类几乎能以 1:1 的比例转换成等价的 CSS,但并不完全如此,也不总是如此。最好的情况是,你使用一个实用类,而不用考虑 CSS。在最坏的情况下,您必须了解如何在 CSS 中实现该功能,以及 Tailwind 如何进行翻译。然后,你还需要考虑如何让 Tailwind 做你想在 CSS 中做的事情。

        所有这些都会在开发过程中增加大量的脑力开销。在最好的情况下,开发人员甚至懒得学习 CSS,最终导致知识停滞不前。如果一些初级前端开发人员甚至不了解 CSS,只是自称为 “Tailwind 开发人员”,我也不会感到惊讶。

        是的,所有的抽象都会将焦点转移到堆栈的更高层,但 Tailwind 令人不安的地方在于,它一方面假装自己是一个轻量级抽象(或者根本就不是抽象[1]!),另一方面却造成了混乱,并降低了人们对其抽象内容的认识。

        此外,在元素上看到几十个实用类也会让人抓狂,一不小心,每个实用类的外观和行为都会略有不同。我有很多次都想通过改变单个元素的边距值来解决某些问题。这让我想起了几十年前我们用过的“ `”和单像素 GIF 间隔黑客。声称可以解决这个问题的方法是组件,但有时并不合适,或者将实用工具类组合到一个类中,但那我为什么还要使用 Tailwind 呢?还有像 DaisyUI 这样建立在 Tailwind 之上的库来解决这个问题,但一想到要在这个简易塔上堆砌更多的抽象,我就不寒而栗。

        我可以理解为什么不是优秀设计师的开发人员会觉得它很吸引人,也可以理解它在原型设计时有多有用,但在这两种情况下,使用纯 CSS(如果必须的话,还可以使用一些预处理器)从长远来看更易于维护,对开发人员也更有利,只是在短期内会稍显不便。

        [1]: https://news.ycombinator.com/item?id=33787346

        1. >所有这些都会在开发过程中增加大量的精神开销

          我的经验并非如此。

      3. 很长一段时间,我也不明白这一点。我是在一个项目中真正尝试过之后才喜欢上它的。的确,它的大部分功能与编写内联样式相同,但它也比内联样式更强大。下面是我喜欢它的几个方面:

        – 在 “内联样式 ”中使用伪选择器等功能

        – 可用于 padding、margin 等的一组有限的预定义值,使其更容易保持一致

        – 一些有用的实用工具,如漂亮的阴影和动画

        当然,我可以用不同的方法实现所有这些功能。虽然它没有什么突破性或独特性,但对我来说是一个很好的软件包。

        1. > 有限的预定义值集…

          有了预定义 css 常量的功能,我想现在可以直接使用样式道具,而不必使用原始的十六进制颜色和像素值(例如,有一些 css 库包含这些 https://open-props.style)。

      4. > 最近,在一个 Next.JS 项目中,从 v3 升级到 v4 本应不费吹灰之力,结果却耗费了四个小时。

        你可能会觉得时间太长了,但迁移 IMO 所需的时间并不长。

        我现在要处理的是样式组件、SCSS 和全局样式的混合。4 个小时甚至还不够处理其中的一半。

        比起这些乱七八糟的东西,我更喜欢 TailwindCSS。

        1. 我认为,在优秀的前端软件仓库工作过的人和在糟糕的软件仓库工作过的人之间存在差距。我曾开发过一个应用程序,它混合了样式组件、SCSS、内联样式和全局。它简直就是个废墟,每次更改都要花更长时间,因为你不得不吃掉所有的意大利面造型。

      5. > 编辑:我经常使用 Tailwind。最近,我在一个 Next.JS 项目中将 v3 升级到了 v4,这本来是一件不费吹灰之力的事,结果却花了四个小时。我不能花那么多时间只为确保 “background-color: red”(背景色:红色)仍能正常工作,这简直太滑稽了。正因为如此,我正在从我的项目中删除它。

        最后一句话中的 “它 ”指的是什么?是 Tailwind 还是 Next.JS?

        不管怎么说,确保背景颜色仍然有效,这是 Tailwind 的一个论点吗?这不正是正确使用标准 CSS 的好理由吗?

        1. >> 我一直不明白 Tailwind 的魅力何在?

          他们不是在为 Tailwind 争论。他们用过 Tailwind。

      6. >营销获胜

        我知道我只是被操纵了,我对使用它的喜悦其实只是无知。很高兴知道这一点。

    7. daisyui 不正是我们在尾风事件出现之前所做的吗?我们现在是否又绕了一圈,需要一个完整的插件来处理这个问题?

    8. 每当我看到有人把 Tailwind 说得像灵丹妙药一样时,我都会露出奇怪的表情。因为这样写 HTML 标签的样式属性看起来很奇怪。这是必须避免的。

    9. 我认为要想在用户界面设计方面达到 70% 的水平,使用 tailwind + daisyui 就可以了。如果您需要拥有绝对一流的用户界面,就必须从头开始了解 CSS。

    10. 谢谢您的帮助。

      > 而且,如果你确实了解一些 CSS,那么更上一层楼,学习如何编写可扩展的 CSS 并不难。

      我愿意相信。

      我懂一些 CSS,也会写 SCSS。但要达到下一阶段似乎很难。

    11. “CSS并不复杂。它是为 HTML 元素设计样式的好方法”。

      人类的思维是相对的。因此,告诉他们 CSS 取代了什么可能会有所帮助。

      HTML 有许多结构:文本、图片、链接、表格、分隔等。我们必须在程序化生成的布局中为它们设计样式。我们需要学习图形用户界面或 2D 图形引擎。我们可能要学习多个引擎,使用有限制的跨平台引擎,或者自己编写引擎。我们一度需要像 Flash 这样的本地扩展。

      即使是经验丰富的程序员,学习所有这些也是很困难的。而许多普通程序员学习 CSS 却相当容易。然后,通常只需对其进行调整,直到它能正常工作。此外,与测试自制的图形用户界面相比,浏览器能让修改周期变得快速而简单。

      因此,在大多数情况下,这无疑更容易。这并不总是最好的。但它是 HTML 的一个很好的基准。

      1. 我的经历恰恰相反: 我很容易就掌握了基于 HTML 的网页设计,但当 CSS 出现时,它就变得非常棘手,我总是无法让它可靠地完成我想要的功能。所有的东西似乎都被无形的弹簧连接在一起,因此,如果你对某样东西的呼吸有点奇怪,其他地方就会发生不想要的事情。最后,我彻底放弃了网页设计,不再继续与 CSS 作斗争。

        使用传统的HTML布局,我只需写出一个文档,就可以合理地期望它看起来是正确的:但使用CSS是一个令人沮丧的、不断尝试和犯错的过程,通常情况下,改变我的设计以适应CSS愿意做的事情,要比在无尽的副作用中挣扎,试图实现一些用表格很容易做到的事情要容易得多。

        1. “我很容易就学会了基于 HTML 的网页设计,但当 CSS 出现时,它就变得如此棘手,以至于我始终无法让它可靠地实现我的愿望。”

          确实如此。它很容易学。它很容易做简单的事情。但在很多情况下,它太难以预测了,在这些情况下可能需要使用其他布局。然而,这些都需要在执行第三方代码的基础上进行实际编程。

          无论好坏,他们通常都会选择简单安全的方式。

    12. 与 15 年前相比,今天的 CSS 拥有更多的功能,但在我看来,它更容易掌握。

      那时,CSS 的实现有更多的怪癖,你必须把所有这些都记在脑子里。在 Firefox 中,CSS 属性的组合以一种方式工作,但这并不意味着它在 Internet Explorer 中也能以类似的方式工作。

    13. CSS 虽然作用不大,但却过于复杂。你必须学会它。相比之下,我在做安卓开发时,从来不需要 “学习 ”他们的 xml DSL 是如何工作的,主要是 “just work ”tm。

      Android 有约束布局,而 css 现在已经到了第 4 级,但仍然没有约束布局,它至少有 5 种重叠的布局机制。我想,如果你是一个代码诗人而不是工程师,更多的选择总是有趣的。

      CSS 在设计时没有考虑工程师的意见,而现在主要是(前端)工程师在编写 CSS。没有模块系统,与网络堆栈其他部分的集成是通过 API 实现的,这让人感觉很偶然,比如 class=? <link>?、var(–?)、居中……

      别跟我提什么 css 框架,为什么在网页上设计样式要花费这么多功夫,而在其他平台上设计样式却几乎没有任何认知负担?

    14. > Tailwind 只是一系列预定义的实用工具类,你过度使用这些类,就会破坏一些简洁的代码原则。

      我的意思是,如果你说的是清洁代码这本书,我认为 Tailwind 在 “过度分解 ”这部分做得很好。

    15. 是的,这与我的想法不谋而合。我会去看看你关于 CSS 的网站。根据我的经验,当我需要使用 CSS 时,我当然需要查找操作方法,但当我开始使用它时,就会发现用最少的代码就能让东西很好地运行,这让我很有成就感。我做了一个个人网站,完全不需要媒体查询就能响应。要求各不相同,但如果你能很好地掌握 CSS,不依赖其他东西来帮你做 CSS,你就能写出很好的模块化 CSS,而且还能正常工作。

      尾风页面并没有做到在任意宽度下都不会跳动的响应式布局。当宽度减小时,元素不是无缝浮动/移动,而是突然跳到下一个位置。这相当 “一般”,并不出色。我猜他们是在使用媒体查询。

    16. 菊花ui 不就是在做当年 bootstrap 所做的事情吗?

  2. 许多前端开发人员拒绝学习如何使用虚构 CSS 和 Javascript,而且不惜一切代价避免接触它们,这让我感到非常惊讶。我认为,很多现代网络工具就像开发人员穿上了一件巨大的机械战衣,与网络底层技术展开了激烈的斗争。在你和你工作的媒介之间存在着如此多的抽象层,你可以在整个职业生涯中都不学习如何自己创建一个网站。

    最初的理由是 “可扩展性”(这个词其实代表了很多不好的行为),因为你显然无法为一个大型网站编写简单的 CSS。但是,这种情况会逐渐减少,直到很快你的业余爱好网站变成一个 20 兆字节、有 500 个 NPM 包支持的 SPA。

    1. 使用 vanilla 协议栈构建网络应用程序从未如此简单。

      2010 年,对 DOM 进行抽象的论点令人难以置信。当时的浏览器千奇百怪,你别无选择,只能支持它们。十多年后的今天,我认为我们的世界已经完全不同了。如今,唯一让我头疼的浏览器是 Safari,但与我们过去使用的浏览器相比,它简直就是小巫见大巫。

      谁能适应新的现实,谁就能超越那些继续用生锈的旧训练轮蹒跚前行的人。

    2. 与任何职业一样,大多数工人只是精通他们需要做的事情。那些在网上大肆评论 Tailwind 如何 “够用 ”的人,说的可能都是他们的亲身经历。很多网络开发人员并没有与设计师合作、按照视觉规范实施软件的专业经验。

    3. 我认为你没有抓住重点。

      让 25 名开发人员一起管理 CSS 样式表,同时命名类并不合适。

      而让 25 名开发人员不必担心 Tailwind 会踩到其他人的脚趾,则更有说服力。

      简而言之 CS 中最难的问题是什么?命名。尾风最大的特点是什么?构建一个最小化命名需求的前端。

      1. 25个开发人员在同一个模块工作?没有共同的风格?

        据我所知,我们是从纯 CSS -> BEM 开始的,因为样式的范围很难界定,所以人们找到了一种命名规则来隔离样式。CSS 中并不存在样式范围。

        然后,我们从 BEM -> Tailwind,因为手工确定样式范围有点困难(?)

        然后我们就有了 Tailwind -> Tailwind + DaisyUI,因为 Tailwind 会导致混乱的具体化。

        ——–

        我的问题是:现代 css 中的模块化/范围界定原语是否已经足够好,从而使 Tailwind 等过时了?

        我们还在使用 Tailwind,是因为人们不理解最初的问题吗?

        也许有人能给我一些启发。

        1. 从纯 CSS 到 BEM,或多或少意味着要放弃 CSS 中的 “级联 ”部分。在过去的 15 年里,我们基本上都是直接对标记进行样式化处理,并在不同的策略之间来回切换,以尽可能最有效、最美观的方式来实现这一目标。

      2. > 不能缩放

        CSS 已经有了 @layer;@scope 也即将推出(正在等待 firefox)。

        还有像 bem 这样的命名约定。还有一些工具可以保证类名的唯一性(css 模块、各种 js 框架中的 “单文件组件”)。

        有一些设计系统可以标准化并减少 CSS 的用量。

        还有网络组件,其样式封装在阴影 DOM 中。

      3. > 25 名开发人员共同管理 CSS 样式表

        和 25 名开发人员共同管理一个 React 组件相比?我认为这也不可行。

        1. 因此,公司才会采用用户界面工具包,否则就会一团糟。如果没有纪律,就很难开发出一套核心组件,而且很多时候开发人员会重复工作,无法提取出共同的部分,这是因为他们需要跨堆栈开发功能,无法识别共同的模式。

          1. 我的意思是,你可以使用语言特性将关注点分离成易于管理的部分(CSS 和 TypeScript 一样可以做到这一点)。

            Tawilwind 诞生的时候,我们还沉浸在 IE 时代,Triton 还是个东西,人们通常需要查找重置或如何设置工具来帮助他们处理供应商前缀(那是在 Interop 出现之前),等等。在此期间,设计人员会将单个的设计代币(如按钮、组合框等)交付实施。像 “样式化组件 ”这样的东西让人感觉如释重负,因为 “哦,我可以对按钮进行样式化,而不会破坏整个网站”。

            从那时起,所有这些摩擦点都得到了改进或被一并移除。如果我们重新审视这个平台,看看如何在不默认采用尾风的情况下获得尾风的所有好处,我们就不会有任何损失。

            顺便说一句,同样的论点也可以用在 React 和重新审视现代 DOM 功能上。

            我想,过去为解决实际问题而诞生的所有框架都有一个共同点–一旦对它们的基本需求消失,我们往往会忘记淘汰它们。

      4. 究竟为什么会有 25 位前端开发人员在同一个样式表中编辑相同的类?

        1. 12 年的老项目,每年 2 名开发人员,每年都有人员流动。这就够了。

          1. > 25 名开发人员一起管理 CSS 样式表

            您的评论表明,您指的是 25 名开发人员同时工作

            每年 2 名开发人员就能轻松维护一个连贯的样式表。

      5. 不过 CSS 模块早在几年前就解决了类名碰撞问题。

        1. 当人们说 “CSS 模块 ”时,我从来不知道他们指的是哪个模块。CSS 规范中有一项功能是 “导入”。还有一系列具有不同行为的 webpack 插件。CSS 模块,我们曾多次通过各种权衡解决了这个问题。你甚至可以在同一个代码库中使用多种 CSS 模块。

      6. 非常同意,我从一开始就写 Tailwind。我喜欢它的这一点:清除、JIT、任意值,而且你还可以随时编写纯 CSS。我曾将 Tailwind 用于大型 FAANG 网站和精品店。两者的效果都很好,规模也很大,而且非常容易定制。

  3. 我正在分叉 Shopify 的 polaris-react 库供我个人使用,其中的一些组件显然是为那些不知道如何使用 CSS 的人制作的。

    例如,有一个名为 “InlineStack ”的组件,它只是一个带有 flex 的 div 的 javascript 封装。这东西快把我逼疯了。

    1. 你忽略了 InlineStack 这样的组件中最重要的部分:道具 [0]。是的,你可以直接将 `display: flex` 应用到你正在处理的 div 上,但就像任何适当的抽象一样,这些保护机制使正确使用 flexbox 成为最简单的途径(“成功之坑”)。

      [0]: https://github.com/Shopify/polaris/blob/eb6161f6b4e02679b5e8

    2. 因为有时你只需要一个 flex 封装。而且在 JSX 中随处可见 InlineStack 比从混合 CSS 中解读布局更容易。虽然纯 CSS 将一些关注点从 HTML 中分离出来,但它也会将不同的关注点混合在一起,如布局、定位、间距、外观和感觉等。至少,像 Stack、Group、Flex 或其他结构性或实用性组件的意图会更加明显。

      1. 那就是你在页面布局和组件方面做错了。

        1. 所有现代 UI 工具包和 css 库都有实用工具类和容器组件,它们让我编写的代码可以重复使用并具有可组合性,这让我很开心。这比使用类作为 “钩子 ”来样式化标记,最终导致选择器嵌套到特定的目标元素要好得多。实际上,你可以将它与 HTML 相提并论,我使用 <stack> 就像使用 <table> 一样,而不是使用一些自定义包装器(如 <div class=“basketball-scores”> )来重新创造,这样做只是为了附加一个名称,以便我可以对其进行样式化。

    3. 这有点像 <center> 标签。如果代码库中充斥着 “InlineStack ”之类的东西,那么处理和解析工作就会变得更加困难,因为生成的 div 汤仍然需要额外的样式设计,而这些样式设计现在既是标记又是 CSS。

      1. 为什么会更难?它能让人一眼就看出组件的视觉布局和用途,而且很多时候,你只需在组件上添加一个 flex,而不需要其他 CSS 来保证另一个 CSS 类的存在。这也是实用 CSS 诞生的原因(例如 <div class=“flex”>)。此外,它还能让你不必在 CSS 中为每个包装器都起一个语义名称。

        请比较以下内容:

            <Stack gap={2} direction="row">
               <Box>
                 <Avatar />
               </Box>
               <Box>
                 <Button />
               </Box>
            </Stack>
            -----
            <MyCustomWrapper>
                <InnerChild>
                  <Avatar>
                </InnerChild>
                <InnerChild>
                   <Button />
                </InnerChild>
             </MyCustomWrapper>
        1. I think this looks way simpler

            <div className=“flex gap-2”>
             <Button/>
             <Avatar/>
            <div>
          

          然后使用 *: 选择器或直接在组件中应用框样式即可

    4. 使用 InlineStack 等组件的好处在于,组件的名称可以语义地描述其在布局中的用途。

      1. 这样造成的碎片化是不值得的,我们正在建造网络技术的巴别塔。如果你看看 “现代 ”网络应用程序,每个 html 组件都被改写成类似 “inlinestack ”这样的垃圾。

        1. 网络巴别塔建于 5 年前的 React 高峰期。随着 React 的衰落和安于现状,越来越多的竞争者悄然进入了网络领域,网络巴别塔的情况确实有所好转。

          虽然我理解看到 InlineStack 这样的东西时的直觉反应,但它和实用工具类并没有什么不同,只不过是在组件级别上进行了抽象,而不是在一堆不同组件中进行 CSS 级别的抽象。另外,这类组件还提供了一个超越网络的抽象层。如果我正在编写一个针对网页和原生移动平台的应用程序,我可以让编译器决定在构建时放置哪个版本,以利用平台的原生特性。

          当规模达到一定程度时,编程就会变得与保持规模的一致性有关,而与单个组件的工艺无关。作为一个喜欢编写 CSS 和手工构建布局的开发者,我理解你的沮丧,但这是对一群试图解决不同问题的开发者的误导。

          我们不需要实现 FAANG 在他们的 “创新实验室 ”里想出的所有东西,而且我百分百相信,在未来几十年里,手工代码在应用程序中仍有一席之地。但我们也不要忘记,台锯并没有取代手锯。它们为不同的受众提供不同的服务,这一点没有问题!

          1. 不是我迂腐,但我对这里如何使用 “巴别塔 ”的比喻感到困惑。在圣经传说中,巴别塔的缺陷在于它作为一个统一项目过于成功。这就是你所说的反应吗?其他评论的意思似乎恰恰相反。

          2. 别忘了,组件也会增加运行时的复杂性。

        2. 我个人更喜欢写 markdown 而不是 html,尤其是在这样的网站上写评论的时候。

          但我必须知道,星星代表 html 的斜体标记(以及其他一些东西)。

          幸好这已经标准化了,每个标记符解析器都知道星星代表什么意思。所以我只需要学习一次。

          大多数框架都没有标准化,这也是令人沮丧的地方。

          当抽象成为一种共性时,它就是好的,而当它仍然是小众的时候,它就是坏的。

      2. 为什么 InlineStack 比 FlexDiv 更有语义性?

        语义在某种程度上是任意商定和记忆的。

        1. 其实不然,FlexDiv 只是 Stack 的另一个名称,它们描述的是同一个方面。例如,你可以想象一个 CSS 库使用 Flex,一个使用 Group,第三个使用 Stack 来表达同一个概念,例如其他一些 UI 框架使用 VBox 和 HBox。但它仍然不同于 TopSectionHeader、SectionHeaderInner、SectionBodyWrapper 或其他任何你必须根据组件内容赋予其 “语义 ”含义的名称。

          1. > 根据内容赋予组件 “语义 ”意义。

            这是 Tailwind 最大的优点之一,因为它能引导人们摆脱这种错误的思维模式。在 “语义 ”周围加引号是正确的。令人惊讶的是,许多人在强调 “关注点分离”,将内容与表现形式分开后,转过头来又以内容命名表现形式。

        2. 因为 flex 只是引用布局引擎,而 div 故意没有语义意义。另外,我也不认为 InlineStack 是一个特别好的名字,但对它的批评需要更多的理由,而不仅仅是 “这不是我们过去的做法”。

          语义会随着时间的推移而演变。自然语言和编码实践都是如此。

        3. 现在我改用 <div class=“flex”><div> 了。

          如果类名不足以让我猜测,我只需悬停类名,LSP 就会显示应用的样式。

          另一个问题是,Shopify 会无缘无故地更改这些组件的名称,例如 InlineStack 曾被称为 Inline,后来又被称为 HorizontalStack,再后来又被称为 InlineStack,而 flex box 模型自 2012 年以来就没有变过。

          1. 命名很难,但我觉得一个类名引用一个 CSS 属性有些奇怪,因为它基本上是一种内联样式: <div style=“display: flex”></div>

            1. Not sure why it matters, <b> is the same as <span style=“font-weight: bold”>… If you want, name it “stack” or “vbox” instead of “flex”.

  4. 用于样式设计的 CSS 非常简单(这是有道理的,因为 “CSS ”是层叠的 “样式 ”表单)

    用于布局的 CSS 也需要一段时间的适应。

    对我来说,任何 CSS 框架的好处都不在于预先打包的样式,而在于简化桌面/平板/手机的布局。

  5. 对我来说,TailwindCSS 确实有助于我学习 CSS。你仍然可以应用相同的 CSS 核心基础。如果你在 Tailwind 中创建了一个复杂的布局,你也可以在普通 CSS 中完成它。我经常在他们的文档中查找类背后的确切规则。

    当然,如果你只是复制类而不去了解它们,那就另当别论了。

    1. 你没有应用相同的核心基础,因为 Tailwind 专门移除了 CSS 的核心基础:层叠。

      1. 我想是的,但就我个人的经验而言,这无疑是一种巨大的解脱。

        1. 是的,特异性战争让组件很难在大型组织的多个产品领域和团队中重复使用。

          css 基本原理指的是各种样式属性的作用。

      2. 尾风是如何去除层叠的?这只是 css 类而已。

  6. 前端开发的精髓在于理解 HTML 的语义。

    在我工作过的每一家公司,我都不得不教导人们不要什么都用 div 标签。你可以随心所欲地设计样式,甚至创建浏览器不允许你设计样式的组件(只要你有回退功能)。

    1. 我敲了一段时间的鼓,被忽视了,于是就放弃了。

      后来出现了可访问性诉讼,人们突然对每个标签背后的语义产生了浓厚的兴趣。

    2. 我见过把 div 想象成按钮的后辈,真让人沮丧。

      1. 我见过高年级学生做同样的事情。

        根本原因似乎总是一样的。

        压力太大,必须马上完成。将来没有时间纠正。当你试图把事情做得更好时,却因为落后于走同样捷径的同行而有可能被解雇。

        对于不关心正确做事的管理层来说,这始终是个问题。因此,保住工作的动力总是不正常的。

    3. > 我不得不教人们停止使用 div 标签来表示所有内容

      你能详细解释一下你的意思吗?

    4. HTML 有语义吗?实际上,你可以在任何地方使用 div,然后使用 CSS 使其成为你想要的任何组件。

      你应该让默认设置来完成它们的工作,但它们的作用并不大。HTML 的主要语义是赋予事物层次结构。从视觉上看,这之后就可以自由发挥了

      1. > 但它们的作用不大

        不不不,不同的元素有不同的行为。例如,一个按钮会自动具备无障碍功能,比如可以用 tab 到它,并用回车键选择,这对屏幕阅读器来说是必不可少的。

        如果你关心的只是视觉效果,那么当然没有什么区别,但一旦你从表面上看,如果不使用正确的元素,你的产品就会很糟糕(当然,这里有一个明确的 “正确”,但有时是主观的)。

        1. Svelte 5 很好地提出了这方面的警告。如果您尝试在 div 上使用 onclick,就会收到警告,要求您将其设置为可制表,并赋予其 aria 角色,同时建议您最好使用按钮。

        2. 这对键盘导航也很重要。无障碍环境不仅适用于有某些障碍的人!

  7. 如今,“了解 ”CSS几乎是不可能的。因为有太多的语言特点。别误会我的意思: 如今的 CSS 非常酷,几乎一切皆有可能(顺便问一句,Doom 能用 CSS 运行吗?

    1. 听起来你需要花更多时间来解决 CSS 方面的问题。所谓 “了解 ”CSS,是指无需查看任何资源或寻求帮助,就能为大多数东西设计样式。

      偶尔可能会有一个特殊问题需要深思熟虑或阅读手册,但任何足够复杂的设计系统都是如此,尤其是像 CSS 这样有生命力的规范。

      我建议大家在采用新功能时多加熟悉。例如,前端开发人员需要学习 Houdini。

      1. 我花了一些时间来解决 CSS 中的问题。你知道 90% 的情况下,业界/搜索认可的解决方案是什么吗?一些假定尺寸的油腻黑客,他们不会将其转化到其他地方,也不会将其归纳为经验。你刚开始知道如何制作 X 的单个 X,但 X 还是那么大。

        Css 是一堆低功耗的垃圾,专门针对网页设计师的临时问题。它可以制作首页,其他方面却一塌糊涂。

        1. 那是很久以前的事了,现在比 15 年前好多了。总之,我从来没有使用 “height: 0; padding: 100%;` 等等。但如今要获得好的效果,几乎不需要这些东西了。

          > 它可以制作头版,但在其他方面却很糟糕

          多年来,我使用 CSS 制作了一些非常漂亮的应用程序和小工具。CSS不是问题,缺乏想象力才是问题。如今,CSS 实际上已经涵盖了很多应用,而随着 Houdini 等应用的曝光,CSS 将很快成为应用的极限。

          1. 这种克服几乎就是 css 的精神,而在其他 gui 框架中,你只需要做事情。它们不需要想象力,只需要直观的几何图形。把它说成是很酷的东西,我也不知道该怎么说。

            1. 再说一遍,现代 CSS 与 15 年前的情况大不相同。

              1. 我看你对 CSS 很有信心。也许你能帮我完成一个简单的任务,我最近正为这个问题苦恼。(有一大堆这样的问题,但这个很新鲜)。

                有一个带有 grow-1 容器的 flex-row-wrap 根。每个容器都是一个网格,有两列:适合标签、自动控制。从视觉上看,这是一排自动调整大小的表格。有时,我想在控制列中放入一段较长的文字,例如,作为对前面输入内容的描述。但它会参与大小请求,并使其网格扩大,占用灵活行的所有空间,甚至更多。我希望它请求的空间为零,就像它不存在一样,但要占用其他 “控件 ”收到的空间。

                在 15 年前的一个非网页库的适当盒式模型中,我会将文本的 “尺寸请求 ”宽度设置为一个较小的值,并将所有控件列元素放入一个尺寸组中。这样,它们都会请求相同(最大)的宽度。尺寸请求-分配循环的可预测性使其变得微不足道。

                我希望能对网格、控件、柔性根等进行某种临时限制。这是个反驳我、激发我想象力的好机会。

    2. 知之为知之,不知为不知。

      我并不假装了解 typescript 的每一个黑暗角落,对 CSS 也是如此。但了解足够多的细节,以便高效编写可维护、易扩展的代码,这一点很重要。

      不要让完美成为优秀的敌人。

    3. 我认为,知道该问什么、该去哪里找,就代表掌握了 CSS。

      了解 Flexbox 等东西的大致威力,并具备一定的审美品位,这才是战斗的关键所在。你必须愿意动手。CSS 几乎完全是一门艺术。找出最适合你的画笔和技巧。可行的途径有很多。

      1. 那是以前,现在它是一个 3D 引擎。

        1. 不,它有一个 3d 引擎,你可以在 99.9999% 的情况下忽略它。CSS 有一些问题,有一些需要理解的地方(选择器、选择器优先级以及内容在绝对/相对位置下的流动方式),但它并不是一门不可能掌握的语言,远非如此。

          正如祖父母所说,不要让完美成为优秀的敌人。

          1. 我的问题是,有了它,我就想用它。

    4. 读完 mixu/cssbook 后,我觉得自己对 CSS 的了解和理解已经相当透彻了。但那是 10 年前的事了!每个新功能都会带来新的边缘情况,这些边缘情况会与所有现有的边缘情况相结合。再加上 WebComponents 这样的功能,就会出现太多未定义的行为。

      1. 你在使用 CSS 时遇到过哪些未定义的行为?

        1. 表格和 Web 组件与网格或 flex 相结合,就会产生神奇的效果。

    5. 我曾一度了解 css,但它却离我而去,远远地嘲笑我。

    6. 与 JavaScript 相比,CSS(CSS 语言)现在有多少功能?

      各种 API 总共有多少功能?

      CSSOM、SVG DOM、HTML DOM、Shadow DOM……各种对象模型有多少特性?

      与 CSS 功能相比,你对所有这些功能的了解有多少?

      跳出这个问题,去看看任何成熟的语言和 CS 学科,你可能 “完全了解 ”的东西太多了,但当然有可能 “知道 ”如何正确使用它的一般论点,一旦知道了这些,单个的东西就只是查查语法而已。

      1. 好吧,显然有人认为所有这些东西都比 CSS 更容易掌握,这实在是太可笑了,所以给了我一个降票,让我知道他们不赞成我的观点。

        非常经典。但不是 CSS Classy。

        1. 我不会对网上的 “降权 ”过于纠结,如果不考虑蓄意的恶意行为者,“降权 ”的理由可以从 “这个人发布了仇恨犯罪 ”到 “其他人已经发布了与此足够接近的内容”,甚至是 “这个人给出了一个完全正确的答案,但感觉并没有把讨论引向我觉得应该去的方向”。

          1. 我知道,只是偶尔觉得特别奇怪,才会发表评论。此外,它也非常快,就像我说了什么冒犯性的话,需要被扑灭一样。)

    7. 在这个法学硕士和人工智能的时代,掌握 CSS 的动力更低了。

    8. 这些玩笑虽然轻松,但必须停止。在这里尤其如此。

    9. 我认为doom()函数仍在各大浏览器中推广。我记得较新版本的 Chrome 浏览器已经实现了这个功能。

  8. 老实说,我觉得它比 CSS 更进一步。人们很少谈论 HTML,可能只是因为它不像 JS 框架等变化那么大。但这并不意味着你应该完全忽略它,只使用一堆 div!

    当你开始深入研究所有不同的 HTML 元素和 aria 准则(例如,`<nav />` 和`<menu role=“menubar” />`之间的区别)时,我认为开发工作开始变得更加清晰,因为你开始明白你的工具应该如何使用。我认为这也会让 CSS 样式的决策更加清晰。另外,你的代码也开始变得更容易访问,这很好。

    https://developer.mozilla.org/en-US/docs/Web/Accessibility/A

  9. 这就是我完全转向 flutter 的原因。所有的东西,包括样式,都只是一个小部件。编写看起来枯燥乏味的 C# 代码,准确描述 UI 组件,而不需要继承、重载、样式编译等,这真是出乎意料的自由。

    1. 它还摒弃了 HTML,将所有内容都放在画布上,这意味着三件事:

      1. 可访问性现在成了事后考虑的问题

      2. 每个网站都要下载巨大的运行时

      3. 手机上令人困惑的非本地行为

      1. 关于运行时,我同意你的看法。有了 wasm 和 wasmgc,情况会好一些,但你仍然无法在任何注重搜索引擎优化的网站上使用 flutter。

        不过,“应用程序 ”部分(登录后)是一次性下载,由服务工作者缓存,只需一瞬间。

        如果 flutter 能为初始页面生成一个 AOT 的 “语义 ”HTML 编译,然后将其水合物化,那就更好了。这样就和等待 JS 捆绑包进行交互非常相似了。

        1. 我的主要不满是 DOM 后端从未起飞。WASM <-> DOM 互操作比以往任何时候都便宜,尤其是如果你捆绑操作,就不需要经常交叉操作。不过,他们还是决定一切从头开始 🙁

    2. 我也一样,作为 C# 开发人员,我喜欢 Flutter。但我从骨子里知道,谷歌总有一天会放弃它。它已经有很多年没有被广泛采用了,而且总有一天它在企业电子表格中也会失去意义。

      1. 至少根据最近 HN 上的这篇文章,Flutter 没有得到广泛应用只是一个神话:https://shorebird.dev/blog/dart-macros/#:~:text=Flutter%20ha…

    3. > 包括造型在内的一切都只是一个小部件。

      这就是缺点。 在 HTML+CSS 中,原本只是两三个嵌套的 <div> 变成了几屏的 widget,使得导航和调试变得更加困难。我曾经遇到过 Flutter 内置部件中出现额外边距的问题,我花了几个小时试图找出原因,但没有成功。

    4. 你好,我是 C# 开发人员。能否请您详细介绍一下您是如何使用 flutter 和 C# 的?

      1. 我想他的意思是 Dart 代码与 C# 非常相似。

    5. 基本上,这就是闪客当年统治世界的原因。

  10. 在 Tailwind 和 LLM 这两代产品之间,我怀疑自己今后在任何项目中手写的 CSS 行数都不会超过几行。对我来说,CSS 就像我使用的编译器的 ASM 输出一样。对我来说,99.999% 的情况下都能得到很好的结果,而我却希望在更高的抽象层次上工作。

    1. 有趣的是,我输入 CSS 比向法学硕士描述我想要什么样的布局和外观要快得多。

      1. 我发现法律硕士最适合创建模板,或者填补我的知识空白。例如

        1. 使用 “使用 Tailwind,创建一个三栏布局,主要内容位于中间一栏,辅助信息位于两侧较小的一栏 ”这样的提示,生成 HTML + CSS 的速度比我打字的速度还快。

        2. 我使用 LLM 生成了一些用于设置背景模糊的 CSS 样式,这是我在使用 Tailwind 之前从未做过的事情。它创建代码的速度比我在文档中找到东西的速度还要快,尽管我后来不得不去修补它。总之,它为我指明了正确的方向。

        如果我在看预览版时想改变某个元素的样式,直接自己编辑通常比让 LLM 来做更快。Tailwind 能让这一切变得更快,因为 CSS 就在 HTML 上,我不必在样式表和 HTML 之间切换。

        1. 1. 无论我使用的是什么框架(现在是 bulma),我通常都会去文档的网格部分复制粘贴示例,然后在完成足够多的页面后复制粘贴我自己的代码。

          > 由于 CSS 就在 HTML 上,我不必在样式表和 HTML 之间切换,因此 Tailwind 可以让这一切变得更快。

          我主要使用网络检查器进行实时编辑,以获得感觉,然后将最终结果复制到工作表中。对于更复杂的组件,我使用 Codepen。

    2. 被降权的评论是正确的。在过去几年中,我使用 CSS 的唯一目的就是调试克劳德无法解决的问题,以及删除多余的、没有应用到任何地方的样式。

      它为我提供了灵活性、准确性和可扩展性,并经受住了时间的考验(3 年来一直如此)

  11. 哇,这里有这么多讨厌 CSS 的人。我喜欢 CSS。我第一次学习 CSS 大概是在 1999 年。当然,从那时起,CSS 已经变得更加复杂(也更加强大),它也有很多怪癖,但并没有那么糟糕。

    最近,我用 vanilla Javascript 和 CSS 构建了一些简单的网站和小型网络应用,没有使用任何框架,感觉比几年前要愉快得多。

    1. > 最近,我用 vanilla Javascript 和 CSS 构建了一些简单的网站和小型网络应用程序。

      有公开链接吗?

      1. 例如,请参阅:https://atlas.internationalbrainlab.org/

        除了基于 Unity 的 3D widget 之外,全部使用 vanilla Javascript、HTML、CSS 和 SVG。

  12. 在这一点上,如果你知道盒模型是如何工作的,以及 margin 和 padding 之间的区别,你就领先于 50%的 “前端开发人员 ”了。

  13. 我同意。但我觉得,如今要在前端开发领域找到一份工作,了解 CSS 并不是必要条件,而了解 React/Next/Vue/whatever 框架才是必要条件。

    1. 我们的想法是,只要了解 HTML 和 CSS,就能知道如何使用任何框架。既然它们是每个前端开发人员都应该掌握的基础技术,那么框架就应该建立在它们的原则之上。

      这一点对于 React 来说并不适用,因为他们只是决定做自己的事情,但对于 Svelte 等框架来说,这是他们努力坚持的核心原则。

      1. Svelte 是我遇到的唯一一个真正解决前端臃肿问题的框架,我很喜欢它。

    2. 在招聘时,我总是优先考虑对 HTML/CSS/JS 有深入了解的开发人员,而不是任何框架。

      如果你了解这门语言,你就能以最小的代价使用这门语言中的任何框架,而能够排除潜在问题的好处更是无价之宝。

    3. 我看到的大多数职位描述中都有 HTML/CSS。入门级职位至少需要这些语言和 Javascript。如果你三样都会,你的胜算会更大。

      1. > 我看到的大多数职位描述中都有 HTML/CSS。

        你看到的几乎所有 FE 职位描述中都会有这些内容。我认为,OP 的意思是,尽管它们自动出现在职位描述中,但它们并不是找到工作的必要条件。

        (就我个人而言,我工作过的公司要么没有 CSS 专家,无法对他们的掌握程度进行充分测试,要么在面试过程中不包括这些专家。或者,更常见的情况是,我们太需要框架开发人员了,只要懂 CSS 就足够了。)

  14. 这里的评论让人想起我们在这个论坛上一再听到的 “Git 并不难理解 ”的自谦,周围是一片真诚而合理的批评声。

    如果很多人–聪明人–抱怨无法理解你的产品,那么你的产品就很难理解。为什么是重要的问题。

    1. 可用性是一个问题,在某些事情上是可以改进的,但有时是人们不愿意阅读手册,而是整天追逐抽象概念。由于缺乏对基础知识的理解,他们一遇到无法解决的边缘情况就会放弃。

    2. 这并不意味着产品坏了。有时,智慧是自己最大的敌人,因为你会认为自己可以轻松理解某件事情,甚至无需正确学习,因为它看起来非常琐碎。大多数软件开发人员就是这种情况,他们试图将其他语言的心智模式套用到 CSS 上,然后期望它能以同样的方式运行。心智模型不匹配的情况并不少见,尤其是在 “聪明人 ”身上,因为他们并不总是认为自己的理解可能是错误的。

      对我来说,CSS 最大的问题在于它的教学方式、学习方式以及围绕概念的心智模型。大多数人对底层系统的工作原理有着不同的心智模式,这种不匹配导致开发人员极力按照自己的意愿使用 CSS。

      CSS 可能是好的,也可能是坏的,还可能有更好的替代方案……但是否有任何实际的改变可能很快发生,以至于我们不再学习和了解 CSS 如何工作?即使我们有了一种新的语言,人们也会试图像以前使用 CSS 那样使用它,所以那些聪明人可能会重蹈覆辙。

      无论我们喜欢与否,我们都会被 CSS 困住。我从 2001 年开始编写 CSS,它取得了长足的进步,但仍有许多事情仅靠 CSS 是无法轻松完成的。但这仍然是我们目前所拥有的唯一工具,要想让它变得更好,或者做出更好的替代方案,我们必须先了解它是如何工作的,然后才会说 “我需要一个新工具”,因为新工具也可能存在同样的问题。

  15. CSS 并不是性能瓶颈。

    CSS 也不难。在我看来,Tailwind 绝对是无稽之谈。

    要么写一些简单明了的好 CSS,要么使用已经完全不需要 tailwind 的带 scope css 的框架,要么使用 JavaScript css 属性(性能会略有下降)。

    性能问题是由于使用了繁重的框架、未优化的图片以及 1000 个广告和跟踪器造成的,而这些都是无人要求的(当然,管理部门除外)。

  16. Css 是个垃圾 api。设计风格不应该这么难。由于技术欠账,我们不得不使用它。这就是当今大多数网络技术的现状。

    1. 基础设施也是如此。

      我认为任何理智的人都不会让 “提示工程师 ”接近他们的 Terraform/OpenTofu/Pulumi/$OTHER 代码。

      给依赖 LLM 的人写权限(就像 “没有它几乎什么都做不了”)是灾难的根源。相比之下,即使给一个初学者写权限也没那么可怕。

      1. > 依赖法学硕士(“没有法学硕士几乎什么都做不了”)的人

        这让我对软件开发的未来感到担忧。即使在这个主题中,你也会看到有人说他们 “不写 css,让人工智能来写”。我不认为自己能在一家开发人员不懂语言,只是让聊天工具po出代码块直到能用为止的公司工作,但我们现在看到的正是这种情况。更糟的是,他们还以此为荣。太可怕了

        1. 具有讽刺意味的是,我觉得这些程序员在近期/中期内实际上正面临着被 LLM 代理取代工作的风险。

          1. 我并不责怪开发人员将 CSS 视为人工智能生成的目标语言。

            大多数网站都是 CRUD。除非他们正在开发一个需要创造性造型的网站,否则人们只想尽快完成工作,解决 “真正 ”的问题。

    2. 相反,我发现推理模型(主要是 DS R1)在复杂的定位和过渡问题上非常出色。它们无法 “可视化 ”任何东西,所以除非你能很好地解释它们,否则无法很好地进行设计(这正是设计中的问题所在,大多数人都有模糊的想法,但却无法用 CSS 术语很好地解释它)。

      1. 如果你能用 CSS 解释清楚,还不如自己写呢:)

    3. 如果网络采用 xhtml 路径就好了。

      1. 如果 XHTML 除了在 <img> 中添加毫无意义的反斜线之外,还能改变什么的话…

  17. > 对我来说,主要原因是不同的:如果不了解语言的底层机制,就无法成为前端开发高手。

    任何范式都是如此,不仅仅是前端。

    1. 当然,但这种说法过于笼统。开发人员不明白的是,CSS之所以如此与众不同,是因为它是一种表达设计的语言,而他们并不了解设计的基本原理。 几乎所有的编程语言都与逻辑有关,所有的计算机科学/编程学校都会教授这些知识。但设计大多不是这样,而且比人们想象的要复杂得多(例如网格理论)。

      1. 几何图形,在大多数情况下都是高中水平,但在第三(Z)维度中与级联相结合。引入具有自身坐标系的 “相对 ”坐标系,然后在其中进行变换(公平地说,只有在某些情况下才会比较复杂,比如变换后的父坐标系与相对父坐标系不同)。然后进入时域进行转换。这毕竟是数学,但与大多数编程课程教授的内容不同。

      2. 这是对逻辑与设计的一个很好的观察。你有推荐更多设计理论的资源吗?

        1. 肯定是这本 https://www.amazon.com/Grid-systems-graphic-design-communica… 但也可以是任何其他关于设计和架构的好书。

          设计有两个方面,一个是实践(绘图、记录、调整),另一个是思考(实际问题是什么以及解决问题的概念,这将为我提供一个选择框架)。关于解决正确问题的内容很多–请查看 IDEO 提供的资源,或者从更广阔的视角去看 Don Norman,例如 https://www.amazon.com/Design-Everyday-Things-Revised-Expand

          此外,不要忘记排版基础知识,因为大多数网站、应用程序和文档大多只有文字,有很多这方面的教程。

    2. > 如果你不了解底层机制,就无法成为大师。

      我想我曾经在幸运饼干中得到过这句话。

  18. > 输入框的自定义图标?出于保护隐私的考虑,在某些情况下添加一个伪类并不容易。

    到底是什么隐私原因?输入框的自定义图标是指用 svg 等代替光标吗?

    1. 我唯一能想到的是它们是否是第三方图标?我也不明白。

      1. 问题在于 css 不允许在输入字段中添加伪元素(:before/after),这使得在输入中添加图标比添加其他元素更麻烦。

  19. CSS 是一种不需要完全了解也能变得非常有效的东西。我真的不认为你需要全部了解它。

    我还认为它有很多你并不需要的工具。不要疯狂地使用选择器!

  20. 无论好坏,自从 Tailwind 发布以来,我一直在使用它。我甚至不确定自己是否还记得中级到复杂的 CSS。有更好的地方可以消磨时间。我真的很感激这个团队所做的一切。

    1. 它还不是标准。它的行为是在实现过程中定义的,还不够规范。很多人都用过这样的东西[1],但这个[2]已经走上了标准轨道。在第一个[2]的文档中,它描述了一个默认的 “文件范围”,但实际上并没有定义什么是文件。它似乎指的是源文件的预编译/捆绑,但实际上并没有说明。这应该属于某些框架的文档,而不是网络平台的东西。

      本地范围样式的想法相当流行。比如 vue 的单文件组件,以及 n+1 种不同的 “CSS 模块 ”实现。但它真正需要的是标准化。像 [2] 和即将推出的 @scope 就能实现这一点。

      [1]: https://github.com/css-modules/css-modules/blob/master/docs/

      [2]: https://github.com/WICG/webcomponents/blob/gh-pages/proposal

      1. > 在第一种方法的文档中,它描述了默认的 “文件作用域”,但实际上没有定义什么是文件。

        这可能是因为,如果你不知道文件是什么,你需要先学习的东西还有很多。这是一个最基本的基础知识,远远超出了 CSS 的范畴。

        但范围确实是事实–CSS 模块喜欢假装 CSS 只在特定的地方使用,并掩盖某些 CSS 属性会级联到所有子代的事实。@scope,特别是 @scope 的下限部分,可以解决这个问题。

        1. 你忽略了我关于文件的观点。浏览器通常不会以他们所说的方式查看文件。这不是网络标准。它是针对特定捆绑包或构建工具的。

  21. CSS 仍是受虐狂的一团糟,应该被取代

    1. 如果我们要替换它,替换后会有哪些改进?

    1. 怎么说?我觉得完全不是这样。

  22. 掌握 Css,然后让人工智能来做。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注