I have some code that glitches initially when menus are expanded on top of each other.
If you select option two in the first menu, the second option appears. If you then go to open the first menu, you will see it glitches as it opens - there is almost a shutter-like delay. Maybe it has something to do with the z index setting, I'm not sure?
In firefox and chrome, there is no (apparent) glitch. In safari, the snippet below, there is a glitch.
Why is it glitching?
const selected = document.querySelectorAll(".selected");
const optionsContainer = document.querySelectorAll(".options-container");
for (let i = 0; i < selected.length; i++) {
selected[i].addEventListener("click", () => {
optionsContainer[i].classList.toggle("open");
selected[i].classList.toggle("open");
for (let j = 0; j < selected.length; j++) {
if (i != j && selected[j].classList.contains("open")) {
optionsContainer[j].classList.toggle("open");
selected[j].classList.toggle("open");
}
}
});
}
for (let i = 0; i < optionsContainer.length; i++) {
let optionsList = optionsContainer[i].querySelectorAll(".options");
for (let j = 0; j < optionsList.length; j++) {
optionsList.forEach(o => {
o.addEventListener("click", () => {
selected[i].innerHTML = o.querySelector("label").innerHTML;
optionsContainer[i].classList.remove("open");
selected[i].classList.remove("open");
if (document.getElementById("level").innerText.indexOf('one') === -1) {
document.getElementById("tier").style.display = "grid";
} else {
document.getElementById("tier").style.display = "none";
}
});
});
}
}
.filter-filterbox-row {
display: grid;
grid-template-columns: auto auto;
grid-template-areas: "question select-box";
padding: 5px 5px;
margin-top: -2px;
}
.filter-filterbox-row .question {
grid-template-areas: "question";
width: 100px;
padding-top: 5px;
padding-bottom: 10px;
padding-left: 15px;
text-align: right;
}
.filter-filterbox-row .select-box {
margin-left: -100px;
grid-template-areas: "select-box";
}
.select-box {
width: 200px;
}
.select-box .options-container {
background: #fff;
width: 200px;
display: none;
transition: all 0.4s;
position: absolute;
max-height: 240px;
border: 1px solid #253e5c;
border-radius: 0 0 4.5px 4.5px;
}
.selected {
position: relative;
border: 1px solid #cdcccc;
border-radius: 4.5px;
padding: 4px 15px;
cursor: pointer;
transition: all 0.4s;
}
.selected.open {
border-bottom: none;
border-radius: 4.5px 4.5px 0 0;
transition: all 0.4s;
border-color: #253e5c
}
.selected::after {
content: "";
background: url(media/dropdown-black.png);
background-size: contain;
background-repeat: no-repeat;
position: absolute;
height: 100%;
width: 12px;
right: 13px;
top: 10px;
transition: all 0.4s;
}
.selected.open::after {
transform: rotateX(180deg);
top: -11px;
}
.select-box .options-container.open {
border-color: #253e5c;
display: block;
z-index: 99;
}
.select-box .options-container.open .options:nth-child(n+2) {
border-top: 1px solid #253e5c;
}
.select-box .options-container .options {
padding-top: 5px;
padding-bottom: 5px;
padding-left: 15px;
}
.select-box .options:hover {
background: #76bc6b;
cursor: pointer;
}
.select-box label {
cursor: pointer;
}
.select-box .options .radio {
display: none;
}
#tier {
display: none;
}
<div class="filter-filterbox-row" id="level">
<div class="question"> Level </div>
<div class="select-box">
<div class="selected">
Select level
</div>
<div class="options-container">
<div class="options">
<input type="radio" class="radio" id="1" name="level">
<label for="1">one</label>
</div>
<div class="options">
<input type="radio" class="radio" id="2" name="level">
<label for="2">two</label>
</div>
</div>
</div>
</div>
<div class="filter-filterbox-row" id="tier">
<div class="question"> Select tier </div>
<div class="select-box">
<div class="selected">
Select tier
</div>
<div class="options-container">
<div class="options">
<input type="radio" class="radio" id="bronze" name="tier">
<label for="bronze">Bronze</label>
</div>
<div class="options">
<input type="radio" class="radio" id="silver" name="tier">
<label for="silver">silver</label>
</div>
</div>
</div>
</div>
JavaScript is a text-based programming language used both on the client-side and server-side that allows you to make web pages interactive. Where HTML and CSS are languages that give structure and style to web pages, JavaScript gives web pages interactive elements that engage a user.
JavaScript simply adds dynamic content to websites to make them look good. HTML work on the look of the website without the interactive effects and all. HTML pages are static which means the content cannot be changed. It adds interactivity to web pages to make them look good.
Both of these are computer languages that help in programming, but there is a major difference between JavaScript and HTML. While JavaScript (abbreviated as JS) is a scripting language, HTML is a markup language. We use HTML to create web pages or web applications.
Arguably, JavaScript is one of the easiest programming languages to learn, so it serves as a great first language for anyone brand new to coding. Even the most complex lines of JavaScript code can be written one by one, in fragments. It can also be tested in the web browser at the same time.
Adding the position: relative;
to the class .filter-filterbox-row
would fix it immediately for Safari:
.filter-filterbox-row {
display: grid;
grid-template-columns: auto auto;
grid-template-areas: "question select-box";
padding: 5px 5px;
margin-top: -2px;
position: relative;
}
position: static;
is the default normal flow of the document if not explicitly stated. Since you've declared a z-index: 99
on the child div:
.select-box .options-container.open {
border-color: #253e5c;
display: block;
z-index: 99;
}
...stating the z-index assumes the div is in absolute position, thus we need to declare a position for the parent div which is the .filter-filterbox-row
. Furthermore, adding the position: absolute;
on the child div is required if you need to state the top
, bottom
, left
or right
properties.
Declaring an explicit position for the parent div is one way to prevent different browser behavior glitches such as this. The same practice we always do when we declare a z-index on the child div and state the position as relative, the parent div should be declared as well with the position if relative or absolute for the child div to behave accordingly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With