Almost every site needs a menu, and the pattern is pretty consistent. On
    large displays, you'll display some full version of the menu on the page at
    all times. On small displays, you'll have a button that opens the menu. It's
    pretty clear how to do that with JavaScript.
    onClick = moveMenu(). Maybe trigger a fancy animation for your
    open/close button. What might be less clear is how to do that without
    relying on JS at all.
Here I'm going to focus mostly on making the small-screen version, since the large-screen version has nothing fancy going on. The menu we'll be developing is the example above, which is also the one I use on this site.
How might we create a mobile menu that does use JS? It might look something like this: (Note this is in Svelte, so I can show you the result easily. If you're not familiar with it that's ok, it should still be easy to follow)
<script>
  let show = false;
  let toggleMenu = () => {
    show = !show;
  };
</script>
<div id="menu_bar">
  <div id="menu" class={show ? "show" : ""}>Contents of the menu</div>
  <button on:click={toggleMenu}>Toggle</button>
</div>
<style>
  div#menu {
    transform: translateY(-100%);
  }
  div#menu.show {
    transform: translateY(0px);
  }
</style>
  there it is, just toggle the position using transform when the "toggle"
    button is clicked. You can see it in action there. In order to get something
    nice, it'll have to be more complicated than that - a taller menu would be cut
    off, for example - but that's the general idea.
How do we accomplish that same idea with only CSS? We need a way to keep
    track of whether or not the menu is open, and use that information to style
    our menu. A good way to store user input in CSS is the
    "checkbox" input type. Using CSS, you can check if a checkbox
    is checked using :checked, and even style elements based on
    that information. It makes creating custom checkboxes very straightforwad,
    and is what we'll use to make this menu.
<div id="menu_bar">
  <label>
    <input type="checkbox" />
    <div id="menu">Contents of the menu</div>
    <p>Toggle</p>
  </label>
</div>
<style>
  input {
    display: none;
  }
  input:checked ~ div#menu {
    transform: translateY(0px);
  }
  div#menu {
    transform: translateY(-100%);
  }
</style>
  That's the basic idea! You just store the state of the menu in the checkbox, and it's perfectly interactible automatically.
There are some complications with the menu as it stands.
label-input
      pair. That is obviously easy to fix, I left it out here for simplicity. You
      could also use the :has selector instead if you want to try implementing
      this a slightly different way, that would allow you to put the menu outside
      the labelids. Again, I did that for
      simplicity/clarityMenu Size
We can fix the menu size by using another div
<script lang="ts">
</script>
<div id="menu_bar">
  <label>
    <input type="checkbox" />
    <div id="clip">
      <div id="menu">
        <p>Here is a menu</p>
        <p>That is tall</p>
        <p>And useful now</p>
      </div>
    </div>
    <div id="toggle">Toggle</div>
  </label>
</div>
<style>
  input {
    display: none;
  }
  input:checked ~ div div#menu {
    transform: translateY(0px);
  }
  label {
    position: relative;
  }
  div#menu {
    transform: translateY(-100%);
  }
  div#clip {
    position: absolute;
    left: 0px;
    top: 0px;
    width: 100%;
    overflow: hidden;
  }
  div#toggle {
    z-index: 10;
  }
</style>
  And that's it! The extra div automatically takes the size of its contents,
    so it's the perfect size to crop our menu. And, all this works without any
    JS! Try disabling JavaScript on this page (you can use a special extension
    for that, or if you have uBlock Origin click "More" and </>). The initial JS example won't work, but all the others do! And, so does
    the menu on this page. It's also easy to add optional functionality that
    does use JS if you want, like closing the menu if you click outside for
    example.
You'll notice the example menu even has a nice animation for the hamburger
    button. That is also done entirely in CSS. It works similarly to how the
    menu itself does, except it animates SVG lines. I won't go into
    detail here, but if you're interested check out the GitHub repo for this
    site
    here.
Well, for fun, mostly. But also, because not everyone has JS! Some people are waiting for JS to load because your site is bloated, or they're on a micro-browser, or they have it disabled for security reasons.
:has like I allude to above is likely
      what you would want.