Hi,

I am not sure if this is possible in css or it's a javaScript thing.

I have a page where it has many images, If you hover over the image the details of that image appear to the top left. However when the images are over next to the left hand side of the page, they disappear off screen. Which is annoying, as you can't read it.

So i want to get it to either go right or left, up or down, depending on where the edge of the browser window is.
If someone could point me in the right direction or if they have a script they use to do this, I'd much appreciate it.

Cheers,

Qwaz

Dani AI

Generated

A common cause of hover popups being clipped is that CSS cannot "flip" the popup based on the viewport. Positioning the popup relative to the viewport (position:fixed) keeps it visible but loses proximity to the image (as noted). A practical compromise is to measure the trigger and the popup at hover, then place the popup so it fits — prefer the right/below position and flip to left/above only when needed. The snippet below is a small, dependency-free example that uses event delegation and fixed positioning so the popup stays on-screen and remains visible when the pointer moves into it.

// minimal "flip-to-fit" hover popups for a .I1 list (vanilla JS)
(function(){
  const root = document.querySelector('.I1');
  if (!root) return;

  function show(li) {
    const popup = li.querySelector('ul');
    if (!popup) return;
    popup.style.display = 'block';           // make measurable
    popup.style.position = 'fixed';
    popup.style.left = '0';
    popup.style.top = '0';
    const pRect = popup.getBoundingClientRect();
    const tRect = li.getBoundingClientRect();

    // prefer right, flip to left if needed
    let left = tRect.right;
    if (left + pRect.width > window.innerWidth) left = tRect.left - pRect.width;
    left = Math.max(0, left);

    // clamp vertically
    let top = tRect.top;
    if (top + pRect.height > window.innerHeight) top = window.innerHeight - pRect.height;
    top = Math.max(0, top);

    popup.style.left = left + 'px';
    popup.style.top = top + 'px';
    popup.classList.add('visible');
  }

  function hide(li) {
    const popup = li && li.querySelector('ul');
    if (!popup) return;
    popup.classList.remove('visible');
    popup.style.display = '';
    popup.style.position = '';
    popup.style.left = '';
    popup.style.top = '';
  }

  root.addEventListener('pointerover', e => {
    const li = e.target.closest('li');
    if (!li || !root.contains(li)) return;
    show(li);
  });

  root.addEventListener('pointerout', e => {
    const li = e.target.closest('li');
    if (!li || !root.contains(li)) return;
    const to = e.relatedTarget;
    const popup = li.querySelector('ul');
    if (popup && (popup === to || popup.contains(to) || li.contains(to))) return;
    hide(li);
  });
})();

Notes and pitfalls: pointer events handle mouse and touch; add keyboard support (focus/blur + ARIA) for accessibility; ensure popups are not inside elements with overflow:hidden (position:fixed avoids that); set an appropriate z-index; debounce repositioning on resize. This implements the flipping idea from using precise bounding-box checks while keeping the popup linked to the image, and it preserves the simple fixed-placement fallback mentioned by . For production-grade behavior (offsets, flip behavior, accessibility) consider a battle-tested popper library.

Recommended Answers

All 6 Replies

QWaz,

You need to post the code that causes detailes to appear.

Unable to advise without it.

Airshow

Hi,
I don't have any code that doesn't work,
But to show you what I mean.

CSS:
.container [}

Well this is what I am using:
However I don't understand how I get it to float to a different direction.
I am also not using any javaScript at the moment.

CSS:
.I1 ul {
	list-style-type: none;
	}
.I1 ul ul {
	display: none;
	}
.I1 ul li a {
	padding: 3px;
	margin-left: auto;
        margin-right: auto;
	display: block;
	border: thin solid #FFFFFF;
	background: none;
	}
.I1 ul li img {
	margin-left: auto;
        margin-right: auto;
	display: block;
	border: none;
	}
.I1 ul li a:hover {
	border: thin solid #101010;
	-moz-border-radius: 5px; 
	-webkit-border-radius: 5px;
	padding: 3px;
	}
.I1 li:hover ul {
	-moz-border-radius: 5%; 
	-webkit-border-radius: 5%;
	border: none;
	background: #101010;
	width: 250px;
	min-width: 120px;
	height: 140px;
	text-align: center;
	display: inline;
	position: absolute;
	padding: 5px;
	margin: -228px auto 20px auto;
	opacity: 0.9;
	filter: alpha (opacity=90);
	}

HTML:
<div class="I1">
   <ul>
      <li><a href="#"><img src="images/i1.jpg" width="100" height="60" /></a>
          <ul>
               <li><div class="I2">$info[na]</div></li>
               <li><div class="I3">$info[co]</div></li>
               <li><div class="I4">RRP: $$RRP</div></li>
               <li><div class="I5">$greenText</div></li>
           </ul>
       </li>
   </ul>    
</div>

QWaz,

I can't think of a 100% css solution but you could try this ....

Leave all your CSS as it is.

Amend the HTML to give classes and ids to some elements :

<div class="I1">
    <ul>
        <li class="listItem" id="I1_0"><a href="#"><img src="images/i1.jpg" width="100" height="60" /></a>
            <ul id="I1_0_popup">
                <li><div class="I2">$info[na]</div></li>
                <li><div class="I3">$info[co]</div></li>
                <li><div class="I4">RRP: $$RRP</div></li>
                <li><div class="I5">$greenText</div></li>
            </ul>
        </li>
        <li class="listItem" id="I1_1"><a href="#"><img src="images/i1.jpg" width="100" height="60" /></a>
            <ul id="I1_1_popup">
                <li><div class="I2">$info[na]</div></li>
                <li><div class="I3">$info[co]</div></li>
                <li><div class="I4">RRP: $$RRP</div></li>
                <li><div class="I5">$greenText</div></li>
            </ul>
        </li>
   </ul>    
</div>

Note how each popup's id matches that of its parent <li>, with "_popup" appended.

Now add some javascript to your page (in the document's head):

<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
$(document).ready(function() {
	$('.listItem').mouseover(function(evt) {
		var offset = $(this).offset();
		evt.stopPropagation();
		var w = $(window).width();
		var h = $(window).height();
		var popupID = $(this).attr('id') + '_popup';
		$("#"+popupID).css('marginLeft', (offset.left < (w/2)) ? '0px' : '-200px' );
		$("#"+popupID).css('marginTop', (offset.top < (h/2)) ? '10px' : '-228px' );
	});
});
</script>

To simplify the code and for greater cross-browser certainty, we use jQuery.

All we do is test which quarter of the screen the element is in, and adjusts margins accordingly.

You will probably need to play with the constants to get the exact effect you want.

When you're happy with it, you should really download jQuery (free) and serve it from your own server.

Airshow

Hi Qwas!

You can use position:fixed in a class that you apply to a div to decide where you want things to show. All info will show on the same spot and not disapear out of the screen :) Simple and pure css.

f.ex

.imgbig{
 position:fixed;
 bottom:125px;
 top: 175px;
 left:1000px;
}

Hi Qwas!

You can use position:fixed in a class that you apply to a div to decide where you want things to show. All info will show on the same spot and not disapear out of the screen :) Simple and pure css.

f.ex

.imgbig{
 position:fixed;
 bottom:125px;
 top: 175px;
 left:1000px;
}

Thanks for that idea. I hadn't thought of that for what I was doing.
I did something a little different, which solved all my issues.

Thanks for you help.

Cheers,

Qwaz

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.