我可以使用不存在的CSS类吗?

我有一个表,我显示/隐藏一个完整的列由jQuery通过CSS类不存在:

<table>
<thead>
<tr>
<th></th>
<th class="target"></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td class="target"></td>
<td></td>
</tr>
<tr>
<td></td>
<td class="target"></td>
<td></td>
</tr>
</tbody>
</table>

有了这个DOM,我可以通过jQuery: $('.target').css('display','none');在一行中做到这一点

这是完美的工作,但它是有效的使用CSS类没有定义?我应该为它创建一个空类吗?

<style>.target{}</style>

有没有副作用或者有没有更好的方法?

22212 次浏览

你可以使用一个没有样式的类,这是完全有效的HTML。

CSS文件中引用的类不是类的定义,它被用作选择器的规则用于样式化目的。

使用没有样式的类不会产生不良影响。的确,CSS的部分用处在于它与标记分离,可以设置或不设置元素/类等的样式。根据需要。

不要认为它们是“CSS类”。把它们看作是“类”,如果需要的话,CSS也会使用它们。

当您在HTML中添加类时,类将被定义,因此您的解决方案完全没问题

“CSS类”是一个用词不当;class是一个属性(或属性,在脚本方面),你分配给HTML元素。换句话说,你在HTML中声明类,而不是在CSS中,所以在你的情况下,“目标”类实际上存在于那些特定的元素上,并且你的标记是完全有效的。

这并不意味着你必须在HTML中声明一个类,然后才能在CSS中使用它。请看ruakh的评论。选择器是否有效完全取决于选择器语法, CSS有自己的处理解析错误的规则集,这些都与标记无关。本质上,这意味着HTML和CSS在有效性方面是完全独立的

一旦你理解了这一点,你就会清楚地看到,在样式表中不定义.target规则是没有副作用的。2当你给元素分配类时,你可以在样式表或脚本中通过这些类引用那些元素。双方都不依赖对方。相反,它们都引用标记(或者更准确地说,它的DOM表示)。即使使用JavaScript来应用样式,这个原则也适用,就像在jQuery一行程序中所做的那样。

当您使用类选择器编写CSS规则时,您所说的一切都是“我想将样式应用于属于该类的元素”。类似地,当您编写一个脚本来根据某个类名检索元素时,您就是在说“我想对属于这个类的元素做一些事情”。是否有元素属于所讨论的类完全是一个单独的问题。


1 这也是为什么一个CSS ID选择器匹配all元素与给定的ID,而不管的ID是恰好出现一次,还是多次(导致不符合HTML文档)。

2 我所知道的唯一一种情况是,当一些浏览器由于错误而拒绝正确应用某些其他规则时,这样的空CSS规则是必要的;创建空规则将导致出于某种原因应用其他规则。见this answer此类错误的示例。然而,这是在CSS方面,因此应该与标记无关。

没有必要在样式表中定义CSS类。它应该可以正常工作。不过,添加它也无妨。

当你在JavaScript中使用一个类名时,它查看CSS来找到这个类。它直接在HTML代码中查找。

所需要的只是类名在HTML中。不需要在CSS中。

事实上,许多人认为它实际上是在CSS和Javascript中保持独立的类使用是个好主意,因为它允许你的设计人员和编码器独立工作,而不会因为使用彼此的类而妨碍彼此。

(注意,上面的段落显然更适用于大型项目,所以如果你是独自工作,不要觉得你必须走这个极端;我提到它是为了说明这两者可以完全分开)

你可以在不使用它的情况下使用CSS类,但我建议如果你只是为JavaScript/jQuery代码添加CSS类,在它前面加上js-YourClassName,这样前端开发人员就不会使用这些类来设置元素的样式。他们应该明白,这些类可以在任何时候被删除。

根据HTML5规范:

类属性的值必须是由空格分隔的集合 表示元素所属的各种类的标记。 ... 对于作者可以在其中使用的令牌没有其他限制 类属性,但鼓励作者使用 描述内容的本质,而不是描述的价值

同样,在版本4中:

class属性在HTML中有几个角色:

  • 作为样式表选择器(当作者希望分配样式时) 一组元素的信息)。李< / >
  • 用于一般用途的处理 李用户代理。< / >

您的用例属于第二种场景,这使得它成为使用类属性的合法示例。

如果你在HTML元素上应用了一个类,并且这个类没有在CSS中定义,那么它就没有效果。这是一种常见的做法,就像Aamir afridi说的,如果你只是为了js的目的而使用类,用js-作为前缀是一个很好的做法。

它不仅对类有效,而且对html元素的id属性也有效。

使用类来查询元素完全没有问题。我过去常常给这样的类命名sys-前缀(例如,我将把你的类命名为sys-target),以将它们与用于样式化的类区分开来。这是过去一些微软开发人员使用的惯例。我还注意到越来越多的人使用js-前缀来实现这个目的。

如果你不习惯将类用于样式以外的目的,我建议使用Role.js jQuery插件,它允许你使用role属性实现相同的目的,所以,你可以将标记编写为<td role="target">,并使用$("@target")查询它。项目页面有很好的描述和示例。我在大型项目中使用这个插件,因为我真的喜欢只为了样式目的而保留类。

正如很多人提到的,是的,使用没有指定CSS的类是完全有效的,而不是把它们看作“CSS类”,你应该简单地认识到类和ID的语义分别是组和单独的元素。

我想插一句,因为我觉得在这个例子中,一个重要的点没有被提出。如果你曾经需要对可变长度的元素进行可视化操作(在这种情况下,你使用的是表行),那么认识到通过Javascript这样做的成本可能非常昂贵总是有意义的(例如,如果你有数千行)。

在这种情况下,假设我们知道列2总是有可能被隐藏(这是表的一个有意识的函数),那么设计一个CSS样式来处理这个用例是有意义的。

table.target-hidden .target { display: none; }

然后不是使用JS遍历DOM找到N个元素,我们只需要在一个(我们的表)上切换一个类。

$("table").addClass("target-hidden")

通过给表分配一个ID,这将更快,你甚至可以通过使用:nth-child选择器引用列,这将进一步减少你的标记,但我不能评论效率。这样做的另一个原因是我讨厌内联样式,并将竭尽全力根除它!

参考jQuery验证引擎。即使在那里,我们也使用不存在的类在超文本标记语言属性上添加验证规则。因此,使用样式表中没有实际声明的类并没有错。

这里没有人完全提到的一件事是JavaScript(在本例中由jQuery辅助)不能直接修改文档的级联样式表。jQuery的css()方法只改变匹配的元素的style属性集。CSS和JavaScript在这方面是完全不相关的。

$('.target').css('display','none');根本不会改变你的.target { } CSS声明。相反,这里发生的是任何class为"target"的元素现在看起来像这样:

<element class="target" style="display:none;"></element>

没有预先定义CSS样式规则会有什么副作用吗?一点儿也没有呢。

还有更好的办法吗?就性能而言,确实有!

如何提高性能?

不是直接修改每个元素的style,而是可以使用预先定义一个新类,并使用addClass()将其添加到匹配的元素中(另一个jQuery方法)。

基于这个已经存在的JSPerf,它比较了css()addClass(),我们可以看到addClass()实际上要快得多:

css() vs addClass()

我们自己如何实现它呢?

首先,我们可以在新的CSS声明中添加:

.hidden {
display: none;
}

您的HTML将保持不变,这个预定义的类只是为以后使用而存在。

我们现在可以修改JavaScript来使用addClass():

$('.target').addClass('hidden');

当运行这段代码时,不是直接修改每个匹配的“目标”元素的style属性,而是现在添加了这个新类:

<element class="target hidden"></element>

使用新的“hidden”类,此元素将继承CSS中声明的样式,并且您的元素将被设置为不再显示。