I'm trying to make a login form and one of the inputs I'm taking is the users location, I wanted to use flags symbols on the labels so I ended up making a custom dropdown menu rather than using the inbuilt HTML option tag. I got the dropdown to be able to open and close it as well as select options, however, the wrapping div of all the options overflows over the edge of my overlying form containing div. I got the elements to display over the edge with a little bit of Javascript logic setting the overflow-y property of the form wrapper to visible and the overflow-x property to clip. This works perfectly for displaying the dropdown menu, however, I can't interact with any of the objects that are over the edge of the form containing div, is there a way to allow mouse/hover/click events to still be able to be performed on the elements even though they are flooding over the edge of the underlying parent container?
In the most simplistic form, the code is a little something like this:
<!--HTML-->
`<div class="registerStep4" id="registerStep4">
<!--...-->
<div class="location">
<div class="dropdown">
<input type="text" class="dropDownTextBox" placeholder="Select Country" readonly>
<div class="option">
<div onclick="show('United States')"><span class="fi fi-us"></span> United States</div>
<div onclick="show('United Kingdom')"><span class="fi fi-gb"></span> United Kingdom</div>
<div onclick="show('Afghanistan')"><span class="fi fi-af"></span> Afghanistan</option></div>
<div onclick="show('Albania')"><span class="fi fi-al"></span> Albania</div>
<div onclick="show('Algeria')"><span class="fi fi-dz"></span> Algeria</div>
<div onclick="show('Andorra')"><span class="fi fi-ad"></span> Andorra</option></div>
<div onclick="show('Angola')"><span class="fi fi-an"></span> Angola</div>
<div onclick="show('Antigua and Barbuda')"><span class="fi fi-ag"></span> Antigua and Barbuda</div>
<div onclick="show('Argentina')"><span class="fi fi-ar"></span> Argentina</option></div>
</div>
</div>
</div>`
/* CSS */
#registerStep4 {
width: 360px;
position: absolute;
top: 0;
transform: translateX(1000px);
user-select: none;
height: 330px;
}
.dropdown {
width: 100%;
}
.dropdown input {
width: 85%;
padding: 10px 30px;
cursor: pointer;
display: block;
margin: auto;
background: rgb(25, 34, 58);
border: 0;
outline: none;
border-radius: 30px;
color: white;
transition: 0.5s;
font-size: 13px;
box-shadow: none;
}
.dropdown input::placeholder {
text-align: center;
color: white;
}
.dropdown .option {
position: absolute;
width: 200px;
text-align: left;
margin-left: 50%;
transform: translateX(-50%);
background-color: rgb(69, 81, 114);
height: 0px;
transition: 0.25s;
z-index: 1000;
overflow-y: scroll;
overflow-x: hidden;
}
.dropdown .option::-webkit-scrollbar {
width: 4px;
}
.dropdown .option::-webkit-scrollbar-thumb {
background: white;
border-radius: 4px;
}
.dropdown.active .option {
height: 180px;
}
.dropdown .option div {
padding-top: 10px;
padding-bottom: 10px;
cursor: pointer;
color: white;
font-size: 14px;
/*pointer-events: visibleFill;????????*/
}
.dropdown .option div:hover {
background: rgb(97, 110, 145);
}
.dropdown .option div span {
position: relative;
margin-left: 5px;
}
.dropdown::before {
content: '';
position: relative;
display: inline-block;
right: -120px;
top: 30px;
z-index: 1000;
width: 8px;
height: 8px;
border-top: 2px solid white;
border-right: 2px solid white;
transform: rotate(-45deg);
transition: 0.25s;
pointer-events: none;
}
.dropdown.active::before {
top: 25px;
transform:rotate(135deg);
}
//Javascript
const dropdownSelect = document.querySelector('.dropdown');
const formWrapper = document.getElementById("formWrapper");
dropdownSelect.onclick = function() {
dropdownSelect.classList.toggle('active');
if(dropdownSelect.classList.contains('active')) {
formWrapper.style.overflowY = "visible";
formWrapper.style.overflowX = "clip";
} else {
formWrapper.style.overflowY = "hidden";
formWrapper.style.overflowX = "hidden";
}
}
In the current form, this works to display the dropdown, on click it drops down all the options, and allows click on all the option divs that are within the bounds of the registerStep4 div
I had to make some changes to your code to replicate the issue. I removed some stray <option>
and <div>
tags in your HTML, changed the #formWrapper
in your JS to #registerStep4
(as I presume you intended), and adjusted the height of the #registerStep4
element to 100px to actually get the dropdown to overflow. This way, I can't interact with the dropdown beyond the edge of #registerStep4
as you described.
I don't believe this behavior is by spec. Most likely, this is an issue with Chrome, as I could not replicate the behavior in Firefox. The issue seems to be caused by the transform: translateX(1000px)
property on #registerStep4
. If you remove the property, the issue resolves itself.
I am not familiar with your case exactly, but I would suggest two options:
#registerStep4
to be hidden in x? If you remove all overflow properties on #registerStep4
, the dropdown should work as expected.#registerStep4
is already absolutely positioned, you can use the left: 1000px;
property to achieve the same result.Below is your snipped using left: 1000px;
instead of a transform. The result is the same, but the issue is resolved (at least by me). I can't offer more help as I, but I hope this was useful.
const dropdownSelect = document.querySelector('.dropdown');
const formWrapper = document.getElementById("registerStep4");
dropdownSelect.onclick = function() {
dropdownSelect.classList.toggle('active');
if(dropdownSelect.classList.contains('active')) {
formWrapper.style.overflowY = "visible";
formWrapper.style.overflowX = "clip";
} else {
formWrapper.style.overflowY = "hidden";
formWrapper.style.overflowX = "hidden";
}
}
#registerStep4 {
width: 360px;
position: absolute;
top: 0;
left: 1000px;
user-select: none;
height: 100px;
}
.dropdown {
width: 100%;
}
.dropdown input {
width: 85%;
padding: 10px 30px;
cursor: pointer;
display: block;
margin: auto;
background: rgb(25, 34, 58);
border: 0;
outline: none;
border-radius: 30px;
color: white;
transition: 0.5s;
font-size: 13px;
box-shadow: none;
}
.dropdown input::placeholder {
text-align: center;
color: white;
}
.dropdown .option {
position: absolute;
width: 200px;
text-align: left;
margin-left: 50%;
transform: translateX(-50%);
background-color: rgb(69, 81, 114);
height: 0px;
transition: 0.25s;
z-index: 1000;
overflow-y: scroll;
overflow-x: hidden;
}
.dropdown .option::-webkit-scrollbar {
width: 4px;
}
.dropdown .option::-webkit-scrollbar-thumb {
background: white;
border-radius: 4px;
}
.dropdown.active .option {
height: 180px;
}
.dropdown .option div {
padding-top: 10px;
padding-bottom: 10px;
cursor: pointer;
color: white;
font-size: 14px;
/*pointer-events: visibleFill;????????*/
}
.dropdown .option div:hover {
background: rgb(97, 110, 145);
}
.dropdown .option div span {
position: relative;
margin-left: 5px;
}
.dropdown::before {
content: '';
position: relative;
display: inline-block;
right: -120px;
top: 30px;
z-index: 1000;
width: 8px;
height: 8px;
border-top: 2px solid white;
border-right: 2px solid white;
transform: rotate(-45deg);
transition: 0.25s;
pointer-events: none;
}
.dropdown.active::before {
top: 25px;
transform: rotate(135deg);
}
<div class="registerStep4" id="registerStep4">
<div class="location">
<div class="dropdown">
<input type="text" class="dropDownTextBox" placeholder="Select Country" readonly>
<div class="option">
<div onclick="show('United States')"><span class="fi fi-us"></span> United States</div>
<div onclick="show('United Kingdom')"><span class="fi fi-gb"></span> United Kingdom</div>
<div onclick="show('Afghanistan')"><span class="fi fi-af"></span> Afghanistan</div>
<div onclick="show('Albania')"><span class="fi fi-al"></span> Albania</div>
<div onclick="show('Algeria')"><span class="fi fi-dz"></span> Algeria</div>
<div onclick="show('Andorra')"><span class="fi fi-ad"></span> Andorra</div>
<div onclick="show('Angola')"><span class="fi fi-an"></span> Angola</div>
<div onclick="show('Antigua and Barbuda')"><span class="fi fi-ag"></span> Antigua and Barbuda</div>
<div onclick="show('Argentina')"><span class="fi fi-ar"></span> Argentina</div>
</div>
</div>
</div>
</div>