let modal = document.querySelector('.modal');
let items = document.querySelectorAll('.item');
items.forEach(fe);
function fe(item, index){
item.addEventListener("click", function(){
item.querySelector('.modal').classList.toggle('show');
});
}
.horizontal-scrollable{
display: flex;
flex-direction: column;
padding: 10px;
background-color: #d2d2d2;
overflow-x:auto;
max-width: 450px;
}
.item {
background-color: #a29f9b;
margin: 5px;
padding: 0 5px;
cursor:pointer;
position:relative;
}
.item2{
min-width:500px
}
.item3{
min-width:700px
}
.modal{
display:none;
position: absolute;
top: 100%;
right: 0;
background: #4977d0;
z-index: 100;
}
.modal.show{
display:block;
}
<div class="horizontal-scrollable">
<div class="item item1">
<h1>Item 1</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item2">
<h1>Item 2</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item3">
<h1>Item 3</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item4">
<h1>Item 4</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
</div>
let modal = document.querySelector('.modal');
let items = document.querySelectorAll('.item');
items.forEach(fe);
function fe(item, index){
item.addEventListener("click", function(){
item.querySelector('.modal').classList.toggle('show');
});
}
.horizontal-scrollable{
display: flex;
flex-direction: column;
padding: 10px;
background-color: #d2d2d2;
overflow-x:auto;
max-width: 450px;
}
.item {
background-color: #a29f9b;
margin: 5px;
padding: 0 5px;
cursor:pointer;
position:relative;
}
.item2{
min-width:500px
}
.item3{
min-width:700px
}
.modal{
display:none;
position: absolute;
top: 100%;
right: 0;
background: #4977d0;
z-index: 100;
}
.modal.show{
display:block;
}
<div class="horizontal-scrollable">
<div class="item item1">
<h1>Item 1</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item2">
<h1>Item 2</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item3">
<h1>Item 3</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item4">
<h1>Item 4</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
</div>
In the above code snippet, If you click on any item, then it will show a modal
on the right side. As you can see, item 3
is larger in width. So if you click on item 3
then you have to scroll-right
to view the modal.
So I want to show modal on mouse click position. How can I do this?
Share Improve this question edited Dec 13, 2021 at 11:31 Amila Senadheera 13.3k16 gold badges29 silver badges46 bronze badges asked Dec 13, 2021 at 11:19 Abhishek kamalAbhishek kamal 3295 silver badges15 bronze badges2 Answers
Reset to default 6There are at least two options
- The first one will spawn the modal directly at the mouse position using JS
- And the second one will spawn the modal on the left side. This can be achieved using CSS
First option
So basically you can get the mouse position and set the modal position to it. In detail remove the top/left/right/bottom properties from the modal class in CSS (they aren't needed) and add some lines of JS. Please write me in the ments if you want to align the modal a bit around the mouse cursor... It's just about a few numbers.
let modal = document.querySelector('.modal');
let items = document.querySelectorAll('.item');
items.forEach(fe);
var mousePos = {};
function fe(item, index){
item.addEventListener("click", function(e){
var rect = e.target.getBoundingClientRect(); // get some poition, scale,... properties of the item
mousePos.x = e.clientX - rect.left; // get the mouse position relative to the element
mousePos.y = e.clientY - rect.top;
item.querySelector('.modal').classList.toggle('show');
item.querySelector('.modal').style.left = mousePos.x + "px"; // set the modal position to the last stored position
item.querySelector('.modal').style.top = mousePos.y + "px";
});
}
.horizontal-scrollable{
display: flex;
flex-direction: column;
padding: 10px;
background-color: #d2d2d2;
overflow-x:auto;
max-width: 450px;
}
.item {
background-color: #a29f9b;
margin: 5px;
padding: 0 5px;
cursor:pointer;
position: relative;
}
.item2{
min-width:500px
}
.item3{
min-width:700px
}
.modal{
display:none;
position: absolute;
background: #4977d0;
z-index: 100;
}
.modal.show{
display:block;
}
<div class="horizontal-scrollable">
<div class="item item1">
<h1>Item 1</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item2">
<h1>Item 2</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item3">
<h1>Item 3</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item4">
<h1>Item 4</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
</div>
Second option
The second option uses basic CSS to align the modals on the left side - it is much easier to implement and you just have to remove thee left/right/top/bottom property from the modal class and add left:0
:
let modal = document.querySelector('.modal');
let items = document.querySelectorAll('.item');
items.forEach(fe);
var mousePos = {};
function fe(item, index){
item.addEventListener("click", function(e){
item.querySelector('.modal').classList.toggle('show');
});
}
.horizontal-scrollable{
display: flex;
flex-direction: column;
padding: 10px;
background-color: #d2d2d2;
overflow-x:auto;
max-width: 450px;
}
.item {
background-color: #a29f9b;
margin: 5px;
padding: 0 5px;
cursor:pointer;
position: relative;
}
.item2{
min-width:500px
}
.item3{
min-width:700px
}
.modal{
display:none;
position: absolute;
background: #4977d0;
left: 0;
z-index: 100;
}
.modal.show{
display:block;
}
<div class="horizontal-scrollable">
<div class="item item1">
<h1>Item 1</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item2">
<h1>Item 2</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item3">
<h1>Item 3</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item4">
<h1>Item 4</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
</div>
Hope I could help :D
You can change the style dynamically and get the position X of your controller, then add the style using JS code.
Also, remove the right 0 from your modal class
let modal = document.querySelector('.modal');
let items = document.querySelectorAll('.item');
items.forEach(fe);
function fe(item, index){
item.addEventListener("click", function(e){
item.querySelector('.modal').style.left = e.clientX + "px";
item.querySelector('.modal').classList.toggle('show');
});
}
.horizontal-scrollable{
display: flex;
flex-direction: column;
padding: 10px;
background-color: #d2d2d2;
overflow-x:auto;
max-width: 450px;
}
.item {
background-color: #a29f9b;
margin: 5px;
padding: 0 5px;
cursor:pointer;
position:relative;
}
.item2{
min-width:500px
}
.item3{
min-width:700px
}
.modal{
display:none;
position: absolute;
top: 100%;
background: #4977d0;
z-index: 100;
}
.modal.show{
display:block;
}
<div class="horizontal-scrollable">
<div class="item item1">
<h1>Item 1</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item2">
<h1>Item 2</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item3">
<h1>Item 3</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item4">
<h1>Item 4</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
</div>