Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I move an absolute positioned element if out of viewport?

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

JSFIDDLE

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>
like image 593
Alvaro Menéndez Avatar asked Oct 23 '25 06:10

Alvaro Menéndez


1 Answers

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>
like image 131
Awsme Sandy Avatar answered Oct 24 '25 20:10

Awsme Sandy