在这个问题“ CSS3 Selector That Works like jQuery's .click()? ”中,我使用 , of 的状态发布了一个答案,用于切换元素的显示。:checked
input
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;
}
一旦我发布了答案,我就想到我们还label
可以使用以下选择器切换用于触发该复选框状态更改的文本(已将label
“文本”修改为“导航”):
label {
display: inline-block;
cursor: pointer;
}
#switch + nav + label::before {
content: 'Show ';
}
#switch:checked + nav + label::before {
content: 'Hide ';
}
This did not work, in that while the selector matched while the input
was in its unchecked state (and the label
showed Show navigation
), the selector failed to match when the state of the input
changed. 请注意,转换仍然对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 ';
}
令我惊讶的是,这奏效了(改变content
的label
改变状态以响应改变的状态input
)。
所以,问题是:为什么通用兄弟组合器允许更新后兄弟,而链接的下兄弟组合器(匹配 DOM 的元素和结构)不允许更新?
此外,这似乎在 Firefox(21,在 Windows XP 上)中有效;所以我想这个问题会稍微改变,包括:这是 Chrome/Webkit 中的错误,还是预期的行为?
而且,更进一步,虽然这是 Chrome 中的一个错误(感谢@Boltclock),但有一个有点可笑的“无所事事”动画修复了非工作演示(尽管存在其他可能更好的替代方案,如 Scott 的答案显示):
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 ';
}
注意:我之所以用这个“修复”更新问题,而不是将其作为答案发布,仅仅是因为问题不是“我该如何解决这个问题?” 但是(基本上)“为什么它不起作用?”