Reputation: 355
Here I have a dropdown entirely made using vanilla JavaScript. But the thing when I click on the dropdown-btn it moves other elements.
let dropdownBtn = document.querySelector("button.dropdown-btn");
let itemListWrapper = document.querySelector("div.item-list-wrapper");
dropdownBtn.addEventListener("click", () => {
if (itemListWrapper.style.display === "none") {
itemListWrapper.style.display = "block";
} else {
if (itemListWrapper.style.display === "block" || itemListWrapper.style.display === "") {
itemListWrapper.style.display = "none";
}
}
});
function continuouslyClickDropdownBtn() {
dropdownBtn.click();
setTimeout(() => {
continuouslyClickDropdownBtn();
}, 750);
}
continuouslyClickDropdownBtn();
.container {
background-color: lightblue;
height: 200px;
padding: 0 2em;
}
.dropdown-wrapper {
width: fit-content;
background-color: hsla(0, 0%, 95%, 0.9);
padding: 0.3em;
border-radius: 0.3em;
position: relative;
}
.dropdown-btn {
border-radius: 0.3em;
width: 100%;
height: 1.75em;
font-size: 1.25em;
cursor: pointer;
}
.item-list-wrapper {
margin-top: 0.5em;
}
.dropdown-item-list {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
gap: 0.1em
}
.dropdown-item {
font-size: 1em;
width: 100%;
padding: 0.2em 0;
display: flex;
flex-direction: row;
cursor: pointer;
}
.dropdown-item:hover {
background-color: hsla(0, 0%, 80%, 1);
font-weight: bold;
}
.dropdown-item span {
flex-grow: 1;
padding: 0 1empx;
}
<div class="container">
<p>upper text</p>
<div class="dropdown-wrapper">
<button class="dropdown-btn">Media Quality</button>
<div class="item-list-wrapper">
<ul class="dropdown-item-list">
<li class="dropdown-item">
<span>360p</span>
</li>
<li class="dropdown-item">
<span>720p</span>
</li>
<li class="dropdown-item">
<span>1080p</span>
</li>
</ul>
</div>
</div>
<p>bottom text</p>
</div>
I tried adding this CSS:
.item-list-wrapper {
margin-top: 0.5em;
position: absolute;
}
But then it removes the background-color from all items.
Even if add say background-color: hsla(0, 0%, 95%, 0.9);
to the class it just adds it to the width of items.
I can't get the background-color to wrap around the whole dropdown once it is open.
How can this be fixed ?
Upvotes: 1
Views: 673
Reputation: 15213
Use absolute positioning for .item-list-wrapper
, adding additional rules to normalize the display of this dropdown menu. Use this selector with css rules:
.item-list-wrapper {
position: absolute;
left: 0;
right: 0;
background-color: inherit;
padding: inherit;
border-radius: 0 0 0.3em 0.3em;
}
With these rules, you inherit the background color, make the width relative to the parent, and set border-radius for the bottom of the dropdown menu.
let dropdownBtn = document.querySelector("button.dropdown-btn");
let itemListWrapper = document.querySelector("div.item-list-wrapper");
dropdownBtn.addEventListener("click", () => {
if (itemListWrapper.style.display === "none") {
itemListWrapper.style.display = "block";
} else {
if (itemListWrapper.style.display === "block" || itemListWrapper.style.display === "") {
itemListWrapper.style.display = "none";
}
}
});
function continuouslyClickDropdownBtn() {
dropdownBtn.click();
setTimeout(() => {
continuouslyClickDropdownBtn();
}, 750);
}
continuouslyClickDropdownBtn();
.container {
background-color: lightblue;
height: 200px;
padding: 0 2em;
}
.dropdown-wrapper {
width: fit-content;
background-color: hsla(0, 0%, 95%, 0.9);
padding: 0.3em;
border-radius: 0.3em;
position: relative;
}
.dropdown-btn {
border-radius: 0.3em;
width: 100%;
height: 1.75em;
font-size: 1.25em;
cursor: pointer;
}
.item-list-wrapper {
position: absolute;
left: 0;
right: 0;
background-color: inherit;
padding: inherit;
border-radius: 0 0 0.3em 0.3em;
}
.dropdown-item-list {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
gap: 0.1em;
}
.dropdown-item {
font-size: 1em;
width: 100%;
padding: 0.2em 0;
display: flex;
flex-direction: row;
cursor: pointer;
}
.dropdown-item:hover {
background-color: hsla(0, 0%, 80%, 1);
font-weight: bold;
}
.dropdown-item span {
flex-grow: 1;
padding: 0 1empx;
}
<div class="container">
<p>upper text</p>
<div class="dropdown-wrapper">
<button class="dropdown-btn">Media Quality</button>
<div class="item-list-wrapper">
<ul class="dropdown-item-list">
<li class="dropdown-item">
<span>360p</span>
</li>
<li class="dropdown-item">
<span>720p</span>
</li>
<li class="dropdown-item">
<span>1080p</span>
</li>
</ul>
</div>
</div>
<p>bottom text</p>
</div>
Upvotes: 1
Reputation: 23654
One way is to have an inner-wrapper
and set it to position:fixed
You'll have to set the height of the dropdown-wrapper
so the element still has a block-presence on the page
let dropdownBtn = document.querySelector("button.dropdown-btn");
let itemListWrapper = document.querySelector("div.item-list-wrapper");
dropdownBtn.addEventListener("click", () => {
if (itemListWrapper.style.display === "none") {
itemListWrapper.style.display = "block";
} else {
if (itemListWrapper.style.display === "block" || itemListWrapper.style.display === "") {
itemListWrapper.style.display = "none";
}
}
});
function continuouslyClickDropdownBtn() {
dropdownBtn.click();
setTimeout(() => {
continuouslyClickDropdownBtn();
}, 750);
}
continuouslyClickDropdownBtn();
.container {
background-color: lightblue;
height: 200px;
padding: 0 2em;
}
.dropdown-wrapper {
position: relative;
height: 40px;
}
.inner-wrapper {
position: fixed;
width: fit-content;
background-color: hsla(0, 0%, 95%, 0.9);
padding: 0.3em;
border-radius: 0.3em;
}
.dropdown-btn {
border-radius: 0.3em;
width: 100%;
height: 1.75em;
font-size: 1.25em;
cursor: pointer;
}
.item-list-wrapper {
margin-top: 0.5em;
}
.dropdown-item-list {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
gap: 0.1em
}
.dropdown-item {
font-size: 1em;
width: 100%;
padding: 0.2em 0;
display: flex;
flex-direction: row;
cursor: pointer;
}
.dropdown-item:hover {
background-color: hsla(0, 0%, 80%, 1);
font-weight: bold;
}
.dropdown-item span {
flex-grow: 1;
padding: 0 1empx;
}
<div class="container">
<p>upper text</p>
<div class="dropdown-wrapper">
<div class="inner-wrapper">
<button class="dropdown-btn">Media Quality</button>
<div class="item-list-wrapper">
<ul class="dropdown-item-list">
<li class="dropdown-item">
<span>360p</span>
</li>
<li class="dropdown-item">
<span>720p</span>
</li>
<li class="dropdown-item">
<span>1080p</span>
</li>
</ul>
</div>
</div>
</div>
<p>bottom text</p>
</div>
Upvotes: 1