-1

Here are html codes:

<div class="wrapper"> <div class="menu-wrap"> <ul> <li> <input type="radio" id="link1" /> </li> </ul> </div> <div class="content-wrap"> <div id="link1-content"><p>Just a paragraph</p></div> </div> </div> 

Here are css codes:

#link1:checked ~ #link1-content { display: none;} 

I am trying to create css click with input[type=radio]. My problem is that the sibling selector does not work.

How can I write appropriate sibling selector?

6
  • You should use JavaScript here. Commented Jan 16, 2013 at 20:56
  • I know how to do that with JS, but I need css only. Commented Jan 16, 2013 at 20:58
  • 5
    "My problem is that the sibling selector does not work". That's because those elements aren't siblings. Commented Jan 16, 2013 at 20:58
  • Good point, is there any hack in css? Commented Jan 16, 2013 at 20:59
  • Nope, not until what you might call CSS4. JavaScript is the only way to do it now. Commented Jan 16, 2013 at 21:04

2 Answers 2

3

You are trying to do something sibling selectors cannot do. You will not be able to style #link1-content because it does not share the same parent as #link1:checked. As @sirko said, this is something that should be accomplished with Javascript/JQuery (see my snippet below).

Source Child and Sibling selectors -- CSS Tricks

Note that in both the general sibling and adjacent sibling selectors the logic takes place within the same parent element.

A very simple jQuery solution:

$('#link1').change(function(){ $('#link1-content').toggle(); }); 

Codepen example

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, I know How to do that with jQuery, I wanted a hack in pure css.
0

You can obtain what you need without using javascript and leaving the html structure in your document just as it is by simply adding a new CSS rule, making use of the :has() relational pseudo-class which is being supported by all major browsers since the end of 2023 at least (see).

Remember, you'll have to always start your CSS rules from the ".menu-wrap class <div>" to look into for a match when the "#link1 <input>" is checked, and then go on to the ".content-wrap class <div>" to look at for the "#link1-content <input>", 'cause those are the elements at the right level of the DOM tree from where you can "move back and forth" for the matching in the case here.

.menu-wrap:has(#link1:checked) ~ .content-wrap #link1-content { display: none;}
<div class="wrapper"> <div class="menu-wrap"> <ul> <li> <input type="radio" id="link1" /> </li> </ul> </div> <div class="content-wrap"> <div id="link1-content"><p>Just a paragraph</p></div> </div> </div>

So here the needed CSS rule is:

.menu-wrap:has(#link1:checked) ~ .content-wrap #link1-content { display: none;} 

P.S. Just let me note that maybe an <input> of type checkbox would make more sense than a radio one here IMHO...

Comments