我正在尝试为React构建自定义下拉组件。不幸的是,我的子列表的宽度(我设置为100%)显示为比其父元素更宽。
DOM:
<div className="dd-wrapper" id={this.state.wrapperID}>
<div className="dd-header" id={this.state.headerID} onClick={() => this.toggleList()}>
<div className="dd-header-title"></div>
</div>
<ul className="dd-list hidden" id={this.state.listID}>
<li className="dd-list-item">Test</li>
<li className="dd-list-item">Test2</li>
<li className="dd-list-item">Test3</li>
</ul>
</div>
toggleList
函数从列表中删除hidden
类,并将边框属性类dd-border
添加到包装器中,该包装器也表现不正常(边框仅包装头)。
它在父元素中被调用(我正在使用Bootstrap网格):
<div className="col-md-3">
<label> Dropdown
<Dropdown id="test-dd"/>
</label>
</div>
这是相关的css:
.dd-wrapper {
width: 100%;
margin-top: 8px;
}
.dd-header {
height: 40px;
background-color: #E2E8F2;
background-image: url("assets/images/down-chevron.png");
background-repeat: no-repeat;
background-position: 95% 50%;
}
.dd-list {
list-style-type: none;
background-color: white;
position: absolute;
}
.dd-list li {
height: 40px;
}
.dd-border {
border: 1px solid #3d70b2;
}
label {
display: inline-block;
width: 100%;
font-size: 14px;
}
.hidden {
display: none;
}
结果如下:
如何在不手动操作的情况下获得与其父级匹配的宽度(以确保它适用于任何大小的下拉列表?其次,是否有人知道让边框覆盖孩子的好方法?
答案 0 :(得分:2)
快速说明:这是一个CSS问题,因此您的React逻辑只是任何愿意回答的人的障碍。我已根据您的描述将重要部分提取到下面没有React的工作代码段中。我建议撤销对你的问题背景不重要的任何事情,以鼓励更快速的答案。
如何在不手动操作的情况下获得与其父级匹配的宽度(以确保它适用于任何大小的下拉列表?
我认为你要找的主要内容是position: relative
。因为绝对定位的元素大小和位置自己对抗第一个&#34;定位&#34;祖先。因此,您可以将其与top
,left
,right
,bottom
,width
和/或height
值相结合(以及可能是box-sizing: border-box;
)
...有没有人知道让边界覆盖孩子的好方法?
您可以通过将下拉菜单直接放在底部并在公共父级上切换类来隐藏/显示某些边框来伪造它。
以下是要演示的片段:
// The toggle logic in vanilla JS just to make the example work
// This, instead of toggling "hidden" on the list, toggles a "dd-closed" class on the wrapper
const wrapperEl = document.querySelector('.js-wrapper')
const headerEl = document.querySelector('.js-header')
if (wrapperEl && headerEl) {
const ancestorLabel = headerEl.closest('label')
const targetEl = ancestorLabel ? ancestorLabel : headerEl
targetEl.addEventListener('click',
() => wrapperEl.classList.toggle('dd-closed')
)
}
&#13;
.dd-wrapper {
position: relative;
width: 100%;
margin-top: 8px;
}
.dd-header {
position: relative;
height: 40px;
background-color: #E2E8F2;
background-repeat: no-repeat;
background-position: 95% 50%;
border: 1px solid #3d70b2;
border-bottom-width: 0;
padding-right: 3em;
}
.dd-header::before {
position: absolute;
content: '\25B4';
right: 0;
text-align: center;
line-height: 40px;
width: 1em;
top: 0;
bottom: 0;
font-size: 2em;
}
.dd-list {
list-style-type: none;
background-color: white;
position: absolute;
border: 1px solid #3d70b2;
margin-top: 0;
left: 0; right: 0;
padding: 0;
}
.dd-list li {
vertical-align: middle;
padding: 1em;
}
.dd-list li:hover {
background-color: #eee;
}
label {
display: inline-block;
width: 100%;
font-size: 14px;
}
.dd-closed > .dd-header::before {
content: '\25BE';
float: right;
}
.dd-closed > .dd-header {
border-bottom-width: 1px;
}
.dd-closed > .dd-list {
display: none;
}
&#13;
<!-- Basically what React would render as your output HTML...plus any necessary changes -->
<label> Dropdown
<div class="dd-wrapper dd-closed js-wrapper">
<div class="dd-header js-header">
<div class="dd-header-title"></div>
</div>
<ul class="dd-list">
<li class="dd-list-item">Test</li>
<li class="dd-list-item">Test2</li>
<li class="dd-list-item">Test3</li>
</ul>
</div>
</label>
<p>(Some other content for the dropdown to cover)</p>
<button>(I do nothing)</button>
&#13;