3

The following CSS checkbox hack works under the assumption that the content is a sibling of the checkbox. When the label is clicked, the content is toggled.

DEMO

<input id="checkbox" type="checkbox" />
<label for="checkbox">
  Toggle content
</label>
<div class="content">Content here</div>
#checkbox {
  display: none;
}

#checkbox:not(:checked) ~ .content {
  display: none;
}

Can the same effect be achieved using CSS only if the content is not a sibling of the checkbox? For example:

<div>
  <input id="checkbox" type="checkbox" />
  <label for="checkbox">
    Toggle content
  </label>
</div>
<div class="content">Content here</div>
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Misha Moroshko
  • 166,356
  • 226
  • 505
  • 746
  • Not possible without JavaScript or possibly some hacky pseudo elements. – j08691 Nov 02 '15 at 03:32
  • 1
    This can be generalized to "How can I style an arbitrary element based on the checked state of a checkbox?", which makes it a duplicate of one of any of the most common limitations of CSS selectors, or even more generally, http://stackoverflow.com/questions/28708741/how-do-i-select-an-element-based-on-the-state-of-another-element-in-the-page-wit The answer is that it depends on whether you can link the two elements using the combinators available to you. It may not be a sibling of the checkbox, but it could be a descendant of a sibling of the checkbox, for example. – BoltClock Nov 02 '15 at 03:32
  • 1
    Not with CSS until CSS4 parent selector is introduced. You can achieve this only through JS. You can also make use of this plugin right now: https://github.com/Idered/cssParentSelector – m4n0 Nov 02 '15 at 03:33
  • @BoltClock Thanks for the link. Can this be achieved with the layout in the question (last bit of HTML)? – Misha Moroshko Nov 02 '15 at 03:36
  • 1
    @Misha Moroshko: No: there is no parent selector, so you can't select out of the checkbox's parent element in order to reach its sibling. – BoltClock Nov 02 '15 at 03:38
  • I am sure you can still do the same as you are doing in the above demo fiddle. Can you explain why you are trying to do it in the way in which it is not possible to deal only with css? – Mr_Green Nov 02 '15 at 04:31
  • @Misha Moroshko The checkbox itself is invisible, so you can safely put it next to the content. The `label for` can appear anywhere in your document. I'm doing this all the time. – Rene van der Lende Nov 02 '15 at 08:48

1 Answers1

4

You could do it with the :target pseudo class and using anchors instead of a checkbox. Ugly as hell but CSS only:

a {
  color: #000000;
  text-decoration: none;
}

#off {
  display: none;
}

.content {
  display: none;
}

#your-target:target ~ .content {
  display: block;
}

#your-target:target #on {
  display: none;
}

#your-target:target #off {
  display: block;
}
<div id="your-target">
  <a id="on" href="#your-target">
    Toggle content
  </a>
  <a id="off" href="#">
    Toggle content
  </a>
</div>
<div class="content">Content here</div>
r4ph43l
  • 53
  • 6