CSS选择器最佳实践

16

我又在琐碎的事情上浪费时间了。我现在问自己 - 也问你们 - 怎样做CSS选择器/HTML标记最好呢?

是尽量避免使用类,保持HTML的纯洁和美观,还是为了样式而随意添加类?

比如,如果我想要给网站的各种表单按钮设置样式,应该怎么做呢?

input[type="submit"] { /* styles */ }

还是我给它们全部添加一个"class=form-button"的类,然后执行

.form-button { /*styles */ }
在这个简单的例子中,人们可能不会太在意,但如果我想要以语义化而非呈现性的方式对列表中的第三个链接进行不同的样式设置,我可以这样做。
.navigation ul:nth-of-type(2) a:nth-of-type(3) { /* styles */ }
与仅为一个链接指定“different-link”类并使用相应的CSS样式表相比。
.different-link { /* styles */ }

我知道在2013年,所有的计算设备和它们运行的浏览器都应该足够快,以至于技术上不太完美的CSS选择器对最终用户不会产生任何影响。

所以最后,这似乎真的是一个问题:“我是要用类来填充HTML(产生冗余),还是用冗长的选择器来填充CSS(使其复杂)?”

您对此有什么看法?


2
这是一个好问题,但不幸的是我不得不投票关闭它,因为这将吸引主要基于观点的答案。在CSS中,实际上没有最佳实践-如果您的样式有效,则非常好,如果无效,则需要重新考虑。特异性和浏览器兼容性是您始终需要考虑的事情,更重要的是,您希望您的代码能够被任何未来的开发人员理解并且可以处理它。 - James Donnelly
2
@JamesDonnelly:相信我,CSS不仅仅是个人观点。 :) - Robert Koritnik
@RobertKoritnik 当然没问题,但是例如说声称 .form-buttoninput[type=submit] 更好,因为标记可能会改变对我而言更像是一种观点,而不是事实。毕竟,您可以简单地删除类型选择器并仅使用属性选择器:[type=submit] - James Donnelly
@Robert Koritnik:这里的关键词是“主要”。你可以用尽可能多的事实参考来支持你的观点,但归根结底,问题的前提是主观性的。 - BoltClock
5个回答

13

HTML和CSS之间的关注点分离

尽管CSS已经从HTML中外部化,但在插入HTML元素特定选择器的情况下,CSS应被视为单独的,实际上并不是这样。如果你的选择器与实际的HTML元素及其层次结构有关,那么你的CSS就与HTML源代码紧密绑定在一起。这使得您的CSS不够灵活,并且可能比它应该的要大。

因此,出现了CSS类。每当你使用类时,这些定义可以附加到任何HTML元素上,只要它们定义了足够的属性。虽然由于额外的属性,你的HTML变得更大了,但语义并没有改变。

为什么.form-buttoninput[type = submit]更好?

因为你可以将<input type=submit />更改为<button type=submit>,它是一个容器,为UI设计师提供了更多的设计自由度。如果你使用CSS类,则可能不会太多地更改其属性,但如果你使用标签名称,则必须整个修改CSS文件。

另一个例子是其他类型的输入,如“取消”按钮。如果它在视觉上与“提交”按钮相同,设计师可能会说“提交”是主要操作,“取消”是次要操作,因此应该显示为一个简单的链接。使用类会再次减少维护。

为什么只使用类的CSS也不是万能的?

有些元素可能具有其他元素没有的特定CSS属性。以无序/有序列表为例。在这种情况下,编写基于标记的选择器来定义适用于特定HTML元素的CSS样式是有意义的。但为了避免选择页面上所有相同类型的元素,建议将CSS选择器定义为基于标记和类的组合选择器。这产生所谓的CSS类选择器约束,在这种情况下是有意义的。

请注意,只使用基于类的选择器来分离公共样式属性,并添加具有约束的标记+类基于选择器的特定样式(LESS / SCSS语法):

/* generic */
.navigation {
    background-color: #999;
    margin: 0;

    .item {
        display: inline-block;
        padding: 10px;
    }
}

/* specific to UL */
ul.navigation {
    list-style: none;
}

这样做可以让你最自由地发挥,并将可维护性最大化。

结论:基于类的选择器更受青睐提示:OOCSS

是的,大部分时间都是这样。这样一来,您将能够编写面向对象的 CSS (SmashingMag 上的文章GitHub 存储库),同时减少代码重复和异常情况。这将提高 CSS 的可维护性。

重要说明:与任何代码一样,您不应该过度设计 CSS。我向您展示了如何提供灵活的样式定义,但您不应总是遵循这些规则。在开始时应提供足够的灵活性,并根据实际需要进行重构。但大多数时间应保持使用类。


3

我通常考虑耦合问题。

如果你只使用标签名称和复杂选择器进行样式设计,那么你的CSS与HTML紧密耦合。因此,如果你仅更改一点点标记,你肯定也会更改CSS。 这对于简单的网站可能还可以接受,例如只有一个或两个页面的情况。

对于“复杂”的网站,我认为使用类是必须的。 使用类可以将CSS与HTML解耦。我的意思是,如果你为“事物”的主要元素(然后成为一个模块)添加类,你就可以自由地更改标记,只要保持相同的类(显然,如果你大量更改标记,你可能需要大量更改CSS。对于较简单的更改,例如将元素包装在div中或将h1更改为h2,你不需要更改CSS)。

此外,你的CSS变得更易于阅读,因为当你看到这个:

.blog-posts > .blog-post > .blog-post-title

您在谈论博客文章标题的样式,这比...更好。
div > div > h1

(或任何其他类似的匿名选择器)。

因此,如果您使用类进行智能样式设计,最终会创建模块,这些模块可以具有更简单的选择器,因为您无需从HTML根元素而是从模块根元素目标元素:

.blog-post-title {}
.blog-post-subtitle {}
.blog-post-body {}
.blog-post-tags {}

等等其他的内容。

SMACSS 是我认为组织样式表的好方法,建议你阅读相关资料。如前所述,如果开发的是“简单”的网站,那么不需要这些麻烦。但对于复杂的网站来说,具有可重用模块是很大的优势。


2
我的简单回答是:如果您在整个网站中使用相同的布局,则应按其tagName选择元素,而不是按类或ID选择元素。
这些问题有点毫无意义,因为您自己在做很多假设并且不断地回答它们,而且这里不允许发表意见,您应该在http://programmers.stackexchange.com上提问。您提到:
“我知道在2013年,所有计算设备及其运行的浏览器都应该足够快,以至于技术上次优化的CSS选择器不应对最终用户产生任何影响。”
那么问题出在哪里呢?
它们之间唯一的区别在于它们将分组具有相同tagName、相同类或ID的元素。它们不会做其他事情。
现在完全取决于您编写代码的方式,因为在许多页面上,您可能还想更改按钮的样式。
伪类
使用伪类或选择器是一个好主意,只有当您想要样式化单个元素的子元素时才可以使用,因为提交按钮没有子元素,所以该选择器是模糊的。
直接选择元素
input[type="submit"] { /* styles */ }

这种方法是最简单但更好的一种,这样你可以为所有输入按钮设置样式而不必担心它们的类和ID。我个人更喜欢它。

使用ID或类

.form-button { /*styles */ }

您可能想要使用它,当您为按钮进行样式设置时,例如结帐提交按钮需要更大或更小。这需要与其他按钮不同。

2

答案:取决于你想要什么。

解释:

1)使用此选择器input [type ="submit"] 将针对网站上的所有提交按钮,您可以在想要为按钮分组/概括一些属性(如font-familyfont-weight等)时使用此选择器。因此,如果您要目标特定的提交按钮,则仅使用此功能是不够的。

2)使用.form-button 将针对具有类.form-button 的任何元素,因此要使其更具体,可以使用 input[type=submit].form-button ,这将限制仅用于提交按钮的类。此外,每次需要对按钮进行样式设置时都需要声明类。

3).navigation ul:nth-of-type(2) a:nth-of-type(3),这就是我所说的过度特定选择器。它会简单地降低性能。不仅如此,它还会导致严重的特异性问题。您需要在无法更改标记的情况下使用此选项。与此相反,在您计划定位的元素上调用一个class 比使用这种方法要容易得多。


结论:

input[type="submit"] —— 使用此功能对所有网站上的提交按钮进行分组相似属性(将由所有提交按钮共享)。

.form-button —— 使用此功能来定位您希望具有独特样式(除了在input[type=submit]中声明的属性之外的附加样式)的按钮。

.navigation ul:nth-of-type(2) a:nth-of-type(3) —— 除非你别无选择,否则我不认为有使用这个的理由,因为它过于特定。再次强调,使用或不使用它取决于一些情况,因此不能完全忽视它。

.different-link —— 它肯定比使用过度特定的选择器来唯一地设计按钮要好得多。


1

这绝对不是非此即彼的选择。

你第一个例子中使用属性为基础的CSS选择器来设置提交的样式,会导致在需要非标准或外观不同的按钮时覆盖该声明。因此,在这种情况下,最好使用非常通用的CSS声明,然后使用类根据用例添加不同风格的按钮。

例如,看看Bootstrap

我认为依赖CSS级联不容忽视(实际上它非常有用和强大),但在我的经验中,试图完全消除类是不切实际的目标。


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