纯CSS可点击下拉菜单?

8

这个教程解释了如何使用:hover伪类来在悬停时为HTML元素设置样式,以及如何在纯CSS中悬停在特定元素上时创建下拉菜单(不使用任何JavaScript)。

是否可以在单击元素而不是悬停在元素上时,在纯CSS中创建与下面示例中相同的下拉菜单?

我希望尽可能不使用JavaScript,或者如果没有JavaScript则无法实现,则尽可能少地使用JavaScript。下拉菜单的项本身应该可点击。

示例:

.dropdown {
    position: relative;
    display: inline-block;
}

.dropbtn {
    background-color: #4CAF50;
    color: white;
    padding: 16px;
    font-size: 16px;
    border: none;
    cursor: pointer;
}

.dropdown-content {
    display: none;
    position: absolute;
    right: 0;
    background-color: #f9f9f9;
    min-width: 160px;
    box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
    z-index: 1;
}

.dropdown-content a {
    color: black;
    padding: 12px 16px;
    text-decoration: none;
    display: block;
}

.dropdown-content a:hover {background-color: #f1f1f1}

.dropdown:hover .dropdown-content {
    display: block;
}

.dropdown:hover .dropbtn {
    background-color: #3e8e41;
}
<div class="dropdown" style="float:left;">
  <button class="dropbtn">Left</button>
  <div class="dropdown-content" style="left:0;">
    <a href="#">Link 1</a>
    <a href="#">Link 2</a>
    <a href="#">Link 3</a>
  </div>
</div>


可能需要巧妙地使用聚焦事件。 - Randy Hall
1
纯粹的代码编写请求在 Stack Overflow 上是不被允许的,我们期望这里的问题与具体的编程问题有关,但我们很乐意帮助您自己编写代码!告诉我们您尝试过什么,并且卡在了哪里。这也将有助于我们更好地回答您的问题。 - Heretic Monkey
可以使用输入和:checked伪类来实现。你已经尝试过什么了吗?例如https://codepen.io/gcyrillus/pen/dsvwF,它展示了焦点和选中的行为,请选择最适合您需求的方法,并查看每种方法在使用时涉及的内容以及在HTML代码中所需的内容。这两个示例都是手风琴式的,在初始使用时非常相似。 - G-Cyrillus
另一个使用pointer-events的示例:https://codepen.io/gcyrillus/pen/pyjrjP 还有手风琴...那么你到目前为止尝试了哪些CSS方法?:focus, :target, :checked, pointer-events,还是其他的? - G-Cyrillus
8
不行,因为它仍然没有展示任何实际让它工作的尝试。此外,在Stack Overflow上没有代码。我在评论中链接的文章[ask]在“帮助他人复现问题”下说明了我们需要的内容:如果可以创建一个可以链接到问题的实时示例(例如,在http://sqlfiddle.com/或http://jsbin.com/上),那么请这样做 - 但也要将代码包含在您的问题本身中。不是每个人都可以访问外部网站,并且链接可能会随着时间而破裂。 - Heretic Monkey
显示剩余2条评论
3个回答

26

在这里,您使用了一个隐藏的复选框,并在其“被选中”时显示菜单。

/*hide the inputs/checkmarks and submenu*/
input, ul.submenu {
  display: none;
}

/*position the label*/
label {
  position: relative;
  display: block;
  cursor: pointer;
}

/*show the submenu when input is checked*/
input:checked~ul.submenu {
  display: block;
}
<input id="check01" type="checkbox" name="menu" />
<label for="check01">Menu</label>
<ul class="submenu">
  <li><a href="#">Item 1</a></li>
  <li><a href="#">Item 2</a></li>
</ul>

源自这个 Codepen的简化版。


这太棒了!可惜在菜单外面点击时它不会关闭。 - Janne Annala
@JanneAnnala,请查看我的更新,但是我不确定在实际应用中它是否有效,请确保进行测试! - CalvT
谢谢!我尝试了类似的方法,但不幸的是它不起作用,因为在mousedown时焦点丢失,但在mouseup时链接被打开,所以菜单在mouseup触发之前就消失了,没有链接被打开。 - Janne Annala
我猜这就是你不按常规方式操作的结果。非常聪明,使用复选框! - Mr PizzaGuy

8

使用单选按钮和同级选择器。

与复选框不同的是,当单击不同的菜单项时,它将自动关闭打开的菜单项。

.menu ul,
.menu input,
.menu .closer,
.menu input:checked~.opener {
  display: none;
}

.menu input:checked~ul,
.menu input:checked~.closer {
  display: block;
}
<ul class="menu">
  <li>
    <input type="radio" name="menuopt" id="drop1" />
    <label class="opener" for="drop1">Parent item 1</label>
    <label class="closer" for="dropclose">Parent item 1</label>
    <ul>
      <li><a href="">Menu item 1</a></li>
      <li><a href="">Menu item 2</a></li>
      <li><a href="">Menu item 3</a></li>
    </ul>
  </li>
  <li>
    <input type="radio" name="menuopt" id="drop2" />
    <label class="opener" for="drop2">Parent item 2</label>
    <label class="closer" for="dropclose">Parent item 2</label>
    <ul>
      <li><a href="">Menu item 1</a></li>
      <li><a href="">Menu item 2</a></li>
      <li><a href="">Menu item 3</a></li>
      <li><a href="">Menu item 4</a></li>
      <li><a href="">Menu item 5</a></li>
    </ul>
    <input type="radio" name="menuopt" id="dropclose" />
  </li>
</ul>

View on jsFiddle


7

例子1:下拉菜单。纯CSS编写。简洁风格。
jsfiddle链接

body {
  margin: 0;
  font-size: 20px;
  font-family: Times, "Times New Roman", serif;
}

/* dd container */
.dropdown {
  display: inline-block;
  position: relative;
  outline: none;
  margin: 10px;
}

/* button */
.dropbtn {
  padding: 12px 16px;
  color: white;
  background-color: #861cb9;
  cursor: pointer;
  transition: 0.35s ease-out;
}

/* dd content */
.dropdown .dropdown-content {
  position: absolute;
  top: 50%;
  background-color: #f7f7f7;
  min-width: 120%;
  box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.2);
  z-index: 100000;
  visibility: hidden;
  opacity: 0;
  transition: 0.35s ease-out;
}
.dropdown-content a {
  color: black;
  padding: 12px 16px;
  display: block;
  text-decoration: none;
  transition: 0.35s ease-out;
}
.dropdown-content a:hover {
  background-color: #eaeaea;
}

/* show dd content */
.dropdown:focus .dropdown-content {
  outline: none;
  transform: translateY(20px);
  visibility: visible;
  opacity: 1;
}
.dropbtn:hover, .dropdown:focus .dropbtn {
  background-color: #691692;
}

/* mask to close menu by clicking on the button */
.dropdown .db2 {
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0; opacity: 0;
  cursor: pointer;
  z-index: 10;
  display: none;
}
.dropdown:focus .db2 {
  display: inline-block;
}
.dropdown .db2:focus .dropdown-content {
  outline: none;
  visibility: hidden;
  opacity: 0;
}
<div class="dropdown" tabindex="1">
  <i class="db2" tabindex="1"></i>
  <a class="dropbtn">Dropdown 1</a>
   <div class="dropdown-content">
      <a href="#">Home</a>
      <a href="#">About</a>
      <a href="#">Contact</a>
   </div>
</div>

<div class="dropdown" tabindex="1">
  <i class="db2" tabindex="1"></i>
  <a class="dropbtn">Dropdown 2</a>
   <div class="dropdown-content">
      <a href="#">Blog</a>
      <a href="#">Plans</a>
      <a href="#">Partners</a>
   </div>
</div>

例子2. 增加了样式。纯CSS,没有JS。下拉菜单/内容通过点击打开和关闭。多种方法可关闭(通过相同的按钮,通过另一个按钮,通过在菜单区域外单击,通过菜单内的图标)。此外,还通过 :hover 添加了子菜单。
jsfiddle链接

body {
  margin: 0;
  font-size: 20px;
  font-family: Times, "Times New Roman", serif;
}

/* dd container */
.dropdown {
  display: inline-block;
  position: relative;
  outline: none;
  background-color: #861cb9;
  margin: 10px 5px;
}

/* button */
.dropbtn {
  display: inline-block;
  padding: 12px 16px;
  color: white;
  cursor: pointer;
  background-color: #861cb9;
  transition: 0.35s ease-out;
}
.dropbtn:hover, .dropbtn.c:hover, .dropbtn.r:hover {
  background-color: #691692;
}

/* dd content */
.dropdown .dropdown-content {
  position: absolute;
  top: 50%;
  visibility: hidden;
  opacity: 0;
  z-index: 100000;
  background-color: #f7f7f7;
  min-width: 120%;
  padding: 10px;
  font-size: 16px;
  box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.2);
  transition: 0.35s ease-out;
}

/* center & right position menu relative to the button */
.dropdown .dropdown-content.c  {
  left: 50%;
  margin-left: calc(-60% - 10px);
}
.dropdown .dropdown-content.r  {
  right: 0;
}

/* style link menu item */
.dropdown-content .mi {
  display: block;
  color: black;
  padding: 8px 0;
  text-decoration: none;
  position: relative;
}
.dropdown-content .mi::before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background:
  linear-gradient(
  90deg,
  rgba(240, 242, 244, 0) 0%,
  rgba(223, 223, 223, 1) 30%,
  rgba(240, 242, 244, 0) 100%
  );
  opacity: 0;
  z-index: -1;
  transition: 0.4s ease-out;
}
.dropdown-content .mi:hover::before {
    opacity: 1;
}

/* style text link */
.dropdown-content .tl {
  color: #36f;
  text-decoration: none;
  border-bottom: 1px dotted #36f;
  transition: 0.35s ease-out;
}
.dropdown-content .tl:hover {
  border-bottom: 1px dotted transparent;
}

/* show dd content */
.dropdown:focus .dropdown-content {
  outline: none;
  visibility: visible;
  opacity: 1;
  transform: translateY(20px);
}

/* mask to close menu by clicking on the button */
.dropdown .db2 {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  opacity: 0;
  cursor: pointer;
  z-index: 10;
  display: none;
}
.dropdown:focus .db2 {
  display: inline-block;
}
.dropdown .db2:focus .dropdown-content, .dropdown-content .db3:focus .dropdown-content {
  outline: none;
  visibility: hidden;
  opacity: 0;
}

/* button gradient */
.dropbtn::before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: -1;
  background: radial-gradient(circle at 0 0, #fff 0%, #D59BF0 5%, #8b1dc0 35%, transparent 60%);
  background-repeat: no-repeat;
  background-color: #861cb9;
  transition: 0.35s ease-out;
}

/* class 'c' center gradient backlight */
.dropbtn.c::before {
  background: radial-gradient(circle at 50% -1px, #fff 0%, #D59BF0 5%, #8b1dc0 35%, transparent 60%);
  background-repeat: no-repeat;
  background-color: #861cb9;
}

/* class 'r' right gradient backlight */
.dropbtn.r::before {
  background: radial-gradient(circle at 100% 0, #fff 0%, #D59BF0 5%, #8b1dc0 35%, transparent 60%);
  background-repeat: no-repeat;
  background-color: #861cb9;
}

/* show gradient backlight */
.dropdown:focus .dropbtn::before, .dropdown:focus .dropbtn.c::before, .dropdown:focus .dropbtn.r::before {
background-color: #691692;
}
.dropdown:focus  {
z-index: 1;
}
.dropdown:focus .dropbtn  {
background: none;
}

/* icon hamburger */
.dropbtn::after {
  content: "";
  display: inline-block;
  width: 15px;
  height: 3px;
  margin-left: 10px;
  border-top: 2px solid #fff;
  border-bottom: 7px double #fff;
}
.dropdown:focus .dropbtn::after {
  height: 0;
  border-bottom: 0;
  margin-bottom: 4px;
}

/* icon content */
.dropbtn.i2::after {
  content: "";
  display: inline-block;
  border: 0;
  width: 15px;
  height: 12px;
  margin-left: 10px;
  background:
  linear-gradient(to right, #fff, #fff) 0px 0px/11px 2px, /* left top / width height */
  linear-gradient(to right, #fff, #fff) 0px 5px/15px 2px,
  linear-gradient(to right, #fff, #fff) 0px 10px/8px 2px;
  background-repeat: no-repeat;
}
.dropdown:focus .dropbtn.i2::after {
  width: 15px;
  height: 12px;
  background: linear-gradient(to right, #fff, #fff) 0px 10px/15px 2px;
  background-repeat: no-repeat;
}

/* icon x */
.dropdown-content .db3  {
  display: inline-block;
  position: absolute;
  top: 5px;
  right: 5px;
  width: 18px;
  height: 18px;
  padding: 0;
  border-radius: 100%;
  z-index: 10;
  transition: 0.15s ease-out;
}
.dropdown-content .db3::before, .dropdown-content .db3::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  height: 60%;           /* height icon */
  width: 2px;            /* width icon  */
  background: #3c4043;   /* color icon  */
}
.dropdown-content .db3::before {
  transform: translate(-50%, -50%) rotate(45deg);
}
.dropdown-content .db3::after  {
  transform: translate(-50%, -50%) rotate(-45deg);
}
.dropdown-content .db3:hover   {
  background: #d1d1d6;
}

/* sub menu container */
.sub-dropdown {
  position: relative;
}
.sub-dropdown-content {
  position: absolute;
  visibility: hidden;
  opacity: 0;
  background-color: #f7f7f7;
  left: 100%;
  top: -10px;
  padding: 10px 5px;
  box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
  z-index: 1;
  transition: 0.35s ease-out;
}
.sub-dropdown-content a {
  color: black;
  padding: 5px 12px;
  text-decoration: none;
  display: block;
  position: relative;
  white-space: nowrap;
}

/* sub menu item */
.si {
  cursor: default;
}
.si::after {
  content: "\25B8";
  margin-left: 5px;
  vertical-align: -1px;
  margin-right: 10px;
  float: right;
}
.sub-dropdown:hover .sub-dropdown-content {
  visibility: visible;
  opacity: 1;
  transform: translateY(10px);
}
.sub-dropdown-content a::before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background:
  linear-gradient(
  90deg,
  rgba(240, 242, 244, 0) 0%,
  rgba(223, 223, 223, 1) 50%,
  rgba(240, 242, 244, 0) 100%
  );
  opacity: 0;
  z-index: -1;
  transition: 0.4s ease-out;
}
.sub-dropdown-content a:hover::before {
    opacity: 1;
}

/* media queries */
@media (max-width:560px) {
.dropdown .dropdown-content.r,
.dropdown .dropdown-content.c {
  left: 0;
  margin-left: 0;
  }
.dropbtn.c::before, .dropbtn.r::before {
  background: radial-gradient(circle at 0 0, #fff 0%, #D59BF0 5%, #8b1dc0 35%, transparent 60%);
  }
}
<div class="dropdown" tabindex="1">
  <i class="db2" tabindex="1"></i><a class="dropbtn i2">Dropdown l</a>
    <div class="dropdown-content"><i class="db3" tabindex="1"></i>
      <p>Dropdown content. Left-aligned relative to the button. Text <a href="#" class="tl">link</a> ....</p>
    </div>
</div>

<div class="dropdown" tabindex="1">
  <i class="db2" tabindex="1"></i><a class="dropbtn c">MyMenu c</a>
    <div class="dropdown-content c"><i class="db3" tabindex="1"></i>
      <a href="#" class="mi">Products</a>

      <div class="sub-dropdown">
      <a class="mi si">Company</a>
          <div class="sub-dropdown-content">
            <a href="#">Sublink 1</a>
            <a href="#">Sublink 2</a>
          </div>
      </div>

      <a href="#" class="mi">Stackoverflow</a>
    </div>
</div>

<div class="dropdown" tabindex="1">
  <i class="db2" tabindex="1"></i><a class="dropbtn r i2">Dropdown r</a>
    <div class="dropdown-content r"><i class="db3" tabindex="1"></i>
      <p>Dropdown content. Right-aligned relative to the button. Text <a href="#" class="tl">link</a> ....</p>
    </div>
</div>


一件值得更多点赞的杰作。但是<i>元素的作用是什么? - Gaspa79
  1. i class="db2"。这是一个不可见的按钮遮罩,以便重复点击菜单按钮关闭菜单。
  2. i class="db3"。它是菜单内部的关闭交叉按钮。
- Arsen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接