CSS选择器最佳实践

时间:2013-10-12 20:59:50

标签: css css-selectors

我又把时间浪费在小事上了。我问自己 - 现在你 - 的问题是:CSS选择器/ HTML标记的“最佳方式”是什么?

我是否会不惜一切代价避免课程,让HTML保持纯净和漂亮,或者我是否想要添加一些课程?

示例,如果我想设置我网站的各种表单按钮的样式,我可以去

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

或者我为所有人添加一个“表单按钮”并执行

.form-button { /*styles */ }

在这个简单的例子中,人们可能不会过多考虑它,但是如果我想用第三个链接来设置 - 语义,而不是表示 - 列表的方式不同,我可以做到这一点

.navigation ul:nth-of-type(2) a:nth-of-type(3) { /* styles */ }

只是给那一个链接一个“不同链接”并使用

.different-link { /* styles */ }

据我所知,在2013年,他们运行的所有计算设备和浏览器应该足够快,技术上次优的CSS选择器不应该对最终用户产生任何差别。

所以最后,它似乎是一个问题'我是否混乱了HTML(使用类)还是混乱了CSS(使用冗长的选择器)?'

对此有何意见?

5 个答案:

答案 0 :(得分:9)

HTML和CSS之间的关注点分离

即使从HTML CSS中外部化应该被认为是独立的,但实际上并不是在插入特定于HTML元素的选择器的情况下。在您的选择器与实际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(article on SmashingMagGitHub repo),减少代码重复和异常。它将提高您的CSS可维护性。

  

重要说明:与任何代码一样,您也不应过度设计CSS。我已经向您展示了如何提供灵活的样式定义,但您不应该总是遵循这些规则。您应该在开始时提供足够的灵活性,并在您离开时根据需要进行重构。但是大多数时候都要把自己放在课堂上。

答案 1 :(得分: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 :(得分:2)

答案:取决于你想要的东西。

说明:

1)使用此选择器input[type="submit"],使用此选项卡将定​​位您网站上的所有提交按钮,当您想要为按钮分组/概括某些属性时,可以使用此选择器,例如{{1 }},font-family等等......如果你想要定位特定的提交按钮,那么使用它是不够的。

2)使用font-weight会定位任何具有类.form-button的元素,因此为了使其更具体,您可以使用.form-button来限制仅用于提交按钮的类。此外,每次需要设置按钮样式时,都需要声明类。

3)input[type=submit].form-button这就是我所说的特定选择器。它只会降低性能。不仅如此,它还会引起严重的特异性问题。您需要在无法更改标记的地方使用此选项。取而代之的是,正如您在问题的最后一点所指出的那样,在您计划定位的元素上调用.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) - 当然比使用超特定选择器唯一地设置按钮样式更好。

答案 3 :(得分:2)

我的简单回答是:如果你在网站上给出相同的布局,你应该通过tagName选择一个元素而不是类或id。

这些问题没有任何意义,因为你自己做了很多假设,并且不断回答它并且不允许在这里提出意见,你应该在http://programmers.stackexchange.com问这个问题。你提到了

  

据我所知,在2013年,他们运行的所有计算设备和浏览器应该足够快,技术上次优的CSS选择器不应该对最终用户产生任何差别。

然后可能是什么问题?

它们之间的唯一区别是它们将使用相同的tagName或相同的类或id对元素进行分组。他们不会做任何其他事情。

现在完全由您来编写代码,因为在许多页面上您可能也想要更改按钮的样式。

使用伪类或选择器是一个好主意,只有当你想要为单个元素的子元素设置样式时,因为提交按钮没有子元素,那么该选择器是模糊的。

直接选择元素

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

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

使用ID或Class

.form-button { /*styles */ }

您可能想要使用它,当您为一个必须更大或更小的按钮设置样式时,我们可以提交结帐按钮。哪个必须与其他不同。

答案 4 :(得分:1)

绝对不是所有这一个。

使用基于属性的css选择器设置提交input样式的第一个示例将引导您在需要非标准或不同外观的按钮的情况下覆盖该声明。因此,在这种情况下使用非常通用的CSS声明可能更好,然后使用类根据用例为按钮添加不同的风格。

Bootstrap为例。

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