如何让绝对定位的select类显示在绝对定位的drawer类上方?
问题:绝对定位的.select无法显示在.drawer上方
我尝试让绝对定位的.select元素显示在绝对定位的.drawer元素上方,试过各种办法,调z-index也没用。
- 当前效果:红色下拉框被白色的.drawer容器底部截断,只能看到部分选项
- 预期效果:红色下拉框完整展开,盖在白色.drawer容器上面
相关代码
HTML
<div class="drawer"> <div class="field"> <div class="input"> <p>field</p> </div> </div> <div class="field"> <div class="input"> <p>field</p> </div> </div> <div class="field"> <div class="label"> <p>select</p> </div> <div class="select hidden"> <p>option 1</p> <p>option 2</p> <p>option 3</p> </div> </div> </div>
CSS
body { background-color: blue; position: relative; } .drawer { position: absolute; background-color: white; height: 200px; width: 500px; right: 0; top: 0; overflow: hidden; } .field { position: relative; } .input { background-color: green; } .label { background-color: yellow; } .select { position: absolute; top: 0; left: 0; width: 100px; background-color: red; transform: translate3d(0px, 20px, 0px); display: block; overflow: auto; will-change: transform; top: 0px; left: 0px; } .select.hidden { display: none; }
JS
var label = document.querySelector('.label'); var select = document.querySelector('.select'); var clickHandler = function() { select.classList.toggle('hidden'); }; label.addEventListener('click', clickHandler);
解决方案
问题出在两个核心点:
.drawer设置了overflow: hidden,这个属性会直接裁剪所有超出容器范围的子元素,不管子元素是不是绝对定位。.select用了transform: translate3d(),这会创建独立的堆叠上下文,就算调整z-index,也只能在这个上下文内生效,没法突破父容器的裁剪限制。
方案1:移除.drawer的overflow:hidden
直接删掉.drawer里的overflow: hidden,超出容器的.select就不会被裁剪,自然能显示在.drawer上方:
.drawer { position: absolute; background-color: white; height: 200px; width: 500px; right: 0; top: 0; /* 移除overflow: hidden */ }
方案2:保留.drawer的裁剪效果,调整DOM结构
如果需要.drawer继续裁剪其他内容,就把.select从.drawer的DOM结构里移出来,放到body下面,再通过JS计算位置对齐到.label:
<div class="drawer"> <div class="field"> <div class="input"> <p>field</p> </div> </div> <div class="field"> <div class="input"> <p>field</p> </div> </div> <div class="field"> <div class="label"> <p>select</p> </div> </div> </div> <!-- 将.select移到drawer外部 --> <div class="select hidden"> <p>option 1</p> <p>option 2</p> <p>option 3</p> </div>
修改JS实现位置对齐:
var label = document.querySelector('.label'); var select = document.querySelector('.select'); var clickHandler = function() { select.classList.toggle('hidden'); if (!select.classList.contains('hidden')) { const rect = label.getBoundingClientRect(); select.style.top = `${rect.bottom}px`; select.style.left = `${rect.left}px`; } }; label.addEventListener('click', clickHandler);
内容的提问来源于stack exchange,提问作者Luis Henrique Valgoi
相关产品推荐
相关产品推荐

