Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy does the general-sibling combinator allow toggling pseudo-element's content, but not the adjacent-sibling?
    primarykey
    data
    text
    <p>In this question "<a href="https://stackoverflow.com/q/17217585/">CSS3 Selector That Works like jQuery&#39;s .click()?</a>" I <a href="https://stackoverflow.com/a/17217826/82548">posted an answer</a> using the <code>:checked</code> state of an <code>input</code>, of <code>type="checkbox"</code> to toggle the display of an element.</p> <p>This is the HTML of the demo I posted in that answer:</p> <pre><code>&lt;input type="checkbox" id="switch" /&gt; &lt;nav&gt; &lt;h2&gt;This would be the 'navigation' element.&lt;/h2&gt; &lt;/nav&gt; &lt;label for="switch"&gt;Toggle navigation&lt;/label&gt; </code></pre> <p>And the CSS (with transitions stripped for brevity):</p> <pre><code>#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; } </code></pre> <p><a href="http://jsfiddle.net/davidThomas/rUkRS/1/" rel="nofollow noreferrer">JS Fiddle demo</a>.</p> <p>Once I'd posted the answer it occurred to me that we could <em>also</em> toggle the text of the <code>label</code> used to trigger the state-change of that checkbox, using the following selectors (having amended the <code>label</code>'s text to 'navigation'):</p> <pre><code>label { display: inline-block; cursor: pointer; } #switch + nav + label::before { content: 'Show '; } #switch:checked + nav + label::before { content: 'Hide '; } </code></pre> <p><a href="http://jsfiddle.net/davidThomas/rUkRS/6/" rel="nofollow noreferrer">Simplified/basic JS Fiddle demo</a>.</p> <p>This did not work, in that while the selector matched while the <code>input</code> was in its unchecked state (and the <code>label</code> showed <code>Show navigation</code>), the selector <em>failed</em> to match when the state of the <code>input</code> changed. Note that the transitions were still effected on the <code>nav</code> 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.</p> <p>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):</p> <pre><code>#switch:checked + nav { background-color: #ffa; } label { display: inline-block; cursor: pointer; } #switch ~ label::before { content: 'Show '; } #switch:checked ~ label::before { content: 'Hide '; } </code></pre> <p><a href="http://jsfiddle.net/davidThomas/rUkRS/4/" rel="nofollow noreferrer">JS Fiddle demo</a>.</p> <p>Somewhat to my surprise, this worked (the <code>content</code> of the <code>label</code> changed in response to the changed-state of the <code>input</code>).</p> <p>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?</p> <p>Further, this <em>does</em> 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?</p> <p>And, even <em>further</em>, it seems that while this is a bug in Chrome (thanks @Boltclock), there's a somewhat ludicrous <a href="http://css-tricks.com/webkit-sibling-bug/" rel="nofollow noreferrer">'do-nothing' animation</a> that fixes the non-working demo (though other, perhaps better, alternatives exist, as Scott's answer shows):</p> <pre><code>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 '; } </code></pre> <p><a href="http://jsfiddle.net/davidThomas/rUkRS/14/" rel="nofollow noreferrer">JS Fiddle demo</a>.</p> <p><strong>Note:</strong> the reason I'm updating the question with this 'fix,' rather than posting it as an answer, is simply because the question <em>wasn't</em> "how can I fix this?" but (basically) "why doesn't it work?"</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload