skip to Main Content

I have this header with a menu inside. I can open the menu when the checkbox is checked but I can’t figure out how to solve that I want the CSS content to change from a hamburger menu to a close icon. For that I’m using ASCII.

So this code is wrong and I know it’s the wrong selector, but I don’t know how to fix it. I guess there is something that needs to change in the structure. Any help is appreciated!

.main-nav {
  position: relative;
  nav {
    a {
      display: block;
      border-bottom: 0.5px solid #000;
      padding: 1rem;
      text-decoration: none;
      color: #000;
      &:hover {
        background-color: #F7CC00;
      }
    }
  }
  label {
    cursor: pointer;
    font-size: 1.5rem;
    padding-right: 1rem;
    &:before {
      content: "2630";
    }
  }
  #toggle {
    display: none;
    &:checked {
      +.menu {
        display: block;
      }
    }
  }
  .menu {
    display: none;
    position: absolute;
    top: 62px;
    right: 0;
    background-color: #fff;
    width: 100vw;
  }
}


/* This is where it goes wrong */

#toggle:checked~label:before {
  content: "2716";
}
<header>
  <div class="container">
    <div class="logo">
      <a href="/"><img src="https://via.placeholder.com/40" alt="logo"></a>
    </div>
    
    <div class="main-nav">
      <label for="toggle"></label>
      <input type="checkbox" id="toggle" />
      
      <nav class="menu">
        <a href="#one" id="link1">Link</a>
        <a href="#two" id="link2">Link</a>
        <a href="#three" id="link3">Link</a>
        <a href="#four" id="link4">Link</a>
        <a href="#five" id="link5">Link</a>
        <a href="#six" id="link6">Link</a>
        <a href="#seven" id="link7">Link</a>
      </nav>
    </div>
  </div>
</header>

2

Answers


  1. Just reverse the order of the checkbox and label so your sibling selector works. Note that I also updated the selector for the menu element.

    .main-nav {
      position: relative;
      nav {
        a {
          display: block;
          border-bottom: 0.5px solid #000;
          padding: 1rem;
          text-decoration: none;
          color: #000;
          &:hover {
            background-color: #F7CC00;
          }
        }
      }
      label {
        cursor: pointer;
        font-size: 1.5rem;
        padding-right: 1rem;
        &::before {
          content: "2630";
        }
      }
      #toggle {
        display: none;
        &:checked {
          ~.menu {
            display: block;
          }
        }
      }
      .menu {
        display: none;
        position: absolute;
        top: 62px;
        right: 0;
        background-color: #fff;
        width: 100vw;
      }
    }
    
    
    /* This is where it goes wrong */
    
    #toggle:checked~label::before {
      content: "2716";
    }
    <header>
      <div class="container">
        <div class="logo">
          <a href="/"><img src="https://via.placeholder.com/40" alt="logo"></a>
        </div>
        
        <div class="main-nav">
          <input type="checkbox" id="toggle" />
          <label for="toggle"></label>
          
          <nav class="menu">
            <a href="#one" id="link1">Link</a>
            <a href="#two" id="link2">Link</a>
            <a href="#three" id="link3">Link</a>
            <a href="#four" id="link4">Link</a>
            <a href="#five" id="link5">Link</a>
            <a href="#six" id="link6">Link</a>
            <a href="#seven" id="link7">Link</a>
          </nav>
        </div>
      </div>
    </header>
    Login or Signup to reply.
  2. Just want to propose another solution and that allows you to keep your order in your HTML and this using the very useful :has css selector.

    .main-nav {
      position: relative;
      nav {
        a {
          display: block;
          border-bottom: 0.5px solid #000;
          padding: 1rem;
          text-decoration: none;
          color: #000;
          &:hover {
            background-color: #F7CC00;
          }
        }
      }
      label {
        cursor: pointer;
        font-size: 1.5rem;
        padding-right: 1rem;
        &:before {
          content: "2630";
        }
      }
      #toggle {
        display: none;
        &:checked {
          +.menu {
            display: block;
          }
        }
      }
      .menu {
        display: none;
        position: absolute;
        top: 62px;
        right: 0;
        background-color: #fff;
        width: 100vw;
      }
    }
    
    
    /* This is where it goes wrong */
    
    .main-nav:has(#toggle:checked) label:before {
      content: "2716";
    }
        <header>
            <div class="container">
              <div class="logo">
                <a href="/"><img src="https://via.placeholder.com/40" alt="logo"></a>
              </div>
              
              <div class="main-nav">
                <label for="toggle"></label>
                <input type="checkbox" id="toggle" />
                
                <nav class="menu">
                  <a href="#one" id="link1">Link</a>
                  <a href="#two" id="link2">Link</a>
                  <a href="#three" id="link3">Link</a>
                  <a href="#four" id="link4">Link</a>
                  <a href="#five" id="link5">Link</a>
                  <a href="#six" id="link6">Link</a>
                  <a href="#seven" id="link7">Link</a>
                </nav>
              </div>
            </div>
          </header>

    using the very useful :has css selector

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search