Reputation: 314
I am trying to style a select drop down box. The custom select box has rounded corners and a dropdown list (a box that drops down with the options) that shows on focus. I used the css below to style the select box. I have also substituted the html select with DIV elements.
Here is the code I have used so far:
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>
The styles I have applied to the select tag are coming into effect, but the problem is that the dropdown box top border does not blend with the select box itself on focus. Is it only possible to change the SELECT input style on focus from a round border to a square border?
Would someone with some more knowledge in this regard please take a few minutes to suggest a solution?
Upvotes: 0
Views: 1176
Reputation: 314
The above code is a solution strictly from a styling point of view. But as per @CBroe remarks, from a usability point of view (for example using the select via keyboard is impossible), the code is not optimal.
This is why I came up with a solution that uses the jQuery plugin Select2
If anyone is interested here is a link to the code https://www.codeply.com/p/Z999PpuSOK
Upvotes: 0
Reputation: 66218
It depends on what you mean by "blending", but if you want to achieve a more harmonious look, you can do the following:
border-bottom-left-radius
and border-bottom-right-radius
of the trigger element to 0px
when the dropdown is open, so that the select trigger visually continues to the dropdown that is visibleSee proof-of-concept below:
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>
Upvotes: 1