如何在CSS中具有任意选择器? [英] How to have an arbitrary selector in CSS?

查看:70
本文介绍了如何在CSS中具有任意选择器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在CSS规则中添加任意选择器?

How do I add arbitrary selectors in CSS rules?

例如,假设我想使 .effect 类中的每个项目都变成红色,如果用户将鼠标悬停在 #target 上.我将如何实施呢?是否有一个健壮的方法来做到这一点?我知道诸如在 #target 内嵌套 .effect 或使用同级选择器 + 之类的东西,但是所有这些这些依赖于某种构造HTML的方式.

For instance, say I want to make every item of the .effect class turn red if the user hovers over#target. How would I implement this? Is there a robust approach to this? I know about things like nesting .effect inside #target or using the sibling selectors ~ and +, but all of these rely on a certain way of structuring the HTML.

这有可能吗?似乎是相对简单的事情.如果不可能的话,那有什么理由吗?

Is this possible at all? It seems like something relatively straight forward. If it's not possible, is there any reason it isn't?

我不想使用Javascript.

I do not want to use Javascript.

推荐答案

不,你不能.

在可预见的将来也不要期望它.让我们看看为什么!

从使用CSS引擎的人的角度来看,选择器实际上是向后评估.这无疑是CSS的一个相当有趣且鲜为人知的方面.尽管CSS选择器规范并未直接定义实现行为,但在定义所有选择器时都应牢记这一点.没有创建可以随意在DOM周围跳转的层次/结构"选择器,因为与我们今天的选择器相比,这会导致主要的性能问题.

From the point of view of someone who works on a CSS engine, selectors are actually evaluated backwards. This is certainly a rather interesting and less known aspect of CSS; Whilst the CSS selector specification does not directly define the implementation behaviour, all selectors are defined with this in mind. No hierarchial/ 'structural' selector has been created which can arbitrarily jump around the DOM as that would cause major performance issues in comparison to what we have today.

例如,让我们采用以下选择器:

So, for example, let's take the following selector:

#target:hover .effect

这要求具有 effect 类的元素是ID为 target 的元素的子元素(在任何深度)因为选择器引擎首先通过匹配具有 effect 类的元素开始,然后继续向后工作,所以增加DOM来查找ID为目标下一个.

This requires that an element with a class of effect is a child (at any depth) of an element with an ID of target because the selector engine starts by matching elements with a class of effect first, then proceeds to work backwards, stepping up the DOM looking for a parent element with an ID of target next.

跳转到父节点非常快.向前评估此结果将涉及测试ID为 target 的任何元素的所有子元素,这会大大提高性能.

Jumping to the parent node is extremely fast. Evaluating this in the forward direction would involve testing all children of any element with an ID of target which is considerably more performance intensive.

CSS评估的这一特性对于性能而言自然很重要;在最坏的情况下,上述选择器只会冒泡到DOM的根,在此过程中仅测试少数元素.直接子选择器 a>b ,例如,仅测试直接父级,然后停止.

This characteristic of CSS evaluation is naturally important for performance; at the worst case, the above selector will only bubble up to the root of the DOM, testing only a handful of elements along the way. The direct child selector, a > b, only tests the direct parent and then stops, for example.

为了获得更高的性能,选择器的结构被烘焙"到DOM中.当然,对此并没有达成共识,即每个CSS引擎的处理方式都不同,但是大致是在选择器的DOM结构匹配时(即,我们发现了一个具有 effect 类的元素,标识为 target 的任何父级)选择器在DOM中都已记录为已匹配,而与 #target 上的悬停状态无关.当 #target 上的悬停状态发生变化时,它仅会碰触在该元素上烘焙的所有选择器-然后,这可能会触发整个选择器激活或停用.这样,例如,当鼠标四处移动时,我们就不会不断测试元素的质量.

For even further performance, the structure of a selector is 'baked' into the DOM. There certainly isn't consensus on this, i.e. every CSS engine does it differently, but roughly when the DOM structure of a selector matches (i.e. we have found an element with a class of effect and any parent with an id of target) the selector is recorded as having matched in the DOM, regardless of the hover state on #target. When the hover state on #target changes, it then simply bumps all the selectors that are baked at the element - this may then trigger the whole selector to activate or deactivate. This way we're not constantly testing masses of elements when the mouse moves around, for example.

简而言之,如果它可以随意地绕过DOM,那么这一切都不起作用.进入/离开DOM的元素可能会影响DOM完全独立部分中的选择器,因此样式引擎可能会检查整个DOM以使该索引保持最新.

In short, none of this works either if it could arbritarily jump around the DOM. Elements entering/ leaving the DOM could affect selectors in entirely separate parts of the DOM, so the style engine would potentially be checking the entire DOM to keep this index up to date.

还考虑我们可以在元素之前进行测试,但不能测试之后(当向后评估时):

Also consider that we can test for elements before something, but not after (when evaluated backwards):

h1 + h2
h1 - h2 /* ..? Doesn't exist! */

这是因为当我们从'h2'元素开始测试此特定选择器时,紧随其后的DOM 可能尚未真正加载.一旦元素进入DOM,要么是因为它只是从传入的HTML中解析出来的,要么是通过脚本添加的,因此我们开始检查其匹配的选择器.这意味着我们不能依赖原始HTML中元素之后的任何可用内容,因此同样,这对于任何故意的DOM跳跃也是一个障碍.

This is because when we test this particular selector starting against a 'h2' element, the DOM following it might not actually be loaded yet. As soon as an element enters the DOM, either because it's just been parsed from the incoming HTML or it has been added via scripting, we begin checking for which selectors it matches. That means we can't depend on anything being available after the element in the raw HTML, so again this would also be a block for any arbritary DOM hopping.

当前无法实现,并且不太可能很快添加,因为它会使CSS实现的多个性能特征失效.但这并不是说它不会被添加.W3C确实意识到硬件变得越来越强大,因此总有一个观点认为作者的便利会赢得实现性能方面的考虑.

It's currently not possible and it's unlikely to be added any time soon because it invalidates multiple performance characteristics of CSS implementations. That's not to say that it won't be added however; the W3C does appreciate that hardware is getting ever more powerful, so there is always a point at which author convenience will win over implementation performance considerations.

因此,将其进一步放在问题的上下文中,看看由@Marvin创建的小提琴了解当前使用选择器的功能.

So, putting this a little further into context of the question, take a look at this fiddle created by @Marvin to see what's currently possible with selectors today.

这篇关于如何在CSS中具有任意选择器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆