CSS 选择器,它以悬停元素的五个相邻同级元素中的每一个为两个方向的目标



我有一个SVG,它的内容与这个问题无关,但是重要的是要知道它包含以下结构:

<svg id='my-svg-id'>
...
<path d="M138.331827,110.420944 ... 110.420944" id="Fill-80" fill="#07032E" />
<path d="M139.331827,110.420944 ... 110.420944" id="Fill-80" fill="#07032E" />
<path d="M140.331827,110.420944 ... 110.420944" id="Fill-80" fill="#07032E" />
<path d="M141.331827,110.420944 ... 110.420944" id="Fill-80" fill="#07032E" />
...
</svg>

所以它归结为一个svg标签,父标签,它包含几个路径标签,子标签。

我想在悬停时对这些路径进行动画处理。更具体地说,我的目标是在悬停(:hover(的路径元素上应用css动画,并且相邻的同级+-5(如果有的话(。

因此,这意味着悬停的元素本身+最多10个其他元素将被定位并因此进行动画处理。

我已经阅读了一些有关相邻兄弟姐妹组合的信息,但到目前为止似乎无法弄清楚。

然而,我设法做的是针对悬停的元素,它是最近的兄弟姐妹,如下所示:

path:hover + path {
animation: my-animation 0.5s linear infinite both;
}

请提供答案或评论任何有用的信息。尽管非常欢迎,但我不希望您提供完全有效的代码示例。任何有用的信息,任何形式的,都非常感谢。

因为只有一个后面的兄弟组合器('~'(,而没有前面的兄弟姐妹组合器,也没有一般的兄弟姐妹组合器,我们必须做一个技巧:我们需要所有路径的列表两次。第一个是我们在悬停时做出反应的路径,第二个是相邻的路径,它们会改变颜色(并且最初是隐藏的(

邻接必须手动引入,因为 CSS 中没有这样的概念。我用data-adjacent-to属性来做这件事

这是概念证明,需要微调:

.path {
transition: color 1s;
stroke: black;
stroke-width: 1px;
fill: currentcolor;
}
.path:hover {
color: black !important;
}
.path.hide {
pointer-events: none;
opacity: 0;
position: relative;
z-index: 1;
color: transparent;
}
#path-1:hover ~ [data-adjacent-to*="path-1"] {
color: gray;
opacity: 1;
}
#path-2:hover ~ [data-adjacent-to*="path-2"] {
color: gray;
opacity: 1;
}
#path-3:hover ~ [data-adjacent-to*="path-3"] {
color: gray;
opacity: 1;
}
#path-4:hover ~ [data-adjacent-to*="path-4"] {
color: gray;
opacity: 1;
}
#path-5:hover ~ [data-adjacent-to*="path-5"] {
color: gray;
opacity: 1;
}
#path-6:hover ~ [data-adjacent-to*="path-6"] {
color: gray;
opacity: 1;
}
#path-7:hover ~ [data-adjacent-to*="path-7"] {
color: gray;
opacity: 1;
}
#path-8:hover ~ [data-adjacent-to*="path-8"] {
color: gray;
opacity: 1;
}
<svg width="200" height="200" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >
<symbol id="lib-path-1" viewBox="0 0 100 100" >
<path d="M50 50 l0 -50 l50 50"/>
</symbol>
<symbol id="lib-path-2" viewBox="0 0 100 100" >
<path d="M50 50 l50 0 l-50 50"/>
</symbol>
<symbol id="lib-path-3" viewBox="0 0 100 100" >
<path d="M50 50 l0 50 l-50 -50"/>
</symbol>
<symbol id="lib-path-4" viewBox="0 0 100 100" >
<path d="M50 50 l-50 0 l50 -50"/>
</symbol>
<symbol id="lib-path-5" viewBox="0 0 100 100" >
<path d="M100 0 l0 50 l-50 -50"/>
</symbol>
<symbol id="lib-path-6" viewBox="0 0 100 100" >
<path d="M100 100 l-50 0 l50 -50"/>
</symbol>
<symbol id="lib-path-7" viewBox="0 0 100 100" >
<path d="M0 100 l0 -50 l50 50"/>
</symbol>
<symbol id="lib-path-8" viewBox="0 0 100 100" >
<path d="M0 0 l50 0 l-50 50"/>
</symbol>

<use class="path" id="path-1" xlink:href="#lib-path-1" style="color: green" />
<use class="path" id="path-2" xlink:href="#lib-path-2" style="color: red" />
<use class="path" id="path-3" xlink:href="#lib-path-3" style="color: blue" />
<use class="path" id="path-4" xlink:href="#lib-path-4" style="color: orange" />
<use class="path" id="path-5" xlink:href="#lib-path-5" style="color: pink" />
<use class="path" id="path-6" xlink:href="#lib-path-6" style="color: silver" />
<use class="path" id="path-7" xlink:href="#lib-path-7" style="color: gold" />
<use class="path" id="path-8" xlink:href="#lib-path-8" style="color: brown" />
<use class="path hide" xlink:href="#lib-path-1" data-adjacent-to="path-2 path-4 path-5"/>
<use class="path hide" xlink:href="#lib-path-2" data-adjacent-to="path-1 path-3 path-6"/>
<use class="path hide" xlink:href="#lib-path-3" data-adjacent-to="path-2 path-4 path-7"/>
<use class="path hide" xlink:href="#lib-path-4" data-adjacent-to="path-1 path-3 path-8"/>
<use class="path hide" xlink:href="#lib-path-5" data-adjacent-to="path-1"/>
<use class="path hide" xlink:href="#lib-path-6" data-adjacent-to="path-2"/>
<use class="path hide" xlink:href="#lib-path-7" data-adjacent-to="path-3"/>
<use class="path hide" xlink:href="#lib-path-8" data-adjacent-to="path-4"/>
</svg>

选择接下来的 5 个元素

我做了一个快速的尝试(非常粗糙(,并得出了以下内容:https://jsfiddle.net/dtwavyeq/4/

为了影响接下来的 5 条路径,我必须执行以下操作:

path:hover + path {
animation: example 0.1s linear infinite both;
}
path:hover + path + path {
animation: example 0.1s linear infinite both;
}
path:hover + path + path + path {
animation: example 0.1s linear infinite both;
}
path:hover + path + path + path + path {
animation: example 0.1s linear infinite both;
}
path:hover + path + path + path + path + path {
animation: example 0.1s linear infinite both;
}

选择以前的元素

不幸的是,没有办法使用 CSS 来做到这一点。 根据答案@https://stackoverflow.com/a/1817801/1688441.

> Yunzen的解决方案是一个仅使用CSS的出色解决方案,但它确实需要您编辑HTML/SVG代码。

你可以考虑用JavaScript来做这件事,因为它会导致更少的代码。

您可以使用 JS DOM 节点的上一个同级和下一个同级属性:

var paths = document.querySelectorAll('path');
paths.forEach(e => {
e.onmouseenter = function() {
this.previousSibling.previousSibling.classList.add('hovered');
this.previousSibling.classList.add('hovered');
this.classList.add('hovered');
this.nextSibling.classList.add('hovered');
this.nextSibling.nextSibling.classList.add('hovered');
}
e.onmouseleave = function() {
this.previousSibling.previousSibling.classList.remove('hovered');
this.previousSibling.classList.remove('hovered');
this.classList.remove('hovered');
this.nextSibling.classList.remove('hovered');
this.nextSibling.nextSibling.classList.remove('hovered');
}
});

当然,你可以想出各种各样的方法来使这段代码更具可读性,但希望你能明白这个想法。 此外,您应该添加检查以查看上一个同级和下一个同级属性是否不为 null,现在前 2 条和后 2 条路径将给出错误。

对于 CSS:

.hovered {
animation: my-animation 0.5s linear infinite both;
}

相关内容

最新更新