为什么CSS和SVG可以接受大量的幻数?


63

很多时候,我看到了热网的问题列表像问题这个,基本上问“我怎么画这个任意形状的CSS”。答案总是是几个CSS或SVG数据块,它们带有一堆看似随机的硬编码值,这些值构成了所需的形状。

当我看着这个时,我会想:“好极了!多么丑陋的代码块。我希望我在项目中再也不会看到这种类型的东西。但是,我经常看到这类问答,并且投票数很高,因此很明显,社区并不认为这很糟糕。

但是为什么可以接受呢?从我的后端经验来看,这对我来说毫无意义。那么为什么CSS / SVG可以呢?


38
如果不是看起来很不错的一堆魔术数字(不是在2(x,y)点之间的笔画或像素阵列等),那是什么图?

68
CSS有变量吗?SVG吗?
Oded

36
这就是为什么许多较大的项目都有CSS预处理程序(如SASS或LESS)支持变量的原因。
Ixrec '16

2
@Oded对于CSS,对变量有大约40%的全局支持(因此,除非您要告诉所有Microsoft访问者不受欢迎,否则不建议这样做)。微软可能会跟随Edge的趋势,而移动设备最终将迎头赶上。另一方面,SVG在某些已失效的状态文档中具有变量的概念,但是它们可能永远不会实现。
phyrfox

12
为什么?因为它们不是魔术数字。CSS保存数据,这不同于保存指令的程序。尽管CSS可以说是完整的,但它不是一种编程语言。
Derek朕会功夫2016年

Answers:


118

首先,在编程中通过使用变量或常量来避免魔术值。CSS不支持变量,因此即使不愿使用魔术值,您也没有太多选择(除了将预处理器用作SASS之外,但您不会对单个代码段执行此操作)。

其次,在像CSS这样的领域特定语言中,值可能没有那么神奇。在编程中,幻数是含义或意图不明显的数字。如果一行显示:

x += 23;

您会问“为什么23”?这是什么原因?变量可以阐明意图:

x += defaultHttpTimeoutSeconds;

这是因为一个单独的数字在通用代码中可能绝对没有任何意义。但是考虑一下CSS:

background-color: #ffffff;
font-size: 16px;

高度和颜色不是魔术,因为从上下文中可以清楚地看出含义。选择特殊值的原因很简单,因为设计师认为它看起来不错。引入变量将无济于事,因为无论如何,您只能将其命名为“ defaultBackgroundColor”和“ defaultFontSize”。


16
确实选择了某些值是因为“它们看起来不错”。但是,OP链接的示例多次包含相同的值,但尚不清楚它们是表示同一事物还是巧合而仅具有相同的值。此外,它使用的值198px是其他值(200px)和2px边框的大小之差。
CodesInChaos

1
@CodesInChaos:是的,在某些情况下变量或某种依赖项表达式会很酷。
JacquesB 2016年

21
请注意,CSS 确实 支持变量
phihag

28
@phihag在规格,是的,但在野外,没有这么多(我并不在此评论的时间考虑40%的全球支持,“广泛的支持”。不过,你说得对,在未来,我们将拥有CSS变量,而我今天确实学到了一些新知识,所以谢谢您
phyrfox 2016年

2
@JaredSmith对于规模相对较大的Web应用程序来说不错,但是对于包含大量polyfill的常见(也许是静态)页面来说,这太过分了。
德里克·朕会功夫2016年

81

可以接受,因为这些格式不是代码,而是数据。如果要删除所有“魔术数字”,则实际上将复制每个标签,并最终得到看起来很可笑的文件,例如:

mainkite_width = 200px
...
.mainkite {
  width: mainkite_width;
  ...

每次您需要更改一些数据时,都需要在两个地方查看。当然,在某些情况下最好避免重复,例如,如果您的颜色经常重复出现,并且可能需要更改以更改主题。有用于解决这些情况的预处理器和拟议的扩展,但通常,希望将数字和结构以数据格式一起使用。


22
+1是因为:“可以接受,因为这些格式不是代码,而是数据。”
Pieter B

1
“当然,在某些情况下最好避免重复,例如,如果您的颜色经常重复出现,并且您可能需要更改以更改主题。” -无论如何.main_color { color: .. },最好用类来完成:,而使用该类重复数据删除的方法
Izkata

决定应用程序外观的代码仍然是代码,而不是数据。
ESR

26

禁止使用幻数是此设计原理的原始版本:

在一个地方做决定

但是这些不是魔术数字。至少,就我所知的任何编码风格指南而言。

宽度:200像素;
高度:200px;

它们有明确的标签。当然,数字恰好相同。但是宽度是宽度,高度是高度。它们旨在独立变化。

现在,如果您有5个对象都必须具有相同的宽度,并且每个对象都独立地对其宽度进行了硬编码,那么我会用间接棒击败您。

如果标有标签,我不会称其为魔术数字,但是我仍然会用间接棒击败您。


4
如果您有足够的对象需要一个变量,则您有足够的对象来创建一个新类。
Jaketr00 2016年

1
这是最好的答案,因为它表明了重点:那些不是魔术数字。
TheBlastOne '16

2
“ 5个物体必须具有相同的宽度,并且每个物体都独立地对其宽度进行硬编码,我会用棍子打败你。” 欢迎来到有趣的网页设计世界。
whatsisname 2016年

2
幻数不仅因为“在一处做出决定”(又称DRY)而引起问题,而且还因为它们难以理解。
sleske '16

除了用棍子殴打之外,还有其他选择吗?
djechlin '16

11

因为CSS不是一种编程语言,所以它是配置文件,其中包含程序的变量数据。

当前CSS非常强大,您可以在其中进行编程,但这并不重要。从本质上讲,它仍然是一种样式表语言

让我们退后一步。假设我们有一种可以在屏幕上绘制的编程语言。假设我们要对其进行编程以绘制网页。

首先,我们将在代码中输入大量的幻数。页边距宽度,文本高度,缩进等,等等。

jump(100) // The margin
drawTable(500, 500)
writeText("Hello World", 12)

因此,我们提取了魔幻数字,并将其放在文件的顶部。

int margin = 100
int table = 500
int text_size = 12
jump(margin) // The margin
drawTable(table, table)
writeText("Hello World", text_size)

现在,这有点丑陋。我们宁愿从配置文件中读取变量号。

margin 100
table 500
text size 12

嗯,还不清楚...这些数字是什么意思?这些名字是什么意思?让我们正式化一下。

margin_left 10em
table_width 500px
table_height 500px
font_size 12px

但是您知道,我们想稍微扩展一下程序。我们还希望它绘制具有多个表的页面,不具有表的页面,具有段落或按钮的页面等等。让我们向配置文件中添加选择器,以便我们可以指定哪个段落应使用更大的字体或不同的文本颜色,也许我们可以支持嵌套元素,也许可以在配置文件中使用常规属性,然后使用特定的属性覆盖它。嵌套元素中的一个。


您感觉到了它的发展方向,最终以CSS的形式出现了。(以及用于呈现它的浏览器。)

然后,我们是否应该向配置文件中添加功能,以便再次避免幻数?添加变量?为我们的CSS文件添加配置文件?如果您还记得我们的CSS文件已经是非常相同的配置文件,那感觉就没有意义了。

但这当然是不正确的。您的CSS文件变得越来越大,最终您会遇到与原始魔术数字相同的问题,在整个地方重复相同的数字,有时进行小的转换等。

但是,现代CSS允许采用多种方法来避免这种重复。您可以使用适用于许多元素的类,可以为all设置样式div,然后专门覆盖一个样式,并且CSS 3甚至允许某种变量使用。

这并不意味着您需要在每个可能的位置开始使用CSS变量。在有意义的地方使用它,并在避免重复的地方使用它,或者在其他可用技术不足的地方使用它。

最后,您也不希望配置文件中有太多的幻数:-)


为什么冗余在哪里很重要?不管在哪里维修都不会成为问题吗?
彼得·莫滕森

@PeterMortensen总是在缩短开发时间或提高可维护性之间进行考虑。高冗余很容易开发,因为您可以在本地和本地快速更改内容;低冗余很容易维护,因为您可以快速更改全局样式。实际上,您希望介于两者之间,因为面对它,具有全局样式会使添加新页面变得容易得多,但是要使所有最后的晦涩功能坚持任何可能的全局样式更改,则需要永远进行开发。
Dorus

很好的CSS具有双向功能。Web开发人员可以决定花费多少时间来减少冗余和增加可维护性,或者花费时间来处理新页面/功能。足够有趣的是,对于任何其他编程语言而言,这同样适用,您可以花费数月的时间来布局完美的设计,或者花费数天的时间来编写程序,并花费数月的时间来查找不可能的错误。
Dorus

足够有趣的是,我刚遇到了一个问题该问题涉及过分抽象,并浪费了可维护性和开发时间。
Dorus's

5

为什么CSS / SVG [一堆看似随机的硬编码值]可以接受?

不好 这是可能的编写和维护简单的“的CSS”的文件,但最终还是随机的硬编码值将成为一种普遍的负担。

对于除非常简单的网页以外的任何其他内容,您要么必须制定一种严格的“查找和替换”策略,要么使用带有变量的CSS预处理器,或者通过JavaScript定义样式。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.