为什么在CSS选择器/HTML属性中使用破折号更受欢迎?

239

过去我一直使用下划线来定义HTML中的类和ID属性。但在过去几年中,我开始改用破折号, 主要是为了迎合社区中的潮流, 而不一定是因为它对我有意义。

我一直认为破折号有更多的缺点,而且我看不到好处:

代码补全和编辑

大多数编辑器将破折号视为单词分隔符,所以我无法通过Tab键快速找到想要的符号。如果类名是“featured-product”,我必须自动完成“featured”,输入连字符,并完成“product”。

对于下划线“featured_product”,则被视为一个单词,因此可以一步完成。

同样适用于通过文档导航。破折号会破坏按单词跳转或双击类名的功能。

(更普遍地说,我认为类和ID应被视为令牌,因此在破折号上轻松分割一个令牌对我来说是没有意义的.)

算术运算符的歧义

在JavaScript中,使用破折号会破坏访问表单元素的对象属性。这只有在使用下划线时才可能:

form.first_name.value='Stormageddon';

(自认为我不会使用这种方式访问表单元素,但是在决定是否使用破折号或下划线作为通用规则时,请考虑其他人可能会使用该方式。) Sass等语言(尤其是整个Compass框架)已经将破折号作为标准,即使对于变量名也是如此。它们最初也使用了下划线。这种差异的解析方式让我感到奇怪:
$list-item-10
$list-item - 10

变量命名在不同编程语言中的不一致性

从前,我在 PHP、ruby、HTML/CSS 和 JavaScript 中使用下划线命名法 (underscored_names) 来定义变量。这种方式既方便又一致,但是为了“适应”现在的环境,我现在使用以下方式:

  • 在 HTML/CSS 中使用破折号命名法 (dash-case)
  • 在 JavaScript 中使用驼峰命名法 (camelCase)
  • 在 PHP 和 ruby 中使用下划线命名法 (underscore_case)

这并没有太困扰我,但我想知道为什么它们会出现这样的不一致,似乎是有意为之。至少对于下划线而言,保持一致是可能的:

var featured_product = $('#featured_product'); // instead of
var featuredProduct = $('#featured-product');

这些差异会导致我们不必要地翻译字符串,同时也可能引发错误。

因此我问:为什么社区几乎普遍采用破折号,是否有任何理由超过下划线?

这里有一个相关问题,大约在这个问题开始的时候,但我认为如果真的只是品味问题,那么它就不应该(或者说不应该)成为惯例。我想了解为什么我们都会遵循这个惯例。


55
我使用破折号是因为我不需要按Shift键。 - Jared
16
想知道为什么这个问题被关闭了...是否有投票来关闭它?我不是在这个问题中征求意见。我给出了具体的理由反对使用破折号,但如果众人都似乎同意这种趋势,那肯定有好的理由。这里有一些好的答案和信息。我能改进这个问题吗? - Andrew Vit
14
我希望您能重新开放我的问题:所有下面的答案都包括“事实、参考资料或特定的专业知识”... 所以我不明白为什么它被认为是“不具建设性”的。 - Andrew Vit
16
我认为将这个帖子标记为“无建设性”是一个愚蠢的决定。如果有一种编码风格因为某些原因(比如更容易被IDE处理,更容易进行代码补全,与工具更好地集成)而被优先采用,那么我认为这会是一个非常有建设性的问题/答案/讨论。 - Jake Wilson
9
@AndrewVit:这是一个非常好的问题,格式良好,信息丰富,突出了多个方面。为此点赞。顺便说一句,我同意将其关闭为“不具建设性”是毫无意义的。实际上它是有建设性的。 - Sk8erPeter
显示剩余7条评论
7个回答

145

代码自动补全

破折号(dash)是被解释为标点符号还是不透明的标识符取决于所选择的编辑器。然而,作为个人喜好,我更喜欢在CSS文件中每个单词之间能够使用Tab键切换, 如果它们用下划线分隔并且没有停止符会很烦人。

此外,使用连字符允许您利用|=属性选择器,该选择器选择包含文本的任何元素,可选地后跟连字符:

span[class|="em"] { font-style: italic; }
这将使得以下HTML元素具有斜体字样式:
<span class="em">I'm italic</span>
<span class="em-strong">I'm italic too</span>

算术运算符的歧义

我认为在JavaScript中通过点符号访问HTML元素是一个缺陷而不是一个特性。这是从早期可怕的JavaScript实现中继承而来的糟糕结构,不是一个很好的实践方式。对于当今大多数使用JavaScript的场景,您需要使用CSS选择器从DOM中获取元素,这使得整个点符号相当无用。您更喜欢哪一个呢?

var firstName = $('#first-name');
var firstName = document.querySelector('#first-name');
var firstName = document.forms[0].first_name;

我发现前两个选项更可取,特别是由于'#first-name'可以被替换为JavaScript变量并动态构建。我也发现它们更加舒适。

Sass在其对CSS的扩展中启用算术运算并不适用于CSS本身,但我理解(并接受)Sass遵循CSS的语言风格的事实(除了变量的$前缀,当然应该是@)。如果Sass文档要像CSS文档一样看起来和感觉一样,它们需要遵循与CSS相同的样式,使用连字符作为分隔符。在CSS3中,算术运算仅限于calc函数,这表明在CSS本身中,这并不是一个问题。

跨语言变量命名的不一致性

所有语言,无论是标记语言、编程语言、样式语言还是脚本语言,都有自己的风格。您会在语言组的子语言中找到这一点,例如XML,其中XSLT使用连字符分隔的小写字母,而XML Schema使用驼峰式大小写。

通常,采用感觉和外观最符合您正在编写的语言的风格比尝试将自己的风格硬塞到每种不同的语言中要好。由于您无法避免使用本机库和语言结构,因此无论您喜欢与否,您的风格都将被本机风格“污染”,所以即使尝试也基本上是徒劳无功的。

我的建议是不要在各种语言之间找到一个喜欢的风格,而是让自己在每种语言中感到舒适,并学会喜欢其中的所有怪癖。CSS的一个怪癖是关键字和标识符都采用小写字母,并用连字符分隔。个人认为这非常美观,并且认为它与全小写(虽然无连字符)的HTML相匹配。


5
是否将破折号解释为标点符号或不透明标识符取决于所选择的编辑器。尽管可能有一些特殊的编辑器,但我认为这通常并不正确。双击一个带连字符的单词只会选中部分而非整个标记:这似乎是全局操作系统共通的情况。 - Andrew Vit
15
关于 |= 选择器的观点很好,我在其他答案中看到了这一点,这是一个公正的观点。语言约定是围绕这个设计的,还是反过来?(连字符作为普遍趋势似乎相对较新,它们可能在同一时间出现。) - Andrew Vit
1
@AndrewVit,有基于CLI的编辑器,双击不相关(因为通常没有鼠标),可以配置此类行为。但总的来说,你是正确的。|=属性选择器是专门为lang属性设计的,但其使用可以扩展。我一直在我的CSS中使用连字符,所以我不能代表大众发言,但从Pascal case、Camel case和下划线中肯定已经趋向于连字符了。据我所知,|=选择器和连字符作为分隔符是无关的。 - Asbjørn Ulsberg
3
我认为点表示法并不是一个bug,问题出在CSS上,它本不应该使用连字符。而且,令人愉悦的外观因人而异。 - vivek
3
很有用,但它的工作方式略有不同。 - gcampbell
显示剩余5条评论

78

HTML/CSS社区使用连字符而不是下划线,可能的一个重要原因是规范和浏览器实现方面的历史缺陷。

来自Mozilla文档,发布于2001年3月 @ https://developer.mozilla.org/en-US/docs/Underscores_in_class_and_ID_Names

1996年最终版的CSS1规范未允许在类名和ID名中使用下划线,除非它们被“转义”。 转义的下划线将看起来像这样:

    p.urgent\_note {color: maroon;}

然而,当时浏览器对此支持不佳,这一做法也从未流行起来。1998年发布的CSS2也禁止在类名和ID名称中使用下划线。然而,该规范早在2001年初发表的勘误中首次将下划线合法化。不幸的是,这使本已复杂的情境变得更加复杂。

我个人喜欢使用下划线,但反斜杠却让它变得非常丑陋,更不用说当时的稀少支持。我可以理解为什么开发者害怕使用它。当然,现在我们不再需要反斜杠了,但短横线的使用规范已经得到了牢固的确立。


8
谢谢!我喜欢了解这种惯例的“词源学”。这有助于我记住使用习惯,因为我可以将语言与它联系起来。这种联想有助于潜意识中使用这种约定。 - Ape-inago
我认为这是迄今为止最好的答案。这不是一种观点;它实际上使用历史背景来回答了问题。 - rokejulianlockhart
我认为这是迄今为止最好的答案。这不是一个观点,它实际上是通过历史背景来回答问题。 - undefined

43

我认为没有人能做出明确的回答,但这是我的猜测:

  1. 下划线需要按Shift键,因此更难输入。

  2. CSS选择器是官方CSS规范的一部分,使用连字符(例如伪类如:first-child和伪元素如:first-line),而不是下划线。同样的道理适用于属性,例如text-decoration,background-color等。程序员是有习惯的生物。如果没有充分的理由,他们会遵循标准的写法。

  3. 这个可能更靠边站了,但是...无论这是神话还是事实,长期以来人们都认为Google将用下划线分隔的单词视为一个单词,将用连字符分隔的单词视为多个单词。(Matt Cutts on Underscores vs. Dashes.)因此,我现在更喜欢使用用连字符分隔的单词来创建页面网址,至少对我来说,这也影响了我的其他命名约定,例如CSS选择器。


2
关于URL中的破折号和语义标记对SEO的好处(无论这是否真实),你提出了一个很好的观点...您能否澄清一下哪些“CSS选择器是官方CSS规范的一部分并使用破折号”? - Andrew Vit
我在我的回答中扩展了第二点,给出了一些例子,尽管我更多地考虑了像text-decoration这样的CSS属性,而不是“选择器”,所以那有点打错了,尽管如上所述,确实有一些选择器可以实现。 - Mason G. Zhwiti
1
谢谢@albert,这将成为一个很好的答案...至少对于历史背景而言。我不知道最初的规范不允许使用下划线!(但是不允许使用下划线没有意义。) - Andrew Vit
谢谢@albert,我一直记得这个原因(我记得它是某种浏览器兼容性问题),但找不到任何支持文件。 - Mason G. Zhwiti
4
第二点让我信服,尤其是考虑到像背景颜色、文字装饰等属性。 - Big McLargeHuge
2
对于好奇的人,@albert在上面的评论中提到的devedge-temp网址(http://devedge-temp.mozilla.org/viewsource/2001/css-underscores/)现在已经迁移到https://developer.mozilla.org/en-US/docs/Underscores_in_class_and_ID_Names。 - aponzani

20

许多原因中,最重要的之一就是保持一致性

我认为这篇文章详细地解释了它。

CSS是一个用连字符分隔语法。也就是说我们会写像font-sizeline-heightborder-bottom等等这样的东西。

所以:

你不应该混合使用语法:这是不一致的


1
我对这个有不同的感觉。在你的自定义类中使用下划线确实在扫视CSS时增加了有益的视觉差异。如果我看到破折号,那么我知道这是一个原生规则或变量。如果我看到下划线,那么我知道这是一个自定义类。这种辨别对我帮助很大! - undefined
感谢@Kalnode提出了使用下划线的有趣论点。 归根结底,这是个人偏好的问题,因为CSS本质上允许不同的样式。关于下划线的缺点,我可以引用我引用的文章的作者的话,他说使用下划线“存在与一致性和无法选择字符串的个别部分的能力方面相同的问题”。 - undefined

15
近年来,使用连字符分隔的整词 URL 段明显增加。这种做法是 SEO 最佳实践的一部分,谷歌明确建议 "在 URL 中使用连字符 (-) 而不是下划线 (_) ":http://www.google.com/support/webmasters/bin/answer.py?answer=76329
尽管在不同的时间和背景下存在不同的约定俗成,但它们通常不是任何协议或框架的正式部分。
因此,我认为谷歌的立场将这种模式锚定在一个关键的上下文中(即 SEO),而在 class、id 和属性名称中使用这种模式的趋势只是群体在朝着这个方向缓慢移动。

6
我认为这是一个程序员个人偏好的问题。有些人喜欢使用破折号,而另一些人则使用下划线。
我个人使用下划线 (_),因为我在其他地方也使用它。例如:
- JavaScript 变量 (var my_name);
- 我的控制器操作 (public function view_detail)
我使用下划线的另一个原因是,在大多数 IDE 中,用下划线分隔的两个单词被视为一个单词。(并且可以用双击选择)。

-2
point of refactoring only btn to bt

case: btn_pink
search btn in word
result btn

case: btn-pink
search btn in word
result btn | btn-pink

case: btn-pink
search btn in regexp
\bbtn\b(?!-) type to hard
result btn

1
请在您的代码中添加一些注释,以帮助用户理解您的答案。我建议您也阅读一些指南,这将有助于使您的答案更清晰,不被删除并获得更多的投票支持。 https://stackoverflow.com/help/how-to-answer - Davide Casiraghi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接