input:checked is not applying the properties

Asked

Viewed 1,061 times

3

I’m developing a responsive menu using css3 (I can’t use JS), and I’m having a problem that’s keeping me from moving forward, the problem is the following :

input:checked ~ nav {
  display: none;
}

But the property is not applied to Nav when the input is marked.

Example of the problem code in a code :

* {
  margin: 0;
  padding: 0;
  list-style: none;
}

input:checked ~ nav {
  display: none;
}
<body>
  <header>
    <div class="menu">
      <input type="checkbox" />
    </div>
    <nav>
      <ul>
        <li><a href="#">INICIO</a></li>
        <li><a href="#">SOBRE</a></li>
        <li><a href="#">CONTATOS</a></li>
        <li><a href="#">FALE CONOSCO</a></li>
        <li><a href="#">PROJETOS</a></li>
      </ul>
    </nav>
  </header>
  
</body>

1 answer

5


The problem is that the selector ~ refers to an element that is preceded by another within the same "parent" of the tree structure of the file, and is not the case for its HTML.

Of W3C documentation:

8.3.2. General sibling Combinator

The general sibling Combinator is made of the "Tilde" (U+007E, ~) Character that separates two sequences of simple selectors. The Elements represented by the two sequences share the same Parent in the Document Tree and the element represented by the first Sequence precedes (not necessarily immediately) the element represented by the Second one.

(my griffin, in the part that interests us)

That in short it is this:

The "generic brother" combinator is the "tilde" (~), separating two sequences of single selectors. The elements have a father in common in the document tree, and the first of the elements precedes the second, not necessarily immediately.

In your case, the "father" of the elements is different, only the "grandfather" is the same.

There are many ways to solve yourself, the best one only depends on the general of your code. The important thing is to understand how CSS selectors work.


Solution examples:

A solution would be to nav within the div:

* {
  margin: 0;
  padding: 0;
  list-style: none;
}

input:checked ~ nav {
  display: none;
}
<body>
  <header>
    <div class="menu">
      <input type="checkbox" />
      <nav>
        <ul>
          <li><a href="#">INICIO</a></li>
          <li><a href="#">SOBRE</a></li>
          <li><a href="#">CONTATOS</a></li>
          <li><a href="#">FALE CONOSCO</a></li>
          <li><a href="#">PROJETOS</a></li>
        </ul>
      </nav>
    </div>
  </header>
</body>

Another would be to take the input of div:

* {
  margin: 0;
  padding: 0;
  list-style: none;
}

input:checked ~ nav {
  display: none;
}
<body>
  <header>
    <input type="checkbox" />
    <nav>
      <ul>
        <li><a href="#">INICIO</a></li>
        <li><a href="#">SOBRE</a></li>
        <li><a href="#">CONTATOS</a></li>
        <li><a href="#">FALE CONOSCO</a></li>
        <li><a href="#">PROJETOS</a></li>
      </ul>
    </nav>
  </header>
</body>


But if you really need an element inside the div:

You can use a label as "remote control" checkbox:

* {
  margin: 0;
  padding: 0;
  list-style: none;
}

#toggle,
input:checked ~ nav {
  display: none;
}
<body>
  <header>
    <div class="menu">
      <label for="toggle">[clique aqui]</label>
    </div>
    <input id="toggle" type="checkbox" />
    <nav>
      <ul>
        <li><a href="#">INICIO</a></li>
        <li><a href="#">SOBRE</a></li>
        <li><a href="#">CONTATOS</a></li>
        <li><a href="#">FALE CONOSCO</a></li>
        <li><a href="#">PROJETOS</a></li>
      </ul>
    </nav>
  </header>
  
</body>

  • Thank you very much! A beautiful hahaha explanation.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.