簡體   English   中英

為什么通用兄弟組合器允許切換偽元素的內容,而不是相鄰的兄弟?

[英]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 ';
}

簡化/基本JS小提琴演示

這不起作用,因為當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小提琴演示

令我驚訝的是,這很有效( labelcontent隨着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小提琴演示

注意:我用這個“修復”更新問題的原因,而不是將其作為答案發布,僅僅是因為問題不是 “我該如何解決這個問題?” 但(基本上)“為什么不起作用?”

Bug工作

顯然, 鏈接在一起的 某些有效偽類允許它工作。

這些工作(見小提琴#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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM