我应该多久在CSS中使用子/兄弟选择器?

时间:2013-11-23 03:35:03

标签: html css css-selectors

我正在与其他开发人员合作,我希望他们能够理解我在接管特定项目时编写的HTML / CSS代码。 所以,我有这个简单的片段。

<section>
<div class="twocolumn">
    <div>
        <p>Hello</p>
        <a href="#">Press</a>
    </div>
    <div>
        <p>Nice one!</p>
        <a href="#">Click</a>
    </div>
</div>
</section>

要在此代码中定位内部元素,这是更好的做法,使用从最外层元素(部分)开始的选择器,以便其他开发人员将理解元素的“排列”:

section > div div:nth-child(1) p + a {
    ...
}

或者我应该使用这样的类:

.twocolumn a {
    ...
}

您认为哪个更容易阅读(对于其他开发人员)?每个流程的优缺点是什么?你能举出其他例子吗?

4 个答案:

答案 0 :(得分:4)

首先,你的选择器不合适。 .twocolumn a本身会匹配a个元素,因为您没有指定只查看div:nth-child(1)

除此之外。请记住,CSS选择器中组合器的唯一目的是在标记中建立两个或多个元素之间的关系。因此,一个兄弟组合子说“这个元素必须是跟随那个元素的兄弟”,一个后代组合子说“这个元素必须包含在那个元素中”,而一个儿童组合子说“这个元素是那个元素的孩子”。如果您不需要强制执行两个元素之间的特定关系(通常这来自您对页面结构的假设),那么您可能不需要在选择器中指定那么多元素。

以您的代码段为例:如果您可以保证该结构中的每个内部div都有p后跟a,则可以省略p + 。如果a可以出现在其他位置,并且您希望确保仅a直接跟在p后面,那么您只需要它。

接下来,如果您可以保证每个section > div都有类.twocolumn,那么您可以使用类选择器。我发现根据类名称应该描述的内容真的不太可能,但假设是这种情况,那么如果你想选择第一个a,你至少需要div:nth-child(1)

.twocolumn div:nth-child(1) a {
    ...
}

我无法提供更一般的建议,因为它实际上取决于您的要求以及您正在使用的内容。但我会说你应该保持平衡,即不要完全依赖你的标记结构,尽可能使用类和ID指向关键元素。正如另一个答案中所提到的,您希望避免紧密耦合CSS和HTML,导致您必须更改选择器以反映HTML结构中的任何潜在更改。

但是仍然考虑到结构中的一小部分可能的变化,就像我上面提到的p + a示例一样,所以你最终不会过度使用类并不必要地膨胀你的标记。 Web应用程序如今非常动态,CSS为您提供了一种相当强大的语法,因此不要害怕使用它并教育其他人如何使用它。

答案 1 :(得分:2)

简答:从不。

好吧,从来没有完全。选择器越复杂,CSS代码与HTML的耦合就越多。更改HTML,然后您必须反映CSS选择器代码中的更改。每次更改来回都意味着更多的手动工作,以确保您的设计不会被打破。

理想情况下,您希望尽可能多地使用CSS类,而不超过一个级别的子选择器。最好使用>运算符来定位直接子项,而不是依赖于祖先选择器。

这显然是我的观点,但我已经开发了超过10年的网站。一个好的理念(我从中学到大部分内容)来自SMACSS。

请记住,它并不总是关于标记。在干净的标记和理智的CSS代码之间有一个收支平衡点。我刚刚发现,通过使用多个CSS类,您可以获得最大的可重用性。

答案 2 :(得分:1)

作为一般最佳实践,较不具体的选择器更好。在这种情况下,您可能不希望在<a> div中定位每个.twocolumn标记。一个更具体的选择器最有可能是最好的,这取决于你实际上要做什么。如果可能,您应该在<a>代码中添加一个类,并定位.twocolumn a.classname

答案 3 :(得分:0)

越具体的选择器处理得越快。

在这种情况下:

section > div {}

样式解析器将查看元素及其直接父级。那是O(1)计算复杂的任务。

但是这个

section div {}

在最坏的情况下会有O(d)复杂度,其中d是DOM树的深度。