伪造:has()“父选择器”仅使用CSS

时间:2014-06-24 18:37:41

标签: html css css-selectors

长期以来,人们一直被誉为许多选择问题的答案,甚至有些人认为完全没有必要,但选择者等级4伪类 :has() ,更为人所知作为父选择器,根据 W3 Spec <的最新修订版,来自第4级的将不会在CSS中实现/ strong>即可。原因是它效率低下且已被JavaScript功能覆盖。

考虑到这一点,我一直在考虑如何使用纯CSS伪造这种效果。下面我提供了一种方法,Q&amp; A风格,以实现作为答案的效果,但想知道是否有其他方法。具体来说,更有效的CSS实现,或响应式CSS实现。

3 个答案:

答案 0 :(得分:10)

在Gecko和WebKit中,某些选择器可以使用<label for>和位于任何位置的关联<input>元素“跳转”。这种做法不可靠,但仍然很有趣。

&#13;
&#13;
#before {
    left: -9999px;
    position: absolute;
}
#parent {
    padding: 0.5em;
}
#before:hover + #parent {
    background-color: #123;
    color: white;
}
#label {
    border: 0.1em solid #678;
    border-radius: 0.2em;
    display: inline-block;
    padding: 0.5em;
}
&#13;
<input type="checkbox" id="before">

<div id="parent">
    <label for="before" id="label">Hover over me!</label>
</div>
&#13;
&#13;
&#13;

(如果使用Chrome,则可能需要点击一次。)

答案 1 :(得分:2)

<强> JSFiddle Example

对于这个方法,我创建了一个静态大小的固定位置容器元素,其中包含一个子元素,占用200px乘200px。

然后,我添加了两个绝对定位的元素(.glass1.glass2)来模拟玻璃窗格(&#34;你可以看,但你不能触摸&#34;) ,我在它们上使用z-index,以便它们覆盖容器元素的剩余空间。

添加这些玻璃窗格是为了模拟没有任何事情发生的影响,除非你将鼠标悬停在孩子身上。否则,这种方法不会模仿父选择器的行为;它只是一个正常的:hover实现。

此时,只需向容器添加:hover属性,但不会影响子元素所覆盖的区域。

&#13;
&#13;
.container {
    background: lavender;
    top: 0;
    left: 0;
    position: absolute;
    width: 600px;
    height: 400px;
    z-index: 0;
    border: 1px solid black;
}
.glass1 {
    width: 400px;
    height: 200px;
    position: absolute;
    left: 200px;
    top: 0;
    z-index: 2;
}
.glass2 {
    width: 600px;
    height: 200px;
    position: absolute;
    z-index: 3;
    top: 200px;
    left: 0;
}
.hover {
    background: lightblue;
    width: 200px;
    height: 200px;
    margin: 0;
    position: absolute;
}
.container:hover:not(.hover) {
    background: seagreen;
}
&#13;
<div class="container">
    <div class="hover">Hover over me. Change my parent.</div>
</div>
<div class="glass1"></div>
<div class="glass2"></div>
&#13;
&#13;
&#13;

这种实现的明显问题是它的静态性和缺乏响应性。一个更实践的手可能允许一定程度的响应。

编辑:ZachSaucier的More efficient version

答案 2 :(得分:1)

这是我在评论中提到的一个例子 - 而不是在实际作为子元素的情况下悬停的元素,它只是之前的的兄弟姐妹应该受影响的元素 - 相邻兄弟组合器用于影响第一个元素悬停时的第二个元素,

.hover:hover ~ .container {
    background: red;
}

http://jsfiddle.net/95HKP/5/embedded/result/

由于不需要额外定位元素“掩盖”第二个元素,因此它不会遇到上述缺点,例如第二个元素中的实际内容无法通过鼠标光标进行选择或其他形式的交互。只有“触发”元素本身绝对位于另一个元素上 - 而不是使用绝对定位,其他方法也可以实现,f.e。否定margin-bottom (我已经引入了一个“spacer”元素来保持内容不被绝对定位的元素重叠 - 这不一定需要额外的元素,例如使用::before创建的伪元素也可以。)

同样,这也是“父选择器” - 只是通过使用一些定位和其他广泛可用的选择器来实现某种效果