2

几年前我在大学学习前端开发时,我们的老师教我们始终在 CSS 选择器中提供目标元素的完整(几乎)父 DOM 层次结构。

因此,在我们的 Web 项目中,我们必须编写如下选择器:

div#container div#content p.bread a.external { }

而不仅仅是:

#container #content .bread .external { }

或(我看到这里可能发生的类冲突的缺点)

.external { }

我个人写我的选择器喜欢

#container #content p.bread a.external {}

直到我最近读到一篇文章说应该避免它(但没有明显的原因)和另一篇文章说相同但那篇文章是为 jQuery 选择器设计的。

我的老师错了吗?编写 CSS 选择器的正确方式(解析速度最快且支持最多)是什么?

4

6 回答 6

3

实际上,您应该尽可能使用最不具体的选择器。

div#container div#content p.bread a.external { }是一个非常非常具体的选择器。它是不必要的具体。元素只能有一个#content,而且它肯定永远在 内#container

写出一般规则。不要试图定位精确的 DOM 元素。如果a.external将捕获您想要的元素集,请使用它。否则你最终将不得不写p.bread a.external, p.potato a.external, p.olive a.external, 等等等等。

性能差异将很小。通用的、可重用的规则的好处是巨大的。

于 2013-06-07T13:16:00.393 回答
2

我的 2 美分

具体到只针对需要定位的内容(正如其他人所说)是一般规则。

我同意 lonesomeday 的观点,即“性能差异将是最小的”,但链中的每一个添加元素都是需要完成的一项检查。

所以想想如何减少它


需要身份证吗?

我不同意 Spudley 的观点,即“永远不需要在选择器中指定多个 ID”。如果您的站点设置为在不同页面上显示不同的内容,因此与显示内容不同#page1 #content#page2 #content那么这是一个选择器中有两个 id 的合理情况。然而,

  1. 如果所有的页面都#container #content那么drop了#container
  2. 此外,如果所有p.bread元素都在 inside #content,则也删除该选择器。

是否需要元素名称?

  1. 旨在用于.bread除? p如果没有,请放弃p.
  2. .external打算用于除a(可能链接到外部站点)以外的任何东西?如果没有,请放弃a.

是否需要阶级的死者关系?

对展示有.bread .external重要意义吗?也就是说,是否.external存在于.bread父级之外并且是否因为该父级而改变?如果是这样,那么保持关系。否则,如果重要的东西只是.external(无论它在哪里),那么它就是您需要的唯一选择器。

于 2013-06-07T14:14:25.800 回答
1

Yes, your teacher was wrong.

From your example:

div#container div#content p.bread a.external { }
  1. Given that an ID in a DOM document must be unique, there should never be a need to specify more than one ID in a selector. So the above selector that contains both #container and #content is immediately wrong simply by that criteria.

  2. An ID is the most efficient and direct way to reference an element. Again, it's unique and instantly accessible, so there's no need to qualify it in any way, so adding div in front of either of the #container or #content here is redundant.

  3. The other two parts of the selector p.bread and a.external are likely to be wrong, but it's not so clear-cut for these.

    A selector only needs to specify the parts that are necessary to select the elements required and exclude any elements that are not required. In this example, if all .bread elements are ps or all .external elements are as then the element type a or p would be redundant and should be dropped. But without seeing your actual HTML content, it's not possible to be certain of this in the way that it is possible for the IDs because a given classname can legitimately be applied to multiple elements of multiple type.

于 2013-06-07T13:18:48.940 回答
0

两种方式都可以,而且对速度的影响可能很小。但是,没有必要将元素添加到您的规则中,我鼓励您不要这样做,因为它有助于您的规则变得更加可重用——这是您应该始终追求的目标。

您还应该避免使用位置来定位元素。例如.sidebar h3。相反,将一个类添加到这些h3s 并以该类为目标。这意味着您可以重用您在其他地方编写的样式,只需添加类即可。这些都是面向对象 CSS 的概念,将通过减少重复代码的数量来帮助您编写更高效的 CSS。

于 2013-06-07T13:15:00.457 回答
0

更长的选择器,例如div#container div#content p.bread a.external { }确实需要更长的时间,是的。但它们很少对油漆时间产生任何明显的影响。

此外,由于 ID (应该是)始终是唯一的,div#container并且div#content实际上应该分别是#container和。#content

于 2013-06-07T13:13:03.167 回答
0

当与 ID 选择器 ( ) 一起使用时,元素是多余的(或者应该是多余的#),因为您的 DOM 应该只包含元素的唯一 ID。

还值得注意的是,应该使用类来捆绑相同元素的样式。如果您的 DOM 中有两个.bread元素,但希望它们的样式不同,您应该考虑使用不同的类名。

于 2013-06-07T13:17:59.460 回答