CSS / Less / Sass - 当:hover时匹配所有前面的同级元素

8
在这段代码中:
<div id="Container">
  <span class='first'>First</span>
  <span class='second'>Second</span>
  <span class='third'>Third</span>
</div>

我想在鼠标悬停时改变颜色。
  1. 如果 (.first:hover) 那么 .first { color: red; }
  2. 如果 (.second:hover) 那么 .first, .second { color: red; }
  3. 如果 (.third:hover) 那么 .first, .second, .third { color: red; }
这是否可以在不使用JS的情况下实现?我可以接受CSS Hack :)
可能的答案:
  1. @panther 的回答

更难的版本:
<div id="Container">
  <span class='first' style='color: red'>First</span>
  <span class='second' style='color: green'>Second</span>
  <span class='third' style='color: blue'>Third</span>
</div>
  1. 如果鼠标悬停在 .first 上,则将 .first 的颜色设置为粉色。
  2. 如果鼠标悬停在 .second 上,则将 .first.second 的颜色都设置为粉色。
  3. 如果鼠标悬停在 .third 上,则将 .first.second.third 的颜色都设置为粉色。

答案:

  1. @Armfoot的回答似乎很好 :)

@Harry 别说“永远不可能”,也许可以使用 @at-root 属性完成某些操作,所有元素的父元素都具有相同的类... 我还在考虑中。 +1 鼓励挑战 :P - Armfoot
@Harry panther的回答让我感到惊讶,尽管它没有使用span类,但它非常简单。我从来没有想过以那种方式去做! - Armfoot
3
@Armfoot说的是一个小技巧,不是明确的解决方案。而且这种方法只在某些情况下有效,例如对于宽度为100%的块级元素或浮动元素(项目之间没有空格)。有时候可以使用这种方法,但在其他情况下需要使用JavaScript。 - pavel
1
@Armfoot:是的。但是,我仍然会小心地建议将其作为答案,因为虽然它可能对问题中指定的确切要求起作用,但如果该问题是XY问题,则可能不起作用。 - Harry
@123qwe:我已经更新了我的答案,并用不同的颜色为span提供了你的第二个问题的解决方案。 - pavel
显示剩余2条评论
3个回答

7
在CSS中没有前一个兄弟选择器,但是...有时你可以使用已知的选择器来实现。有时候。
<style>
    span {color: #000; display: block;}
    div:hover span {color: #f00;}
    span:hover ~ span {color: #000}
</style>

<div id="FirstSecondThird-Container">
    <span class='first'>First</span>
    <span class='second'>Second</span>
    <span class='third'>Third</span>
</div>

https://jsfiddle.net/45zLdcvr/

这段代码适用于使用blockspan的元素(当然,这些span必须是浮动的)。如果span默认使用display: inline,那么当你将鼠标悬停在div和这些span之间的空白处时,它会闪烁。

更新:
如果每个span都有自己的颜色,那么可以这样做:

span {color: red}
.second {color: green}
.third {color: blue}

span {display: block;}
div:hover span {color: pink;}
span:hover ~ .second {color: green}
span:hover ~ .third {color: blue}

https://jsfiddle.net/45zLdcvr/1/


我认为,我可以使用 border: 1px solid transparent 作为内联(-块/-弹性)跨度的闪烁修补程序。 - 123qwe

1

我认为这可以干净利落地实现你想要达到的目标。

@mixin color_on_hover($class){

@if $class==first {span:nth-of-type(1){color:red;}}
@else if $class==second {span:nth-of-type(1), span:nth-of-type(2){color:red;}}
@else if $class==third {span:nth-of-type(1), span:nth-of-type(2), span:nth-of-type(3){color:red;}}

}
span.first:hover{
@include color_on_hover(first);
}
span.second:hover{
@include color_on_hover(second);
}
span.third:hover{
@include color_on_hover(third);
}

希望这有所帮助!

抱歉Django,这会生成像span.first:hover span.nth-of-type(1)这样的规则,因此它并没有回答问题(而且你忘记了include中的c)。好好想一想。 - Armfoot
是的,这样做的定制级别更高,尝试为每个操作定义不同的颜色,你会发现自己被迫制定这些规则。 - user1389087
这个 fiddle 包含了你的代码生成的 CSS,但并没有提供解决方案... 与 panther 的 fiddle 进行比较,后者是可以正常工作的... - Armfoot

1

我找到了一种使用 SASS 中的 @each 的方法,参考了 panther 的答案

$containerID: FirstSecondThird-Container;
##{$containerID}:hover span {color:pink} 
@each $spanclass, $spancolor in (first, red), (second, green), (third, blue) {
  ##{$containerID} span:hover ~ .#{$spanclass}, .#{$spanclass} {
    color: #{$spancolor};
  }
}

这里是结果(生成的CSS):稍微短一点。

#FirstSecondThird-Container:hover span {
  color: pink;
}
#FirstSecondThird-Container span:hover ~ .first, .first {
  color: red;
}
#FirstSecondThird-Container span:hover ~ .second, .second {
  color: green;
}
#FirstSecondThird-Container span:hover ~ .third, .third {
  color: blue;
}

span {display: block;} /* this line was not generated, it's just to place them vertically */
<div id="FirstSecondThird-Container">
  <span class='first'>First</span>
  <span class='second'>Second</span>
  <span class='third'>Third</span>
</div>

这个与panther's fiddle类似的CSS规则。

不错的挑战123qwe :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接