![](/img/trans.png)
[英]changed general-sibling combinator for toggling pseudo-element: what is valid
[英]Why does the general-sibling combinator allow toggling pseudo-element's content, but not the adjacent-sibling?
在这个问题“ CSS3选择器,像jQuery的.click()? ”我发布了一个答案使用:checked
input
:checked
状态, type="checkbox"
来切换元素的显示。
这是我在答案中发布的演示的HTML:
<input type="checkbox" id="switch" />
<nav>
<h2>This would be the 'navigation' element.</h2>
</nav>
<label for="switch">Toggle navigation</label>
和CSS(为了简洁而剥离过渡):
#switch {
display: none;
}
#switch + nav {
height: 0;
overflow: hidden;
/* transitions followed */
}
#switch:checked + nav {
height: 4em;
color: #000;
background-color: #ffa;
/* transitions followed */
}
label {
cursor: pointer;
}
JS小提琴演示 。
有一次,我张贴发生,我认为我们还可以切换的文字答案label
用于触发复选框的状态变化,使用下面的选择(已修订了label
的文本为‘导航’):
label {
display: inline-block;
cursor: pointer;
}
#switch + nav + label::before {
content: 'Show ';
}
#switch:checked + nav + label::before {
content: 'Hide ';
}
这不起作用,因为当input
处于未检查状态时选择器匹配(并且label
显示Show navigation
),当input
状态发生变化时,选择器无法匹配。 请注意,转换仍然在nav
元素上生效,原始匹配选择器指示下一个兄弟组合器最初匹配。 上面的链接显示了不工作(在Chrome 27 / Windows XP中)选择器的简化演示。
然后我想到尝试使用通用兄弟组合器来减少选择链。 这导致了以下CSS(为了简洁起见,再次剥离了转换):
#switch:checked + nav {
background-color: #ffa;
}
label {
display: inline-block;
cursor: pointer;
}
#switch ~ label::before {
content: 'Show ';
}
#switch:checked ~ label::before {
content: 'Hide ';
}
JS小提琴演示 。
令我惊讶的是,这很有效( label
的content
随着input
的改变状态而改变)。
所以,问题是:为什么通用兄弟组合子允许更新后来的兄弟,而链接的下一个兄弟组合子(匹配DOM的元素和结构)不是?
此外,这似乎在Firefox(21,在Windows XP)的工作; 所以我想问题略有改变,包括:这是Chrome / Webkit中的一个错误,还是预期的行为?
而且, 更进一步 ,似乎虽然这是Chrome中的一个错误(感谢@Boltclock),有一些有点可笑的“无所事事”动画修复了非工作演示(尽管其他可能更好的替代方案存在,如斯科特的答案显示):
body {
-webkit-animation: bugfix infinite 1s;
}
@-webkit-keyframes bugfix {
from {
padding: 0;
}
to {
padding: 0;
}
}
#switch {
}
#switch + nav {
-moz-transition: all 1s linear;
-ms-transition: all 1s linear;
-o-transition: all 1s linear;
-webkit-transition: all 1s linear;
transition: all 1s linear;
}
#switch:checked + nav {
background-color: #ffa;
-moz-transition: all 1s linear;
-ms-transition: all 1s linear;
-o-transition: all 1s linear;
-webkit-transition: all 1s linear;
transition: all 1s linear;
}
label {
display: inline-block;
cursor: pointer;
}
#switch + nav + label::before {
content:'Show ';
}
#switch:checked + nav + label::before {
content:'Hide ';
}
JS小提琴演示 。
注意:我用这个“修复”更新问题的原因,而不是将其作为答案发布,仅仅是因为问题不是 “我该如何解决这个问题?” 但(基本上)“为什么不起作用?”
显然, 链接在一起的 某些有效伪类允许它工作。
这些工作(见小提琴#1 , 小提琴#2 , 小提琴#3 ):
#switch:checked + nav:only-of-type + label::before
#switch:checked + nav:nth-of-type(1) + label::before
#switch:checked + nav:nth-child(2) + label::before
这没有(见小提琴#4 ):
#switch:checked + nav:not([class]) + label::before
我尝试了其他一些:not()
组合,没有一个允许它工作。
#switch:checked + nav:nth-child(n) + label::before
这是WebKit浏览器中一个长期存在的错误,它与使用具有下一个兄弟组合子的某些动态伪类有关。 无论您是将样式应用于兄弟元素本身还是应用该兄弟元素的伪元素,都会发生这种情况。
我不知道是否有人提交了错误报告,但网站上经常出现这种情况:
奇怪的是,据报道,Chrome与普通兄弟组合器存在问题,但正如您所指出的那样,它适用于您的特定情况:
所以要么修复了,要么触发/触发它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.