You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

同一容器内多按钮独立下拉菜单的实现方案咨询

问题描述

基于某示例开发下拉菜单,希望在同一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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 08:31:01