简体   繁体   中英

Creating a dropdown menu that shows on focus with Pure CSS

I am working on a dropdown menu for the header of a site. I have it so that when you hover on the "Info for" text, a menu pops up. I would also like to be able to focus on the submenu items, but when tabbing through the site, you can focus on the top button, but the menu disappears when moving to the next item, which is just the body. Let me know if this is possible the way I have it set up!

HTML

<div class="top-bar">
  <div class="info-for">
    <button>Information For&nbsp;&nbsp;&#9660;</button>
    <div class="dropdown">
      <ul>
        <li><a href="#">Info For Option 1</a></li>
        <li><a href="#">Info For Option 2</a></li>
        <li><a href="#">Info For Option 3</a></li>
        <li><a href="#">Info For Option 4</a></li>
        <li><a href="#">Info For Option 5</a></li>
      </ul>
    </div>
  </div>
  <div class="give-search">
    <a href="#">Give</a>
    <span class="spacer">|</span>
    <button>Q</button>
  </div>
</div>

CSS

//-----BASE-----//
:root {
  --purple: #61578b;
  --gold: #deb364;
  --white: #fefefe;
  --background-gray: #f2f2f2;
  --border-gray: #cccccc;

  --font-serif: "Noto Serif", serif;
  --font-sans: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif;
}
body {
  font-family: var(--font-sans);
  margin: 0;
}
a {
  text-decoration: none;
  &:focus {
    outline: none;
  }
}

//-----HELPER-----//
.dropdown {
  display: none;
  position: absolute;
  top: 100%;
  background: var(--white);
  border: 1px solid var(--border-gray);
  & ul {
    list-style-type: none;
    padding: 0;
    margin: 0;
    width: max-content;
  }
  & a {
    display: block;
  }
  &:hover,
  &:focus-within {
    display: block;
  }
}

//-----HEADER-----//
.top-bar {
  background-color: var(--purple);
  color: var(--white);
  font-weight: bold;
  position: relative;
  & > * {
    display: inline-block;
  }
  & .dropdown {
    & li:hover,
    & li:focus-within {
      background-color: var(--background-gray);
    }
    & a {
      padding: 0.75rem 0.5rem;
      color: var(--purple);
      font-family: var(--font-sans);
      font-weight: bold;
    }
  }
}
.info-for {
  font-family: var(--font-serif);
  & button {
    all: unset;
    cursor: pointer;
    padding: 1rem;
    &:hover,
    &:focus {
      color: var(--gold);
    }
    &:hover + .dropdown,
    &:focus + .dropdown {
      display: block;
    }
  }
}
.give-search {
  float: right;
  padding: 1rem;
  & a {
    color: var(--white);
    &:hover,
    &:focus {
      color: var(--gold);
    }
  }
  & .spacer {
    padding: 0 2rem;
  }
  & button {
    all: unset;
    cursor: pointer;
    &:hover,
    &:focus {
      color: var(--gold);
    }
  }
}

Here is my Codepen

display:none seems to be your issue.

To hide your absolute .dropdown at screen , instead display , use coordonates or margin to pull/push it outside of the screen but allow it to be reached and read ( display:none hides it totally).

here is a possible example without display and negative margin DEMO below

or classic margin on your forked codepen : https://codepen.io/gc-nomade/pen/RwZJjNO .

 .dropdown { position:absolute; margin-inline-start:-100vw;/* righ or left, follows direction of document */ } .dropdown:focus-within { margin:0 }
 <div class="top-bar"> <div class="info-for"> <button>Information For&nbsp;&nbsp;&#9660;</button> <div class="dropdown"> <ul> <li><a href="#">Info For Option 1</a></li> <li><a href="#">Info For Option 2</a></li> <li><a href="#">Info For Option 3</a></li> <li><a href="#">Info For Option 4</a></li> <li><a href="#">Info For Option 5</a></li> </ul> </div> </div> <div class="give-search"> <a href="#">Give</a> <span class="spacer">|</span> <button>Q</button> </div> </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM