阿里、蚂蚁、晟腾、中科加禾精彩分享 AI 基础设施洞见,现购票可享受 9 折优惠 |AICon 了解详情
写点什么

为什么 CSS 这么难?

  • 2019-07-20
  • 本文字数:3334 字

    阅读完需:约 11 分钟

为什么CSS这么难?

我同 CSS 打交道已经有几年了,每当需要就会用到它。最近我想明白了一个问题,那就是为什么做好 CSS 样式如此之难。如果你一直都在 CSS 中苦苦挣扎,你要知道自己并不是一个人。本文就是要告诉你为什么 CSS 这么难,并且搞不明白它也不是开发者的错。

示例问题

比如说我有了下面这个 CSS 类,它应该能让我轻松地将一些文本设置为代码,再将一些文本设为红色,还把一些文本设置为粉红色背景:


.pinkBG { background-color: Pink;} .red { color: Red;} .code { font-family : courier;background : #eaeaea;padding : 12px;color : Navy;font-weight : bold;width : 200px;}
复制代码


现在我在 HTML 里使用上面的 CSS 类:


<div class="code">This is Code</div><div class="red pinkBG code">This is Red Code</div>
复制代码


结果就不知道出了什么问题。看起来好像“red”和“pinkBG”这俩 CSS 类根本没起效果。我在浏览器中看到的是:



到底发生了什么?如果你是一名经验丰富的 CSS 老鸟,很快就会发现问题出在我的 CSS 上。因为我在 HTML 中为 DOM 元素指定类的顺序没有任何意义。唯一重要的是 CSS 样式表中 CSS 类定义的顺序。然后恰好上面代码中的这个顺序产生了上述结果。

补救措施

只要我“重新排序”我的 CSS,一切就正常了:


.code { font-family : courier;background : #eaeaea;padding : 12px;color : Navy;font-weight : bold;width : 200px;}.pinkBG { background-color: Pink;} .red { color: Red;}
复制代码


现在输出变成了:



太棒了,这正是我想要的!

一般问题

从上面的解决方案里你发现了什么问题?那就是我作为 CSS 样式表的用户却不能按我把 CSS 类应用到元素的顺序指定 CSS 类的顺序。如果写样式表的是其他老鸟怎么办?敢情我还得找他们修改样式表吗?他们不会嫌麻烦吗?


就算他们照做了,他们做修改时不会带来很多副作用吗?也许这个样式表已经用到上千个地方了,修改它可能会很危险。所以也许我只能复制他们的样式表并根据需要修改我的副本。但是一旦他们改动了原始版本中某些非常重要的内容时,我的这套做法就不行了,改过的部分没法再用到我的网站里了。


我分配给 DOM 元素的样式类的组合效果取决于样式表中这些类的编写顺序。而且这个顺序只有这么一种。


在 HTML 中我不能这样写:


<div class="red pinkBG code">
复制代码


我不能指望首先应用 CSS 类“red”的属性,然后是类“pinkBG”的属性,然后是“code”的属性,这是做不到的。我希望样式表是这种机制,但实际情况恰恰相反。


如果我改变这些类的顺序,比如说:


<div class="code red pinkBG">
复制代码


会发生什么呢?什么都没发生。输出完全一样。


唯一重要的是在我的 CSS 样式表中定义这些类的顺序。重要的事情再强调一遍。


这意味着每个 CSS 类所做的事情并不会“加起来”,不会“总和”成它们的组合效果。我不仅要知道这些类的单独定义,还得花一些时间来弄清楚另外三件事情:


  • 是否在 CSS 类“red”之前或之后定义了 CSS 类“code”?

  • 是否在 CSS 类“pinkBG”之前或之后定义了 CSS 类“code”?

  • 是否在 CSS 类“pinkBG”之前或之后定义了 CSS 类“red“?


搞清楚这些问题才能知道你的网站会显示成什么样子。也许还可以问问哪家的人工智能助手?或者干脆找位大侦探来研究一下吧。


请注意,你还必须要给 CSS 类排序。它们总是并且必须按某种顺序排列。问题是这些顺序直接影响你的网站内容。那么自然就引出了下一个问题,对 CSS 类来说最好的顺序是什么?

CSS 类有所谓的最佳顺序吗?

CSS 目前的工作机制要求编写样式表的人必须试着为其中定义的样式类安排一个最佳顺序。但这样的最佳排序是否存在呢?如果你有 7 个 CSS 类:


7 * 6 * 5 * 4 * 3 * 2 == 5040
复制代码


就会有足足五千多种排序方式。哪种顺序最好呢?鬼知道。如果你有 9 个 CSS 类,可选的顺序就会有 362,880 个。那么实际上你有多少类呢?


于是你用 CSS 时到底该怎么办?我可以告诉你一条经验法则,也许其他人还有更多经验…


怎样在一个样式表中排序 CSS 类?


答案:如果 CSS 类具有不同数量的样式属性,就把属性较多的类放在前面


这条规则背后的原理是,类的属性越少,它的属性值与其他类的属性值冲突的可能性也会越低。这样排序后你的类就能显示你想要的效果了。把简单的类排到后面意味着这些简单的类的效果会覆盖前面的类,最终输出结果中这些简单类的优先级最高。然后,你就可以选择是否把它们添加到 HTML 中了,如果添加进去的话它们也只会影响自己关联的那么一两个属性。


注意在上面的示例中用这条规则就能达成我要的结果。


观察:努力减少每个类的样式属性数量。如果每个样式类只有一个属性,那么大部分问题就自动解决了。但是从示例中可以看出现实中我们没法一直这样做。我们希望代码段具有某些字体、某些背景等,如下图所示。


通用解决方案

一个更好的方案是让附加到 DOM 元素的类名顺序等同于这些 CSS 类作为样式应用的顺序


然后样式表的用户就能决定将样式类应用到特定 DOM 元素的顺序了。是的,把权力还给用户。这样大家不就都能过上幸福生活了吗?


为什么 CSS 样式类目前不能使用这种机制?有什么令人信服的理由吗?我不知道,你知道的话可以告诉我。


也许将来的 CSS 版本会解决这个问题吧。也许将来的 CSS 会有一个指令写着“使用用户指定的顺序,而不是样式表中的顺序”。那可就太棒了。


你想买什么颜色的车都行,反正只有黑色的可以买;你想按任何顺序应用 CSS 类都行,反正必须是按样式表中的顺序应用。这还有什么意义吗?

纸牌屋

如前所述,哪怕只有 9 个 CSS 类也会有 362,880 种不同的排序。改一个新顺序就能改变你的网站的外观,甚至让它变得乱糟糟或丑陋不堪。如果改变顺序还让一些交互元素看不见了,甚至连网站的功能都会受影响。


当然,362,880 种排序中的大多数都能产生完全相同的结果。但具体是哪些顺序呢?这可说不准。这就是为什么 CSS 如此之难的原因所在。你不能只研究单个样式类的定义。你必须打包研究它们,理解它们在组合中的彼此关系。CSS 类不能简单相加


1 + 2 == 2 + 1
复制代码


这个等式当然没问题。但是:


CssClass_A + CssClass_B != CssClass_B + CssClass_A
复制代码


要是算式变成下面这样得有多难啊:


a + b != b + a
复制代码


作为一个比喻,现在想象一下,你的网站的一个“坐标”是它使用的 CSS 类的 362,880 种排序中的一种。这就像 X 轴有 362,880 点,坐标就是其中一点。假设你选择的 x 坐标值是 123,456。


你后来发现要让某个元素的样式正确,你必须将 x 的坐标改为 x == 123,457 才行。但是这种变化也会产生意想不到的副作用。


你做了一个非常小的改变,就像在一个纸牌屋中移动一张牌一样。但这种小小的改变会以你想不到的方式改变你网站的外观,让它变乱或者更难看、不堪一击。

想象一下

如果你最喜欢的编程语言都像 CSS 这种笨样会怎么样?假设你有一个由函数 c(),**b()a()**组成的 JavaScript 程序。它会计算一些结果并在控制台或网页上显示。也许它会计算出在网站某些部分使用的颜色。


有一天,你决定清理代码并将函数定义重新排序为 a()b()c()。结果一周后你的客户非常愤怒地找上门来,说他们的用户无法再读取他们网站的部分内容。为什么?因为这些部分的背景颜色和文本颜色变成一样的了。


你肯定会抱怨说你用了哪门子的坑爹编程语言不是吗?你肯定会跟编程语言厂商抱怨:“亲爱的先生们,我们很难用你们的语言做出符合我们需求的程序。因为每次我们重新排列功能定义的顺序时,程序的输出结果都会改变!“


你的编程语言厂商这样回复说:“亲爱的客户,我们已经查看了你的问题,我们也认为 JavaScript 的这种机制真的很愚蠢。但是我们无法改变这种状况,因为我们需要向后兼容。但我们确实在下一版本中加入了解决方案。它只要求你在程序的开头加上以下指令就行:“


DefinitionsOrderDoesNotMatter = true
复制代码

总结

使用 CSS 制作网站就像小心搭建一个纸牌屋一样。没办法,现实就是如此。但 CSS 仍然是我们的最佳选择。


我们能做的也只是把属性较少的类放在后面而已。


此外还要阅读所有样式表,了解每个样式表的所有部分的效果,还要搞清楚各个部分之间的关系。你必须使用“整体方法”来理解你的 CSS。目前的 CSS 版本只能这样处理。


然后呼吁你的 CSS 提供商在下一版本中加一个选项,不要再让样式类的定义顺序跟输出效果关联了。


英文原文:https://medium.com/@panuviljamaa/why-css-is-difficult-a2cdf0a04ca1


2019-07-20 14:045463

评论

发布
暂无评论
发现更多内容

秒懂算法 | 搜索基础

TiAmo

DFS BFS 搜索算法

OceanBase 生态产品:时序数据库CeresDB 正式发布 1.0 版本

OceanBase 数据库

数据库 oceanbase

探索以小程序提升运维效率

Onegun

运维 小程序容器

M1电脑运行Windows10弹出“内部版本已过期”的解决方法

Rose

pd虚拟机 M1电脑 Windows内部版本已经过期

瓴羊Quick BI:“3端4表4擎、3+NPlus”得到众多行业内部人士的认可!

对不起该用户已成仙‖

技术沙龙 | 探索软件测试前沿技术及最佳实践,体验ChatGPT在测试领域中的应用

测试人

软件测试 沙龙 ChatGPT

TypeScript 与 JavaScript:你应该知道的区别

京东科技开发者

JavaScript typescript 前端 后端 企业号 3 月 PK 榜

数据测试实践:从一个bug开始的大数据引擎兼容性探索

京东科技开发者

大数据 bug修复 引擎 测试数据构造 企业号 3 月 PK 榜

Higress on K8s 5分钟开箱即用

阿里巴巴中间件

阿里云 云原生 Higress

ins视频保姆级图文教程,快学起来!

frank

R-Drop论文复现与理论讲解

华为云开发者联盟

人工智能 华为云 深度神经网络 华为云开发者联盟 企业号 3 月 PK 榜

搬得进来,搬得出去!快来过一把数据迁移的“瘾”

OceanBase 数据库

数据库 oceanbase

用户分享 | 达梦第三方客户端DockQuery使用体会

BinTools图尔兹

数据库 用户体验 国产数据库工具

融云入选中国信通院《高质量数字化转型产品及服务全景图》

融云 RongCloud

产品 数字化 通讯

解决mac电脑打开应用“意外退出”的问题 (点按“重新打开”以再次打开应用程序)

魔仙苹果mac堡

PHPStorm 意外退出 mac电脑

MMMBSC互助基金系统开发智能合约部署

薇電13242772558

智能合约 dapp

探索 Pixelmator Pro 3新功能——AI智能模板

Rose

Pixelmator Pro Mac修图软件

动转静两大升级!一键转静成功率领先,重点模型训练提速18%+

飞桨PaddlePaddle

人工智能 百度 飞桨 PaddlePaddle 框架解析

聊聊线上发布这件事

老张

软件测试 权限管理 服务部署

取得成功的 13 个方法

宇宙之一粟

个人成长 翻译 成功

跨端技术或许是提升软件运维效率的利器

FinFish

小程序化 小程序技术 高效运维 软件运维

React等前端框架如何与小程序结合

Onegun

前端 前端框架 React Vue 3

京东云RASP云原生安全免疫创新实践

京东科技开发者

Web 安全 漏洞 业务安全 企业号 3 月 PK 榜

Dubbo Triple 协议

昵称不能为null

dubbo RPC triple协议

小程序技术如何提升企业的移动研发效率?

FinFish

降本增效 小程序容器 移动研发 小程序技术

云智慧助力中国信通院组装式应用开发平台系列标准建设

云智慧AIOps社区

适用于 Apple Silicon (M1芯片)的 Photoshop常见问题及解决方案

魔仙苹果mac堡

PhotoShop PS常见问题

Vineyard 论文被 SIGMOD'2023 接收,助力计算引擎之间高效数据交换

阿里巴巴中间件

阿里云 计算引擎

精选案例 | 博睿数据30w+监测节点护航新华网、人民网两会重保工作

博睿数据

可观测性 智能运维 博睿数据 精选案例 主动式拨测

你代码的异味是故意的还是不小心?是故意的!

禅道项目管理

FDF循环互助游戏系统开发智能合约搭建

薇電13242772558

智能合约

为什么CSS这么难?_语言 & 开发_Panu Viljamaa_InfoQ精选文章