为什么通用兄弟组合器允许切换伪元素的内容,而不是相邻兄弟? [英] Why does the general-sibling combinator allow toggling pseudo-element's content, but not the adjacent-sibling?

查看:12
本文介绍了为什么通用兄弟组合器允许切换伪元素的内容,而不是相邻兄弟?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这个问题CSS3 Selector That Works like jQuery's .click()?"我 使用 input:checked 状态发布答案type="复选框" 切换元素的显示.

In this question "CSS3 Selector That Works like jQuery's .click()?" I posted an answer using the :checked state of an input, of type="checkbox" to toggle the display of an element.

这是我在该答案中发布的演示的 HTML:

This is the HTML of the demo I posted in that answer:

<input type="checkbox" id="switch" />
<nav>
    <h2>This would be the 'navigation' element.</h2>
</nav>
<label for="switch">Toggle navigation</label>

还有 CSS(为简洁起见,去掉了过渡):

And the CSS (with transitions stripped for brevity):

#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 Fiddle 演示.

一旦我发布了答案,我突然想到我们可以切换用于触发该复选框状态更改的 label 的文本,使用以下选择器(已将 label 的文本修改为navigation"):

Once I'd posted the answer it occurred to me that we could also toggle the text of the label used to trigger the state-change of that checkbox, using the following selectors (having amended the label's text to 'navigation'):

label {
    display: inline-block;
    cursor: pointer;
}

#switch + nav + label::before {
    content: 'Show ';
}

#switch:checked + nav + label::before {
    content: 'Hide ';
}

简化/基本 JS Fiddle 演示.

这不起作用,因为当 input 处于未选中状态时选择器匹配(并且 label 显示 Show navigation),当 input 的状态改变时,选择器 failed 匹配.请注意,转换仍然对 nav 元素起作用,并且原始匹配选择器指示下一个兄弟组合器最初匹配.上面的链接显示了不工作(在 Chrome 27/Windows XP 中)选择器的简化演示.

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. Note that the transitions were still effected on the nav element, and the original matching selector indicates that the next-sibling combinator matched originally. The above link shows a simplified demo of the not-working (in Chrome 27/Windows XP) selectors.

然后我想到尝试通用兄弟组合器,以减少选择器链.这导致了以下 CSS(为简洁起见,再次剥离了过渡):

It then occurred to me to try the general-sibling combinator, to reduce the selector-chain. which resulted in the following CSS (with transitions again stripped for brevity):

#switch:checked + nav {
    background-color: #ffa;
}

label {
    display: inline-block;
    cursor: pointer;
}

#switch ~ label::before {
    content: 'Show ';
}

#switch:checked ~ label::before {
    content: 'Hide ';
}

JS Fiddle 演示.

令我惊讶的是,这有效(labelcontent 响应 input 的更改状态而更改).

Somewhat to my surprise, this worked (the content of the label changed in response to the changed-state of the input).

那么,问题来了:为什么通用兄弟组合器允许更新后兄弟,而链接的下兄弟组合器(匹配 DOM 的元素和结构)却不允许?

So, the question: why does the general-sibling combinator allow for updating of a later-sibling while chained next-sibling combinators (which match the elements and the structure of the DOM) does not?

此外,这确实似乎可以在 Firefox(21,在 Windows XP 上)中工作;所以我猜这个问题会稍微改变一下,包括:这是 Chrome/Webkit 中的错误,还是预期的行为?

Further, this does seem to work in Firefox (21, on Windows XP); so I guess the question is altered slightly to include: is this a bug in Chrome/Webkit, or an expected behaviour?

而且,甚至进一步,这似乎是 Chrome 中的一个错误(感谢@Boltclock),还有一个有点可笑的 'do-nothing' 动画 修复了无法运行的演示(尽管存在其他可能更好的替代方案,正如 Scott 的回答所示):

And, even further, it seems that while this is a bug in Chrome (thanks @Boltclock), there's a somewhat ludicrous 'do-nothing' animation that fixes the non-working demo (though other, perhaps better, alternatives exist, as Scott's answer shows):

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 Fiddle 演示.

注意:我之所以用这个修复"更新问题,而不是将其作为答案发布,仅仅是因为问题不是我怎样才能解决这个问题?"但是(基本上)为什么它不起作用?"

Note: the reason I'm updating the question with this 'fix,' rather than posting it as an answer, is simply because the question wasn't "how can I fix this?" but (basically) "why doesn't it work?"

推荐答案

这是 WebKit 浏览器中一个长期存在的错误,与使用具有下一个兄弟组合器的某些动态伪类有关.无论您是将样式应用于兄弟元素本身还是该兄弟元素的伪元素,都会发生这种情况.

This is a long-standing bug in WebKit browsers related to the use of certain dynamic pseudo-classes with next-sibling combinators. This happens whether you're applying styles to the sibling element itself or a pseudo-element of that sibling element.

我不知道是否有人提交了错误报告,但在网站上经常看到这种情况:

I don't know if anybody has filed a bug report yet, but this has been seen rather frequently on the site:

奇怪的是,还报告说 Chrome 与通用兄弟组合器存在问题,但正如您所注意到的,它在您的给定场景中有效:

Strangely it was also reported that Chrome had issues with the general sibling combinator, but as you note it works in your given scenario:

所以要么是固定的,要么是其他东西触发/触发了它.

So either that was fixed, or something else triggers/triggered it.

这篇关于为什么通用兄弟组合器允许切换伪元素的内容,而不是相邻兄弟?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆