Reputation: 9012
I have many boxes with differents widths. All of them are displayed inline-block
so they will be distributed differently as window width changes.
Every box has a big tooltip that will show on hover. These tooltips have a fixed width and height, same for all of the boxes.
These tooltips are position:absolute
over the boxes and centered with:
left: 50%;
margin-left: -halfwidth;
My problem is that if the box is close to window left or right they will be partially hidden (I have no problem with top and bottom, they will never reach those edges)
Is there any easy way with javascript (better if jquery) to detect when the element is out of the viewport and then change the left
property accordingly to prevent it?
any help, hint or comment will be greatly apreciated. Thank You
html, body {margin:0;padding:0;height:100%;}
ul {
width:100%;
text-align:center;
position:relative;
top:50%;
transform:translateY(-50%);
padding:0;
}
li {
display: inline-block;
background-color: red;
width: 100px;
height: 25px;
margin-right: 10px;
position: relative;
}
.hover-element {
position: absolute;
background-color: yellow;
z-index: 9999;
width: 350px;
height: 175px;
left: 50%;
margin-left: -175px;
bottom:25px;
display: none;
border:1px solid #000;
}
li:hover .hover-element {
display: block;
}
.hover-element:hover {
visibility: hidden;
}
<ul>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
</ul>
Upvotes: 4
Views: 3348
Reputation: 696
I'm going to mention the steps here. If you'd need the code, just ask for it. I am currently on my mobile device, so typing the code would get hard!
In the same hover event, do these:
After changing the display, check if the tooltip element is in viewport. You can refer to the link Victor Medeiros provided.
If is not completely in viewport, change the margin-left property to I just realised, if it crosses the viewport, just set the margin-left or margin-right (as applicable, find it by getBoundingClientRect) to 0.-175px - (the number of pixels it crossed the boundary by)
.
Yep, that's it! I hope that should work, I haven't tried it out. What's the result?
Upvotes: 1
Reputation: 2426
Have a look:
var windowWidth = document.body.scrollWidth || window.innerWidth;
$('li').on('mouseenter', function(e){
var $hover = $(this).find('.hover-element');
var coords = $hover[0] && $hover[0].getBoundingClientRect();
var rightDistance = 0;
if (coords.left <= 0) {
$hover.css({
'left': ($hover.css('left').split('px')[0] - coords.left) + 'px'
})
}
rightDistance = windowWidth - coords.left - $hover.width() - 2 * $hover.css('borderWidth').split('px')[0];
if (rightDistance < 0) {
$hover.css({
'left': ($hover.css('left').split('px')[0] - (-rightDistance)) + 'px'
})
}
$('p').html($hover.css('left') + '/' + coords.left)
})
html, body {margin:0;padding:0;height:100%;overflow-x: hidden;}
ul {
width:100%;
text-align:center;
position:relative;
top:50%;
transform:translateY(-50%);
padding:0;
}
li {
display: inline-block;
background-color: red;
width: 100px;
height: 25px;
margin-right: 10px;
position: relative;
}
.hover-element {
position: absolute;
background-color: yellow;
z-index: 9999;
width: 350px;
height: 175px;
left: 50%;
margin-left: -175px;
bottom:25px;
display: none;
border:1px solid #000;
}
li:hover .hover-element {
display: block;
}
.hover-element:hover {
visibility: hidden;
}
<script
src="https://code.jquery.com/jquery-2.2.4.min.js"
integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
crossorigin="anonymous"></script>
<ul>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
</ul>
Upvotes: 2
Reputation: 1408
Thats all you need, i detected the offset left position of the div, and added the class to li
and a small tweaks in css.
$("li").mouseenter(function(){
var f = $(this).find('.hover-element');
var rightEdge = f.width() + f.offset().left;
var leftEdge = f.offset().left;
var screenWidth = $(window).width();
if(leftEdge < 0){
$(this).addClass("left");
$(this).removeClass("right");
}
else if(rightEdge > screenWidth){
$(this).addClass("right");
$(this).removeClass("left");
}
else{
$(this).removeClass("right lefft");
}
});
$("li").mouseleave(function(){
$(this).removeClass("right lefft");
})
html, body {margin:0;padding:0;height:100%;}
ul {
width:100%;
text-align:center;
position:relative;
top:50%;
transform:translateY(-50%);
padding:0;
}
li {
display: inline-block;
background-color: red;
width: 100px;
height: 25px;
margin-right: 10px;
position: relative;
}
.hover-element {
position: absolute;
background-color: yellow;
z-index: 9999;
width: 350px;
height: 175px;
left: 50%;
margin-left: -175px;
bottom:25px;
display: none;
border:1px solid #000;
}
li.left .hover-element{
left: 0;
margin-left: 0;
}
li.right .hover-element{
margin-left: 0;
left: auto;
right: 0;
}
li:hover .hover-element {
display: block;
}
.hover-element:hover {
visibility: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
<li>
<div class="hover-element"></div>
</li>
</ul>
Upvotes: 3
Reputation: 116
The following links are a starting point for your question (if not the actual answer).
Is there any easy way with javascript (better if jquery) to detect when the element is out of the viewport and then change the left property accordingly to prevent it?
How to tell if a DOM element is visible in the current viewport?
Absolute position of an element on the screen using jQuery
Upvotes: 1
Reputation: 178
Change
li {
display: inline-block;
background-color: red;
width: 100px;
height: 25px;
margin-right: 10px;
position: relative;
}
Whit
li {
display: inline-block;
background-color: red;
width: 100px;
height: 25px;
margin-right: 10px;
position: static;
}
Upvotes: -5