同一容器内多按钮独立下拉菜单的实现方案咨询
问题描述
基于某示例开发下拉菜单,希望在同一div容器内实现单个按钮对应独立的下拉菜单。当前代码在单个按钮时可正常工作,但存在多个按钮时,所有按钮共用同一个下拉菜单。

▲ 第一个按钮的下拉菜单可正常工作

▲ 同一DIV内的第二个按钮也会显示相同的下拉菜单...
我认为问题与position:absolute属性有关,移除该属性后情况略有改善,但下拉菜单的位置会偏移到容器区域。
已尝试方案
原本期望下拉菜单仅绑定到特定ID(如translate),但添加下拉菜单后,同一容器内的所有按钮都会触发该下拉菜单,不符合需求。
尝试过的代码如下:
/* Page settings */ .page-settings { @include flex-center; position: fixed; flex-direction: row; z-index: 10; top: 3vw; right: 2vw; .btn { @include flex-center; @include ease-in-out; width: min(10vw, 80px); aspect-ratio: 1 / 1; border-radius: 50%; margin: 0 4%; background-color: var(--color-grey-4); border: none; box-shadow: var(--box-shadow-1); i { font-size: var(--size-button); color: var(--color-grey-1); pointer-events: none; } &:hover { transform: translateY(-3px); box-shadow: 0 10px 20px var(--color-white); } } } #translate { &:focus, &:active { .dropdown { transform: translate(0, 20px); opacity: 1; visibility: visible; } } .material-icons { border-radius: 100%; animation: ripple 0.6s linear infinite; } .dropdown { position: absolute; top: 100%; left: 0; background: #fff; width: 100%; border-radius: 4px; box-shadow: 0 4px 12px rgba(#000, .1); text-align: left; opacity: 0; visibility: hidden; &:before { content: ''; position: absolute; top: -6px; left: 20px; width: 0; height: 0; box-shadow: 2px -2px 6px rgba(#000, .05); border-top: 6px solid #fff; border-right: 6px solid #fff; border-bottom: 6px solid transparent; border-left: 6px solid transparent; transform: rotate(-45deg); mix-blend-mode: multiple; } li { z-index: 1; position: relative; background: #fff; padding: 0 20px; color: #666; &:first-child { border-radius: 4px 4px 0 0; } &:last-child { border-radius: 0 0 4px 4px; a { border-bottom: 0; } } } a { display: block; border-bottom: 1px solid rgba(#000, .05); padding: 16px 0; color: inherit; font-size: 10px; text-decoration: none; } } } @media screen and (max-width: 600px) { .page-settings { flex-direction: column; .btn { margin: 7% 2%; } } }
最小可复现代码如下:
body { background: #f5f5f5; height: 100%; color: rgba(0, 0, 0, 0.87); font-family: "Roboto", sans-serif; font-size: 14px; font-weight: 400; line-height: 1.5em; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .container { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); } .btn { outline: 0; display: inline-flex; align-items: center; justify-content: space-between; background: #5380f7; min-width: 260px; border: 0; border-radius: 4px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); box-sizing: border-box; padding: 16px 20px; color: #fff; font-size: 12px; font-weight: 600; letter-spacing: 1.2px; text-transform: uppercase; overflow: hidden; cursor: pointer; } .btn:focus .dropdown, .btn:active .dropdown { transform: translate(0, 20px); opacity: 1; visibility: visible; } .btn .material-icons { border-radius: 100%; -webkit-animation: ripple 0.6s linear infinite; animation: ripple 0.6s linear infinite; } .btn .dropdown { position: absolute; top: 100%; left: 0; background: #fff; width: 100%; border-radius: 4px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); text-align: left; opacity: 0; visibility: hidden; transition: 0.3s ease; } .btn .dropdown:before { content: ""; position: absolute; top: -6px; left: 20px; width: 0; height: 0; box-shadow: 2px -2px 6px rgba(0, 0, 0, 0.05); border-top: 6px solid #fff; border-right: 6px solid #fff; border-bottom: 6px solid rgba(0, 0, 0, 0); border-left: 6px solid rgba(0, 0, 0, 0); transform: rotate(-45deg); mix-blend-mode: multiple; } .btn .dropdown li { z-index: 1; position: relative; background: #fff; padding: 0 20px; color: #666; } .btn .dropdown li.active { color: #5380f7; } .btn .dropdown li:first-child { border-radius: 4px 4px 0 0; } .btn .dropdown li:last-child { border-radius: 0 0 4px 4px; } .btn .dropdown li:last-child a { border-bottom: 0; } .btn .dropdown a { display: block; border-bottom: 1px solid rgba(0, 0, 0, 0.05); padding: 16px 0; color: inherit; font-size: 10px; text-decoration: none; } @-webkit-keyframes ripple { 0% { box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.1), 0 0 0 20px rgba(255, 255, 255, 0.1), 0 0 0 40px rgba(255, 255, 255, 0.1), 0 0 0 60px rgba(255, 255, 255, 0.1); } 100% { box-shadow: 0 0 0 20px rgba(255, 255, 255, 0.1), 0 0 0 40px rgba(255, 255, 255, 0.1), 0 0 0 60px rgba(255, 255, 255, 0.1), 0 0 0 80px rgba(255, 255, 255, 0); } } @keyframes ripple { 0% { box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.1), 0 0 0 20px rgba(255, 255, 255, 0.1), 0 0 0 40px rgba(255, 255, 255, 0.1), 0 0 0 60px rgba(255, 255, 255, 0.1); } 100% { box-shadow: 0 0 0 20px rgba(255, 255, 255, 0.1), 0 0 0 40px rgba(255, 255, 255, 0.1), 0 0 0 60px rgba(255, 255, 255, 0.1), 0 0 0 80px rgba(255, 255, 255, 0); } }
<div class="container"> <!-- Btn--> <button class="btn"> <span>Account Settings</span><i class="material-icons">public</i> <ul class="dropdown"> <li class="active"><a href="#">Profile Information</a></li> <li><a href="#">Change Password</a></li> <li> <a href="#">Become <b>PRO</b></a> </li> <li><a href="#">Help</a></li> <li><a href="#">Log Out</a></li> </ul> </button> <button class="btn"> <span>Account Settings</span><i class="material-icons">public</i> <ul class="dropdown"> <li class="active"><a href="#">Profile Information</a></li> <li><a href="#">Change Password</a></li> <li> <a href="#">Become <b>PRO</b></a> </li> <li><a href="#">Help</a></li> <li><a href="#">Log Out</a></li> </ul> </button> </div>
调研情况
尝试创建新类.dropdown-menu,但未解决问题;也曾尝试调整position:absolute及top、left定位,改用grid布局,均未成功。
通过谷歌搜索相关问题,得到的答案多样,但均不符合当前问题场景。
求助问题
如何在同一容器下实现多个按钮各自独立的下拉菜单?
感谢帮助!
内容的提问来源于stack exchange,提问作者voaneves
相关产品推荐
相关产品推荐

