自定义 select 框
Custom select box
我正在尝试设置 select 下拉框的样式。自定义 select 框具有圆角和一个显示在焦点上的下拉列表(带有选项的下拉框)。我使用下面的 css 来设置 select 框的样式。我还将 html select 替换为 DIV 元素。
这是我目前使用的代码:
document.querySelector('.custom-select-wrapper').addEventListener('click', function() {
this.querySelector('.custom-select').classList.toggle('open');
for (const option of document.querySelectorAll(".custom-option")) {
option.addEventListener('click', function() {
if (!this.classList.contains('selected')) {
this.parentNode.querySelector('.custom-option.selected').classList.remove('selected');
this.classList.add('selected');
this.closest('.custom-select').querySelector('.custom-select__trigger span').textContent = this.textContent;
}
})
}
})
.custom-select-wrapper {
position: relative;
user-select: none;
width: 188px;
z-index: 30000000000;
}
.custom-select {
position: relative;
display: flex;
flex-direction: column;
}
.custom-select__trigger {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 10px;
height: 27px;
background: #ffffff;
cursor: pointer;
border: 1px solid #707070;
border-radius: 8px;
}
.custom-options {
position: absolute;
display: block;
top: 100%;
left: 0;
right: 0;
border: 1px solid #707070;
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
background: #fff;
transition: all 0.5s;
opacity: 0;
visibility: hidden;
pointer-events: none;
z-index: 2;
}
.custom-select.open .custom-options {
opacity: 1;
visibility: visible;
pointer-events: all;
}
.custom-option {
position: relative;
display: block;
padding: 0 10px 0 10px;
line-height: 25px;
cursor: pointer;
transition: all 0.5s;
}
.arrow {
position: relative;
top: 15px;
right: 15px;
}
.arrow::before,
.arrow::after {
content: "\f0d7";
font-family: "Font Awesome 5 Free";
font-size: 20px;
font-weight: 700;
color: #394a6d;
position: absolute;
bottom: 0px;
}
<div class="custom-select-wrapper">
<div class="custom-select">
<div class="custom-select__trigger">
<span>Option 1</span>
<div class="arrow"></div>
</div>
<div class="custom-options">
<span class="custom-option selected" data-value="tesla">Option 2</span>
<span class="custom-option" data-value="volvo">Option 3</span>
</div>
</div>
</div>
我在select标签上应用的样式正在生效,但问题是下拉框的顶部边框没有与焦点上的select框本身融合。是否只能将焦点上的 SELECT 输入样式从圆形边框更改为方形边框?
请在这方面有更多知识的人花几分钟时间提出解决方案吗?
这取决于你所说的“混合”是什么意思,但如果你想获得更和谐的外观,你可以这样做:
- 当下拉列表打开时,将触发器元素的
border-bottom-left-radius
和border-bottom-right-radius
设置为0px
,这样select触发器在视觉上继续到下拉列表可见
- 删除下拉菜单的顶部边框,这样您就不会用加倍粗的边框分隔触发器和下拉菜单
请参阅下面的概念验证:
document.querySelector('.custom-select-wrapper').addEventListener('click', function() {
this.querySelector('.custom-select').classList.toggle('open');
for (const option of document.querySelectorAll(".custom-option")) {
option.addEventListener('click', function() {
if (!this.classList.contains('selected')) {
this.parentNode.querySelector('.custom-option.selected').classList.remove('selected');
this.classList.add('selected');
this.closest('.custom-select').querySelector('.custom-select__trigger span').textContent = this.textContent;
}
})
}
})
.custom-select-wrapper {
position: relative;
user-select: none;
width: 188px;
z-index: 30000000000;
}
.custom-select {
position: relative;
display: flex;
flex-direction: column;
}
.custom-select__trigger {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 10px;
height: 27px;
background: #ffffff;
cursor: pointer;
border: 1px solid #707070;
border-radius: 8px;
transition: all 0.5s;
}
.custom-options {
position: absolute;
display: block;
top: 100%;
left: 0;
right: 0;
border: 1px solid #707070;
border-top: none;
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
background: #fff;
transition: all 0.5s;
opacity: 0;
visibility: hidden;
pointer-events: none;
z-index: 2;
}
.custom-select.open .custom-select__trigger {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.custom-select.open .custom-options {
opacity: 1;
visibility: visible;
pointer-events: all;
}
.custom-option {
position: relative;
display: block;
padding: 0 10px 0 10px;
line-height: 25px;
cursor: pointer;
transition: all 0.5s;
}
.arrow {
position: relative;
top: 15px;
right: 15px;
}
.arrow::before,
.arrow::after {
content: "\f0d7";
font-family: "Font Awesome 5 Free";
font-size: 20px;
font-weight: 700;
color: #394a6d;
position: absolute;
bottom: 0px;
}
<div class="custom-select-wrapper">
<div class="custom-select">
<div class="custom-select__trigger">
<span>Option 1</span>
<div class="arrow"></div>
</div>
<div class="custom-options">
<span class="custom-option selected" data-value="tesla">Option 2</span>
<span class="custom-option" data-value="volvo">Option 3</span>
</div>
</div>
</div>
以上代码是严格从样式角度的解决方案。但是根据@CBroe 的评论,从可用性的角度来看(例如通过键盘使用 select 是不可能的),代码不是最优的。
这就是我想出一个使用 jQuery 插件 Select2
的解决方案的原因
如果有人感兴趣,这里是 link 代码
https://www.codeply.com/p/Z999PpuSOK
我正在尝试设置 select 下拉框的样式。自定义 select 框具有圆角和一个显示在焦点上的下拉列表(带有选项的下拉框)。我使用下面的 css 来设置 select 框的样式。我还将 html select 替换为 DIV 元素。
这是我目前使用的代码:
document.querySelector('.custom-select-wrapper').addEventListener('click', function() {
this.querySelector('.custom-select').classList.toggle('open');
for (const option of document.querySelectorAll(".custom-option")) {
option.addEventListener('click', function() {
if (!this.classList.contains('selected')) {
this.parentNode.querySelector('.custom-option.selected').classList.remove('selected');
this.classList.add('selected');
this.closest('.custom-select').querySelector('.custom-select__trigger span').textContent = this.textContent;
}
})
}
})
.custom-select-wrapper {
position: relative;
user-select: none;
width: 188px;
z-index: 30000000000;
}
.custom-select {
position: relative;
display: flex;
flex-direction: column;
}
.custom-select__trigger {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 10px;
height: 27px;
background: #ffffff;
cursor: pointer;
border: 1px solid #707070;
border-radius: 8px;
}
.custom-options {
position: absolute;
display: block;
top: 100%;
left: 0;
right: 0;
border: 1px solid #707070;
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
background: #fff;
transition: all 0.5s;
opacity: 0;
visibility: hidden;
pointer-events: none;
z-index: 2;
}
.custom-select.open .custom-options {
opacity: 1;
visibility: visible;
pointer-events: all;
}
.custom-option {
position: relative;
display: block;
padding: 0 10px 0 10px;
line-height: 25px;
cursor: pointer;
transition: all 0.5s;
}
.arrow {
position: relative;
top: 15px;
right: 15px;
}
.arrow::before,
.arrow::after {
content: "\f0d7";
font-family: "Font Awesome 5 Free";
font-size: 20px;
font-weight: 700;
color: #394a6d;
position: absolute;
bottom: 0px;
}
<div class="custom-select-wrapper">
<div class="custom-select">
<div class="custom-select__trigger">
<span>Option 1</span>
<div class="arrow"></div>
</div>
<div class="custom-options">
<span class="custom-option selected" data-value="tesla">Option 2</span>
<span class="custom-option" data-value="volvo">Option 3</span>
</div>
</div>
</div>
我在select标签上应用的样式正在生效,但问题是下拉框的顶部边框没有与焦点上的select框本身融合。是否只能将焦点上的 SELECT 输入样式从圆形边框更改为方形边框?
请在这方面有更多知识的人花几分钟时间提出解决方案吗?
这取决于你所说的“混合”是什么意思,但如果你想获得更和谐的外观,你可以这样做:
- 当下拉列表打开时,将触发器元素的
border-bottom-left-radius
和border-bottom-right-radius
设置为0px
,这样select触发器在视觉上继续到下拉列表可见 - 删除下拉菜单的顶部边框,这样您就不会用加倍粗的边框分隔触发器和下拉菜单
请参阅下面的概念验证:
document.querySelector('.custom-select-wrapper').addEventListener('click', function() {
this.querySelector('.custom-select').classList.toggle('open');
for (const option of document.querySelectorAll(".custom-option")) {
option.addEventListener('click', function() {
if (!this.classList.contains('selected')) {
this.parentNode.querySelector('.custom-option.selected').classList.remove('selected');
this.classList.add('selected');
this.closest('.custom-select').querySelector('.custom-select__trigger span').textContent = this.textContent;
}
})
}
})
.custom-select-wrapper {
position: relative;
user-select: none;
width: 188px;
z-index: 30000000000;
}
.custom-select {
position: relative;
display: flex;
flex-direction: column;
}
.custom-select__trigger {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 10px;
height: 27px;
background: #ffffff;
cursor: pointer;
border: 1px solid #707070;
border-radius: 8px;
transition: all 0.5s;
}
.custom-options {
position: absolute;
display: block;
top: 100%;
left: 0;
right: 0;
border: 1px solid #707070;
border-top: none;
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
background: #fff;
transition: all 0.5s;
opacity: 0;
visibility: hidden;
pointer-events: none;
z-index: 2;
}
.custom-select.open .custom-select__trigger {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.custom-select.open .custom-options {
opacity: 1;
visibility: visible;
pointer-events: all;
}
.custom-option {
position: relative;
display: block;
padding: 0 10px 0 10px;
line-height: 25px;
cursor: pointer;
transition: all 0.5s;
}
.arrow {
position: relative;
top: 15px;
right: 15px;
}
.arrow::before,
.arrow::after {
content: "\f0d7";
font-family: "Font Awesome 5 Free";
font-size: 20px;
font-weight: 700;
color: #394a6d;
position: absolute;
bottom: 0px;
}
<div class="custom-select-wrapper">
<div class="custom-select">
<div class="custom-select__trigger">
<span>Option 1</span>
<div class="arrow"></div>
</div>
<div class="custom-options">
<span class="custom-option selected" data-value="tesla">Option 2</span>
<span class="custom-option" data-value="volvo">Option 3</span>
</div>
</div>
</div>
以上代码是严格从样式角度的解决方案。但是根据@CBroe 的评论,从可用性的角度来看(例如通过键盘使用 select 是不可能的),代码不是最优的。
这就是我想出一个使用 jQuery 插件 Select2
的解决方案的原因如果有人感兴趣,这里是 link 代码 https://www.codeply.com/p/Z999PpuSOK