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

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

问题描述

在此问题 CSS3选择器像jQuery的.click()?使用输入的:checked 状态提供答案 type =checkbox可切换元素的显示。



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

 < input type =checkboxid =switch/& 
< nav>
< h2>这将是'navigation'元素。< / h2>
< / nav>
< label for =switch>切换导航< / label>

和CSS(为了简洁起见,转换被剥离):

  #switch {
display:none;
}
#switch + nav {
height:0;
overflow:hidden;
/ *转换后* /
}
#switch:checked + nav {
height:4em;
color:#000;
background-color:#ffa;
/ *转换后跟* /
}

标签{
cursor:pointer;
}

JS Fiddle demo



一旦我发布了我的回答,我们也可以切换用于触发该复选框的状态更改的标签的文本,使用以下选择器(修改了标签

 标签{
display:inline-block;
cursor:pointer;
}

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

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

简化/基本JS Fiddle演示



这没有用,因为当选择器匹配而输入处于未选中状态(并且标签显示显示导航 输入的状态更改时,失败匹配。注意,转换仍然在 nav 元素上实现,原始匹配选择器指示下一个同级组合器最初匹配。上面的链接显示了一个不工作(在Chrome 27 / Windows XP)选择器的简化演示。



然后我试图通用同胞组合器,以减少选择器链。这导致以下CSS(为了简洁,转换再次被剥离):

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

标签{
display:inline-block;
cursor:pointer;
}

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

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

JS Fiddle演示



有一点让我感到惊讶的是,这个工作( content 已改变以响应输入的改变状态。



所以,问题:为什么通用同胞组合器允许更新后来的兄弟姐妹,而链接的下一个兄弟姐妹组合器(它匹配DOM的元素和结构)不? / p>

此外, 似乎适用于Firefox(21,在Windows XP上)。所以我想问题稍有改变,包括:这是Chrome / Webkit中的错误,还是预期的行为?



甚至进一步 >,似乎虽然这是Chrome中的一个错误(感谢@Boltclock),有一个有点荒谬的'do-nothing'动画,修复非工作演示(虽然其他,也许更好,替代品存在,如Scott的回答所示):

  body {
-webkit-animation:bugfix infinite 1s;
}
@ -webkit-keyframes bugfix {
from {
padding:0;
}
到{
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 demo



注意: 而不是将其作为答案,仅仅是因为不是如何解决这个问题?但是(基本上)为什么不工作?

解决方案

这是WebKit浏览器中的一个长期的bug使用某些动态伪类与下一个同级组合器。无论是对兄弟元素本身应用样式还是对同级元素的伪元素应用样式,都会发生这种情况。



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





奇怪的是,还报告说Chrome与一般的兄弟组合器有问题,您的给定方案:





所以要么是固定的,要么是其他触发器/触发器。


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.

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>

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 demo.

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 ';
}

Simplified/basic JS Fiddle demo.

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.

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 demo.

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

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?

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?

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 demo.

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?"

解决方案

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:

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天全站免登陆