【问题标题】:Should CSS selectors include elements from the DOM?CSS 选择器是否应该包含来自 DOM 的元素?
【发布时间】:2013-06-07 13:09:50
【问题描述】:

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

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

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

而不仅仅是:

#container #content .bread .external { }

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

.external { }

我个人编写我的选择器,例如

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

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

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

【问题讨论】:

  • “最快解析”的方式并不总是“正确”的方式。
  • 明智的话@BoltClock。你会说什么是“正确”的方式?

标签: css css-selectors


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案2】:

    我的 2 美分

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

    我同意 lonesomeday 的观点,即“性能差异将很小”,但链中的每一个添加元素都需要再进行一次检查。

    所以想想如何减少它


    需要身份证吗?

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

    1. 如果所有页面都是#container #content,则删除#container
    2. 此外,如果所有p.bread 元素 #content 内,则也删除该选择器。

    是否需要元素名称?

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

    需要类的继承关系吗?

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

    【讨论】:

      【解决方案3】:

      是的,你的老师错了。

      从你的例子:

      div#container div#content p.bread a.external { }
      
      1. 鉴于 DOM 文档中的 ID必须是唯一的,因此永远不需要在选择器中指定多个 ID。所以上面包含#container#content 的选择器仅仅按照这个标准就是错误的。

      2. ID 是引用元素的最有效和最直接的方式。同样,它是独一无二的且可立即访问,因此无需以任何方式对其进行限定,因此在 #container#content 前面添加 div 是多余的。

      3. 选择器p.breada.external 的另外两部分很可能是错误的,但对于这些来说并不是那么明确。

        选择器只需要指定选择所需元素所需的部分,并排除任何不需要的元素。在此示例中,如果所有.bread 元素都是ps 或所有.external 元素都是as,那么元素类型ap 将是多余的并且应该被删除。但是如果没有看到您的实际 HTML 内容,就不可能像 ID 那样确定这一点,因为给定的类名可以合法地应用于多种类型的多个元素。

      【讨论】:

        【解决方案4】:

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

        此外,由于 ID (假定)始终是唯一的,div#containerdiv#content 实际上应该分别是 #container#content

        【讨论】:

          【解决方案5】:

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

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

          【讨论】:

            【解决方案6】:

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

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2013-05-01
              • 2023-03-12
              • 2017-12-10
              • 2013-10-17
              • 1970-01-01
              • 2011-02-07
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多