【问题标题】:How long can a CSS selector be?CSS 选择器可以有多长?
【发布时间】:2018-09-22 10:47:26
【问题描述】:

一个 CSS 选择器可以有多长?

我对“规范”所说的内容不太感兴趣,而是对浏览器实际可以处理的内容感兴趣。到目前为止,我只知道一个浏览器会阻塞(非常)长的选择器;铬。

编辑:Example where Chrome does not apply CSS rule to some countries, e.g. the US, Turkey, Syria and the UKthe CSS。有 7 个选择器,至少 #5 对于某些浏览器来说太长了。

【问题讨论】:

  • “我对规范所说的不太感兴趣” 没关系,因为规范没有说明任何内容。
  • @ScottS:谢谢,但你确定你的结果与可用内存无关吗?因为我可以看到大约 2048 个红色 div。可能与其他浏览器相比,Chrome 分配的可用内存百分比较小
  • @onetrickpony: 2048 与我在关于从字符串中删除 > * 的段落中获得的第三个小提琴链接(“它在 2049 年开始失败”)相匹配(不确定你在看什么去测试)。因此,如果它确实与记忆有关(我不确定),那么我们可能会匹配记忆。

标签: css cross-browser css-selectors


【解决方案1】:

ScottS concluded Chrome 处理 1366 个选择器。为什么是 1366?

1366 * 3 = 4098

为什么是 3?此选择器中有 3 个组件:.y1366 .c1 > *4098 是选择器部分总数的限制。 Proof here(我只在第一个选择器中添加了> *,它标记了 4095 个元素而不是 4096)。

我的测试

一组 4096 个选择器将完全忽略其余的选择器。示例:

.z .y1, .z .y2, .z .y3,..., .z .y3{background-color:red}

Live Example

在示例中,每个选择器都有 2 个组件:

.y1 > *
Component 1: .y1
Component 2: *

第 2048 位之后的每个选择器都会被忽略。为什么是 2048 年?因为每个选择器有 2 个组件,限制为 4096。不服气?

Next example

在上面的例子中,每个选择器都有一个组件:

.y1, .y2, .y3 ...

只有前 4096 个选择器有效。 Chrome 没有限制,所以所有的选择器都应该可以工作。然而,在某一点之后,剩余的选择器将被完全忽略。这个错误至少存在 2 年。 IE9 及以下的选择器限制为 4095 个。

错误 2

一大群选择器,其中一个有两个组件.bdy .y1 4096 个组合组件后会导致类bdy 的元素受到影响。

示例

.bdy .y1, .y2, .y3, ... .y4097{background-color:red}

上面的 CSS 选择器组导致类名 bdy 的元素应用 background-color:red。条件是在一个包含两个组件的选择器之后有 4096 个选择器。

Live example

在上面的示例中,由于使用了 4096 选择器(在选择器以类名为 bdy 且类名为 y1 的元素的子元素为目标之后),主体被应用为红色。该错误会导致父级受到影响。

.bdy .y1 中,元素.y1(在父.bdy 下)被定位,但元素bdy 也受到影响。如果将两个组件选择器向前移动 10 个位置,则可以再创建 10 个选择器,直到出现此错误。这意味着当组件选择器的总数达​​到 4096 时会出现该错误。

解决方案

他们不会修复它。仅当所有选择器都在一行上时才会发生此问题。所以就这样做吧:

.c1 .y1,
.c1 .y2,
.c1 .y3...

代替:

.c1 .y1, .c1 .y2, .c1 .y3...

【讨论】:

  • 看起来,在 chrome 63 中,4096 个选择器组不再是条形
  • 在 chrome 80 中,此限制提高到 8196。
  • 而且 bug 2 似乎不再是这种情况了。
【解决方案2】:

纯粹是一些观察

如果我删除通过.y2010 .au > *(前97 个)设置的所有选择器,那么.y1990 .us > * 设置首先出现。这似乎意味着一个限制是问题。如果我计算正确,Chrome 的代码限制似乎是 1366(这些数字来自于将其导入到带有逗号分隔的 excel 电子表格中,然后对单元格进行计数)。因此,将其分成 2 或 3 个较小的组可能会解决问题。

我无法完全解释的一件事是在 Chrome 开发者工具中,如果我隐藏了 .land { fill: lightgray},那么 .us 的正确颜色就会出现,而其他颜色则会显示出来,这几乎表明它是“隐藏”或“以某种方式覆盖”颜色,这不太有意义。当.land 被隐藏时,我无法弄清楚它在哪里得到正确的颜色。

一些实验

第一轮 - 不仅仅是一组选择器

但是,似乎它可能是更多的字符而不是选择器的总数,因为 Chrome 处理 these 1366 selectors fine(感谢 onetrickpony 最初的小提琴帮助我提出了这个测试示例)和 even one more to 1367 is okay

但是将 html 和 css 设置为与 更接近 与您的实际用例it works at 1366 items 匹配,但我得到了红色的奇怪泄漏如果它是1367 items,则在Chrome中将body本身。 (也许这与我对上面提到的.land 颜色奇怪的体验有关,用于您的实际用例。)

如果我删除 css 的 > * 部分然后是 1367 items again works,所以问题不是 * 选择器本身,因为如果将其更改为 div it fails again。但是,* 选择器可能会导致奇怪的颜色泄漏,因为在此示例中,我的 Chrome it begins to fail at 2049 上删除了 > *,因为我预计它会失败(即在 div 中失去颜色,而不是有颜色像以前的故障一样泄漏)。请注意,这个包含 50,000 个元素的示例(警告:如果加载它,您可能会收到“停止脚本”警告,只需绕过一两次,它就会完成加载still works in Firefox and IE10 for me。即使我在both browsers 中添加了> * 也是如此,而在Chrome 中它又恢复为背景泄漏(这似乎进一步证实了* 选择器可能与奇怪的颜色行为有关) .

第二轮 - # of Selectors 和 # of Characters 的一些组合

根据上面的一个失败示例,我计算出失败的字符总数大约为 20500。但是我可以得到50002 characters without an issue here100002 here——所以它必须是X 个选择器 和Y 个字符 的某种组合,这会产生限制。在this example 中,我可以在4097 元素失败之前通过red 背景的4096 个元素,因为我减小了各个选择器的大小。减少必须与字符串中的选择器数量成比例,因为只有两个选择器仍然允许500,006 characters in one of them to still work for both。 4096 个可能是选择器数量的真正“最大”限制,因为当我将选择器减少到每个只有两个字符(加上 ., 和空格)时,我仍然是 succeed at 4096 ,但fail at 4097

我觉得有趣的是,最后一次测试集失败发生在 4095 号码附近,Internet Explorer gives as the maximum number of selectors that can be done via the IHTMLStyleSheet::addRule method。这显然只是该方法的一个限制,因为 IE10 与上述测试中的 4097 数字标记或 Chrome 失败的任何测试(都没有使用该方法生成选择器)运行良好。我不知道为什么与 IE 浏览器 Chrome 失败的数字如此接近,但很有趣。

结论

没有确切的幻数,但鉴于上述实验,与 Firefox 或 IE10 相比,Chrome 的选择器大小的选择器数量似乎确实存在一些较小的字符限制。这显然不是选择器的实际数量,也不是实际的总字符数,而是两者之间的某种组合,其中最多出现 4096 是限制,但如果选择器字符串更长(作为初始在1366 之后失败的示例。

【讨论】:

  • 哇,这只会变得更有趣...所以我想底线是,如果出于任何原因,您超过 1000 个左右的选择器,您需要非常非常仔细地进行测试。 (或者分解选择器。或者找到另一种实现你想要的方法。)
  • 对我来说,最好使用后端编程来确定年份和国家/地区之间的匹配,然后为您希望在该年份的国家/地区进行颜色编码动态设置特定的类名。然后你只是在处理什么,比如 7 个类,而不是这数千个选择器。 (当然,您已经拥有所有信息,因此它甚至不必是动态的,但静态设置它们可能需要更多时间。)
  • 可选地,如果一个国家/地区在一个级别上拥有大多数年份,只需将其作为该国家/地区的默认设置,并在某些年份覆盖它,只有那些是例外的,这将大大减少数量选择器。
  • 斯科特斯:当然。不过,这里的重点是允许第三方用户将地图添加到他们的网站,并为他们提供一种相对简单的着色方式。以及允许缓存的静态地图...
  • @ScottS 我做了更多的测试,发现了模糊之处。检查我的答案
【解决方案3】:

CSS 选择器没有最大长度。您可以根据需要定义。但是,应该考虑的重要事情是file size

IE 将读取的最大kb size288kb,该标记之后的任何样式都不会被读取。- Internet Explorer CSS File Size Limi

此外,每个样式表的最大选择器限制为 4095 css 规则,31 样式表可以链接到一个文件中 - IHTMLStyleSheet::addRule method

最后一个大问题是带宽。似乎css文件通常是轻量级的。但是,如果有 31 个名称很长的 css 规则,则可能会降低性能。

【讨论】:

  • 有趣的是,在我在 my answer 中使用 Chrome 进行的实验中,最多允许的最大选择器是 4096,仅比 IE 规则 4095 少一个数字。但是 IE 规则也仅针对 addRule 方法,因为在那些相同的实验中(我不使用该规则生成选择器),IE10 处理的选择器数量超过了这个数量。 Chrome 在最好的情况下以接近相同的数字失败似乎不仅仅是巧合。
猜你喜欢
  • 1970-01-01
  • 2021-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-10
  • 2012-06-19
  • 2020-10-09
相关资源
最近更新 更多