如何创建高级 CSS 下拉菜单

效果展示

在这里插入图片描述

在这里插入图片描述

实现思路及部分代码

1、定义整体页面结构

从上述的效果展示图可以看出,页面的整体结构应该需要一个总菜单容器来装载父级菜单项,并且对应的父级菜单项应该有对应的菜单子项。子菜单是分类的话,我们还需要额外在扩展对应的容器来装载分类子菜单。所以我们可以这样来定义页面的结构:

<div class="header">
  <div class="dropdown">
    <button class="link"></button>
    <!-- 分组子菜单 -->
    <div class="dropdown-menu">
      <div>
        <div class="dropdown-heading"></div>
        <div class="dropdown-links">
          <a href="#" class="link"></a>
        </div>
      </div>
    </div>
    <!-- 只有一组菜单 -->
    <div class="dropdown">
      <button class="link"></button>
      <div class="dropdown-menu">
        <div class="dropdown-links">
          <a href="#" class="link"></a>
        </div>
      </div>
    </div>
    <!-- 带有表单的子菜单 -->
    <div class="dropdown">
      <button class="link">登录</button>
      <div class="dropdown-menu">
        <form class="login-form">
          <label for="email">Email</label>
          <input type="email" name="email" id="email" />
          <label for="password">Password</label>
          <input type="password" name="password" id="password" />
          <button type="submit">Login</button>
        </form>
      </div>
    </div>
  </div>
</div>

2、编写对应的样式

在页面结构的基础上进行样式的编写,具体核心代码如下:

.header {
    
    
  background-color: #f3f3f3;
  display: flex;
  align-items: baseline;
  padding: 0.5rem;
  gap: 1rem;
}

.link {
    
    
  background: none;
  border: none;
  text-decoration: none;
  color: #777;
  font-family: inherit;
  font-size: inherit;
  cursor: pointer;
  padding: 0;
}

.dropdown-menu {
    
    
  position: absolute;
  left: 0;
  top: calc(100% + 0.25rem);
  background-color: white;
  padding: 0.75rem;
  border-radius: 0.25rem;
  box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.1);
  opacity: 0;
  pointer-events: none;
  transform: translateY(-10px);
  transition: opacity 150ms ease-in-out, transform 150ms ease-in-out;
}

.dropdown.active > .link + .dropdown-menu {
    
    
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

.information-grid {
    
    
  display: grid;
  grid-template-columns: repeat(2, max-content);
  gap: 2rem;
}

.dropdown-links {
    
    
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.login-form > input {
    
    
  margin-bottom: 0.5rem;
}

3、决定下拉菜单的触发事件并编写对应事件代码

在这里我选择点击事件来触发菜单的显示,并且为了方便事件额获取,所以我这里会为关键的事件元素添加对应的data属性,具体实例如下:

<div class="dropdown" data-dropdown></div>
<button class="link" data-dropdown-button>新闻版块</button>
document.addEventListener("click", (e) => {
    
    
  const isDropdownButton = e.target.matches("[data-dropdown-button]");
  if (!isDropdownButton && e.target.closest("[data-dropdown]") != null) return;

  let currentDropdown;
  if (isDropdownButton) {
    
    
    currentDropdown = e.target.closest("[data-dropdown]");
    currentDropdown.classList.toggle("active");
  }

  document.querySelectorAll("[data-dropdown].active").forEach((dropdown) => {
    
    
    if (dropdown === currentDropdown) return;
    dropdown.classList.remove("active");
  });
});

完整代码

完整代码示例下载

猜你喜欢

转载自blog.csdn.net/qq_33003143/article/details/131874649