Bill
Bill

Reputation: 101

Why focus does not work properly in profile-dropdown?

I wrote the following dropdown menu feature:

.uc-main-container .uc-main-top .profile-dropdown {
  position: relative;
  display: inline-block;
}

.uc-main-container .uc-main-top .profile-dropdown:focus {
  outline: none;
}

.uc-main-container .uc-main-top .profile-dropdown:focus .profile-dropdown-content {
  display: block;
}

.uc-main-container .uc-main-top .profile-dropdown .profile-dropdown-content {
  transition: all 300ms ease;
  display: none;
  position: absolute;
  overflow: hidden;
  right: -.1rem;
  top: 0.4rem;
  border-radius: 0.05rem;
  padding: 0.15rem 0rem;
}
<div class="uc-main-container flex-column">
  <div class="uc-main-top flex">
    <ul class="uc-cp flex">
      <li class="uc-cp-item">home</li>
      <li class="uc-cp-item profile-dropdown" tabidex="-1">
        <a class="user-icon">menu</a>
        <div class="profile-dropdown-content" tabindex="-1">
          <a href="/profile" class="profile-menu-profile">Profile</a>
          <a href="/settings" class="profile-menu-settings">Settings</a>
          <a href="/logout" class="profile-menu-logout">Logout</a>
        </div>
      </li>
    </ul>
  </div>
</div>

Expected Result:

Clicking on menu should display profile-dropdown-content

Actual Result:

Clicking menu does nothing.

Upvotes: 1

Views: 56

Answers (1)

Zach Jensz
Zach Jensz

Reputation: 4078

The following selector will achieve what you want:

.uc-main-container .uc-main-top .profile-dropdown a:focus + .profile-dropdown-content

The changes I made to get it to work:

Your selector: .uc-main-container .uc-main-top .profile-dropdown:focus .profile-dropdown-content

  1. .profile-dropdown is on the <li> element, which is not being focused, you need to check for focus on the actual <a> itself.
  2. .profile-dropdown-content isn't a child of the rest of our selector now, so we use the adjacent sibling selector + to select the next sibling that we want to style.
  3. Your anchor element needs an href attribute in order to be focusable

Here is a working snippet:

.uc-main-container .uc-main-top .profile-dropdown {
  position: relative;
  display: inline-block;
}

.uc-main-container .uc-main-top .profile-dropdown a:focus {
  outline: none;
}

.uc-main-container .uc-main-top .profile-dropdown a:focus + .profile-dropdown-content {
  display: block;
}

.uc-main-container .uc-main-top .profile-dropdown .profile-dropdown-content {
  transition: all 300ms ease;
  display: none;
  position: absolute;
  overflow: hidden;
  right: -.1rem;
  top: 0.4rem;
  border-radius: 0.05rem;
  padding: 0.15rem 0rem;
}
<div class="uc-main-container flex-column">
  <div class="uc-main-top flex">
    <ul class="uc-cp flex">
      <li class="uc-cp-item">home</li>
      <li class="uc-cp-item profile-dropdown" tabidex="-1">
        <a class="user-icon" href="#">menu</a>
        <div class="profile-dropdown-content" tabindex="-1">
          <a href="/profile" class="profile-menu-profile">Profile</a>
          <a href="/settings" class="profile-menu-settings">Settings</a>
          <a href="/logout" class="profile-menu-logout">Logout</a>
        </div>
      </li>
    </ul>
  </div>
</div>

Upvotes: 2

Related Questions