Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to make cursor tooltip not go offscreen

I’m working on a popup box that shows some text some position away from an element when the cursor hovers over it. You can see a simplified demo here: https://jsfiddle.net/xsvm2Lur/61/

Right now the popup box will squash up when it is near the bounding box. I want the popup to appear to the bottom-left (if the popup will overflow to the right) or top-left (if the popup will overflow to the bottom and to the right) of the hovered element’s position if the popup will overflow.

The position and text that will be shown are dynamically generated (e.g. I don’t know before rendering).

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Right now I have a working version using Javascript. The way I go about it is:

  • Get the text that will be displayed. Count the number of characters that is going to be displayed x 0.25em for each character to get the width of the text.
  • Calculate the width of the displayed string + padding (left and right). Let’s call it textLength. This will be set as the popup’s width so all the text goes into 1 line.
  • If textLength + x position of the cursor > box width, "invert" the popup box on the x-axis by deducting the popup’s "left" value by textLength and some distance away from the element.
  • Repeat the same check for the y position, i.e. if cursor position + line height (1em) + bottom padding > box height, invert y.

The solution works, but I’m wondering if there’s a better way to do this without character counting, or if there is another way to do it elegantly, maybe CSS only without Javascript?

Demo image

>Solution :

Sadly, I don’t believe there is a way to do it with CSS only. However, by working on your fiddle, I’ve managed to add the functionality you wanted.

The way I went about it was just to include a reference to the container and check whether the popup position and size where inside the container’ BoundingClientRect.

This is the updated code for the popupShow function:

const showPopup = (top, left, text, container) => {
    popup.textContent = text;
  
  const containerBCR = container.getBoundingClientRect();
  const popupBCR = popup.getBoundingClientRect();
  const popupWidth = popupBCR.width,
        popupHeight = popupBCR.height;
  
  let popupTop = top + 20,
        popupLeft = left + 20,
      newPopupWidth;
  
  console.log("height: ", popupHeight);
  console.log("top: ", top);
  console.log("bottomPopup: ", top + 20 + popupHeight);
  console.log("bottomBoundary", containerBCR.bottom);
  
  if (left + 20 + popupWidth > containerBCR.right) {
    popupLeft = left - popupWidth;
    
    if (popupLeft < containerBCR.left) {
        popupLeft = containerBCR.left;
      newPopupWidth = left - containerBCR.left;
    }
  }
  
  if (top + 20 + popupHeight > containerBCR.bottom) {
    popupTop = top - popupHeight;
    
    if (popupTop < containerBCR.top) {
        popupTop = containerBCR.top;
    }
  }
  
  popup.style.top = popupTop + "px";
  popup.style.left = popupLeft + "px";
  popup.style.width = newPopupWidth;
  popup.style.visibility = 'visible';
}

As you can see, I’ve also edited the popup to use "visibility: hidden" instead of "display: none". This is because if the display is set to "none", we won’t be able to get his size (there might be workarounds for this, though).

Try checking out the updated fiddle and tell me what you think.

I’ve pushed one circle a little bit further down because the code doesn’t currently check for the padding of the popup, so it was overflowing a little (few pixels).

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading