Mastering Tooltip Placement Using CSS or JavaScript

I have been working on creating a CSS-only tooltip for a web application and so far I have managed to create some useful tooltips with different classes:

  • tooltip-up
  • tooltip-down
  • tooltip-left
  • tooltip-right

The distinguishing factors between them are the arrow direction and animation. For instance, the 'tooltip-right' class has the arrow pointing towards the left side and animates from left to right.

https://i.sstatic.net/qRapm.png

An issue arises when the tooltip contains a lot of text; the positioning differs for tooltip-left, tooltip-right, and tooltip-up due to the varying text length. Tooltip-down does not face any issues as everything naturally flows downwards by default.

https://i.sstatic.net/ZF84c.png

Hence, my question is whether it is feasible to precisely position the tooltip using only CSS. Or would JavaScript be necessary? If so, what approach would you recommend? Perhaps checking the text length in the tooltip and adding inline CSS for margins? As an example, I tried emulating Foundation Tooltips. We are utilizing Foundation but encountering compatibility issues with Angular.

Here's a snippet of code that I have implemented:

  .tooltip-up,
  .tooltip-down,
  .tooltip-left,
  .tooltip-right {
    font-size: 12px;
    position: absolute;
    text-align: center!important;
    visibility: hidden;
    background-color: rgba($gray, 0.99);
    color: #fff;
    text-align: left;
    border-radius: 3px;
    width: 250px;
    height: auto;
    padding: 7px 10px;
    z-index: 1;
    opacity: 0;
    box-shadow: 0 2px 5px 0 rgba($solid-black, 0.16), 0 2px 10px 0 rgba($solid-black, 0.12);
    @include transition (.2s ease-in);
  }

  .tooltip-right {
    top: -35%;
    left: 135%;
    transform: translateX(-15%);
    margin-top: -10px;

    &:after {
      border-right: 7px solid rgba($gray, 0.99);
      border-bottom: 7px solid transparent;
      border-top: 7px solid transparent;
      top: 50%;
      content: " ";
      height: 0;
      left: -7px;
      position: absolute;
      width: 0;
      transform: translateY(-50%);
    }

  }

Please note that there are four tooltip classes, so any solution should consider all positions (left, right, top). Thank you in advance for any advice or assistance provided.

Answer №1

To center the tooltip arrow, you can utilize a simple trick: apply translateY(-50%) along with position: absolute and top: 50%.

By setting the value to 50%, the arrow will always be positioned in the center relative to the tooltip itself. However, there are a couple of things to watch out for:

  • Make sure not to translate the tooltip completely out of view.
  • Sometimes, text may appear blurry if the height is an odd pixel size (e.g., using 27px could move the tooltip 13.5px down).

p { display: inline-block; position: relative; border: 1px solid blue; }

.tooltip-center {
  box-sizing: border-box;
  font-size: 14px;
  position: absolute;
  text-align: center;
  background-color: #333;
  color: #fff;
  text-align: left;
  border-radius: 5px;
  width: 300px;
  padding: 10px 15px;
  z-index: 2;
  opacity: .9;

  top: 50%;
  left: 0;
  /* width + arrow width = 300 + 10 = 310 */
  transform: translate3d(310px, -50%, 0);
}

.tooltip-center::after {
  content: "";

  border-right: 10px solid #333;
  border-bottom: 10px solid transparent;
  border-top: 10px solid transparent;

  position: absolute;
  height: 0;
  width: 0;
  right: -10px;
  top: 50%;

  transform: translateY(-50%);
}
<h3>Applying translateY for accurate positioning</h3>
<p>
  <span>
    Lorem ipsum dolor
  </span>
  <span class="tooltip-center">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </span>
</p>

Answer №2

Attempt:

.info-box,
.info-bubble,
.info-popover,
.info-tooltip {
    font-size: 12px; /* Consider using the em unit for better scalability */
    position: absolute;
    text-align: center!important; /* Why the use of !important here? */
    visibility: hidden; /* Perhaps remove this line since opacity is set to 0 */
    background-color: rgba($grey, 0.99);
    color: #fff;
    text-align: left; /* Can be removed */
    border-radius: 3px;
    width: 250px; /* Evaluate using the em unit instead */
    height: auto; /* Default value can apply, so this line may not be necessary */
    padding: 7px 10px; /* The em unit might be a better choice here */
    z-index: 1; /* Set it higher than other elements in your code */
    opacity: 0;
    box-shadow: 0 2px 5px 0 rgba($solid-black, 0.16), 0 2px 10px 0 rgba($solid-black, 0.12);
    @include transition (.2s ease-in);
}

.info-popover {
    top: -35%;
    left: 135%;
    transform: translateX(-15%);
    margin-top: -10px;

&:after {
    border-right: 7px solid rgba($grey, 0.99);
    border-bottom: 7px solid transparent;
    border-top: 7px solid transparent;
    top: 1em; /* Experiment with what works best, avoiding % as it may cause arrow misalignment with lengthy text */
    content: "";
    height: 0;
    left: -7px;
    position: absolute;
    width: 0;
    transform: translateY(-50%);
}

}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Enforce a limit of two decimal places on input fields using jQuery

Looking to limit an input field so that users can only enter numbers with a maximum of two decimals. Is it possible to achieve this using jQuery? Any way I could utilize the jQuery toFixed() function for this purpose? Thank you in advance! ...

Configuring IP Whitelisting for Firebase Cloud Functions with MongoDB Cluster

What is the process for including my Firebase Cloud Functions in the IP whitelist of my MongoDB cluster? Error Message: ...

Include brand logo to the Bootstrap navigation bar

Following the method provided in Bootstrap documentation, I included the following code: <div class="container"> <a class="navbar-brand" href="#"> <img src="/img/hangers.jpg" alt= ...

The console.log() function does not accurately display the true value

While looping through a list and using a @click function to update other elements, I have encountered an issue with the index values bound to selectedFixtures. Each time I click on an element, it initially prints out [], and then on subsequent clicks, it ...

Sticky header and a sidebar gallery with consistently sized thumbnails

Hello everyone, I'm stepping into the world of HTML and CSS with my first question. As a beginner, I find myself facing a challenge that seems to be beyond my current skill level. Here's the scenario: I want to create a webpage with a fixed left ...

What is the best way to hide or eliminate spinners/arrows in react-select?

I am currently utilizing react-select for my project, but I'm encountering an issue with removing the spinners/arrows from the dropdown menu. So far, I have successfully removed the default separator "|" and Dropdown Indicator using the following cod ...

The event.currentTarget's attempt to toggle the class of the child element is not functioning as

I am having trouble toggling a class of a child element of the target element. I can't seem to get it to work and I'm unsure of what steps to take next. HTML: <div class="post-footer-icons-container-el" data-btntype="comment&qu ...

Ensuring complete height and width with no scrollbar in a Material UI React application

I'm attempting to create a page that fills the entire height of the screen without adding an undesirable scrollbar. When I say 100% height, I mean it should just fit the size of the screen. Here is a demonstration of the issue. The yellow highlighted ...

Exploring the interactive doughnut graph using SVG and Vue.js

Looking to create a unique dynamic donut chart using SVG and Vue. I want it to mirror the exact SVG format found on this webpage: (To see the animated chart, select a dish and click on ingredients) This might not have been the best approach, but it was ...

What sets apart elevation from z-index in material-ui?

As I delved into the material-ui documentation, I came across an interesting snippet: Various components in Material-UI make use of z-index, a crucial CSS property that aids in organizing content along a third axis. Material-UI employs a predefined z-in ...

How can the target pseudo-class be utilized to replace the 'active' state on navigation across several pages effectively?

Within a large application, I am managing a micro site and looking to implement tertiary navigation with an active state for pages. This involves inserting a single html blob into multiple pages. My goal is to use an active class to highlight the page in ...

What is the best way to create a nested match using regex?

const foundMatches = regExPattern.match(/\((.+?)\)/g); When tested against: [example[1]] The result is "[example[1]", indicating a potential nesting issue. How can this be resolved? ...

Amazon Banner Integration for Angular Version 4

Having some trouble getting an Amazon banner to display inside an angular material 2 card. The div appears empty and the banner is not rendering. Any idea what could be causing this issue? Below is the code snippet showcasing my attempts: <md-card clas ...

Using Jquery, take out each parent element and duplicate the child element

It seems to be partially working, but I encounter multiple instances of the cloned element. My goal is to rearrange elements in my JavaScript when the browser viewport reaches a mobile size. Original Order: <div class="sar--img-right-first"> ...

Javascript function that triggers at the end of a time update

How can I ensure that the alert event is triggered only once at the 15-second mark of a 45-second video? The code snippet below initiates the alert, but how can I modify it to make sure the alert only appears once. var video = document.getElementById("m ...

Take off the wrapping from the package

I need help with my code on how to remove the wrapper span tag without removing the text. <ul> <li> <a href="#"> </a> <ul> <li> <a href="#"> ...

Modifying an element in an array while preserving its original position

Currently, I am working on updating the state based on new information passed through response.payload. Here is my existing code snippet: if(response.events.includes('databases.*.collections.*.documents.*.update')) { setMemos(prevState => pre ...

Error: Unable to cast value "undefined" to an ObjectId for the "_id" field in the "User" model

Whenever a user logs into their account, I am trying to retrieve their data on the login screen. The login functionality itself works perfectly, but unfortunately, the user data is not displaying. I have tried troubleshooting this issue by making changes i ...

Include the url of the html file in your JavaScript code

I have a piece of code that I want to include in my JavaScript instead of HTML. The code is as follows: <script async src="https://www.googletagmanager.com/gtag/js?id=ID"></script> Since all my functions are written in JavaScript, I ...

What is the best way to integrate a vh property instead of px for a scrolling navigation using jQuery?

I want to achieve a navigation bar that fades in after scrolling 100% of the viewport height, but all examples I find use a pixel value instead of viewport height. Is there a way to convert window height into jQuery to make this work? Thank you in advance ...