【发布时间】:2013-06-17 15:26:06
【问题描述】:
在这个问题“CSS3 Selector That Works like jQuery's .click()?”中,我posted an answer 使用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;
}
一旦我发布了答案,我突然想到我们可以也使用以下选择器切换用于触发该复选框状态更改的 label 的文本(具有将label的文字修改为“导航”):
label {
display: inline-block;
cursor: pointer;
}
#switch + nav + label::before {
content: 'Show ';
}
#switch:checked + nav + label::before {
content: 'Hide ';
}
Simplified/basic JS Fiddle demo.
这不起作用,从中匹配input 987654366的选择器(和label 987654338 @),选择器失败 em>以匹配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 ';
}
令我惊讶的是,这有效(label 的 content 响应 input 的更改状态而更改)。
那么,问题来了:为什么通用兄弟组合器允许更新后兄弟,而链接的下兄弟组合器(匹配 DOM 的元素和结构)却不允许?
此外,这确实似乎可以在 Firefox(21,在 Windows XP 上)中工作;所以我猜这个问题会稍微改变一下,包括:这是 Chrome/Webkit 中的错误,还是预期的行为?
而且,即使是进一步,这似乎是 Chrome 中的一个错误(感谢@Boltclock),有一个有点可笑的'do-nothing' animation 修复了不工作的演示(虽然其他的,也许更好,存在替代品,正如斯科特的回答所示):
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 ';
}
注意:我之所以用这个“修复”更新问题,而不是将其作为答案发布,仅仅是因为问题不是“我怎样才能解决这个问题?”但是(基本上)“为什么它不起作用?”
【问题讨论】:
标签: html css css-selectors