Prevent tooltips from displaying outside of an HTML table by using the overflow hidden property for horizontal scrolling

TL;DR: Struggling to position and display tooltips in a table due to the constraints of overflow: hidden.

An example has been created to demonstrate the issue with tooltips not displaying correctly within a table. The problem arises because the table necessitates the use of overflow: scroll for proper horizontal scrolling functionality. Here is an illustration:

.gap {
  height: 50px
}

div.table { 
  max-width: 200px;

  overflow: scroll;
  border: 2px solid blue;
  display: inline-block;
  font-family: 'Roboto Mono';
  font-weight: 700;
}

.tr {
  display:flex;
}

.td, .th {
  border: 1px solid black;
  min-width: 60px;
  height: 50px;
}

.th {
  position: relative;
  font-size: 13px;
  padding: 2px;
  background-color: #888888;
  text-align: center;
  border-right: 1px solid #555555;
  display: inline-block;
  box-sizing: border-box;
}

.tip-wrapper {
  position: absolute;
}

.tip0 {
  visibility: hidden;
  position: absolute;
  top: -60%;
  z-index: 1;
  max-width: 325px;
  min-width: 160px;
  color: #333333;
  text-align: left;
  background: white;
  border: 1px solid black;
}

.tip1 {
  visibility: hidden;
  position: fixed;
  z-index: 1;
  max-width: 325px;
  min-width: 160px;
  color: #333333;
  text-align: left;
  background: white;
  border: 1px solid black;
}

.tooltip:hover .tip0, .tooltip:hover .tip1 {
  visibility: visible;
}
<div class='gap'>.</div>
<div class='table'>
  <div class='table-headers'>
    <div class='tr'>
      <div class='th tooltip'>
        Z
        <div class='tip0'>
          Heres the ToolTip For Column Z, getting cut off (bad)
        </div>
      </div>
      <div class='th'>Y</div>
      <div class='th tooltip'>
        X
        <div class='tip-wrapper'>
          <div class='tip1'>
            Heres the Tooltip For Column X, which doesn't stay at the top (bad)
          </div>
        </div>
      </div>
      <div class='th'>W</div>
      <div class='th'>V</div>
    </div>
  </div>
  <div class='table-body'>
    <div class='tr'>
    </div>
    <div class='tr'>
      <div class='td stick'>A</div>
      <div class='td'>B</div>
      <div class='td'>C</div>
      <div class='td'>D</div>
      <div class='td'>E</div>
    </div>
    <div class='tr'>
      <div class='td'>F</div>
      <div class='td'>G</div>
      <div class='td'>H</div>
      <div class='td'>I</div>
      <div class='td'>J</div>
    </div>
    <div class='tr'>
      <div class='td'>F</div>
      <div class='td'>G</div>
      <div class='td'>H</div>
      <div class='td'>I</div>
      <div class='td'>J</div>
    </div>
    <div class='tr'>
      <div class='td'>F</div>
      <div class='td'>G</div>
      <div class='td'>H</div>
      <div class='td'>I</div>
      <div class='td'>J</div>
    </div>
    <div class='tr'>
      <div class='td'>F</div>
      <div class='td'>G</div>
      <div class='td'>H</div>
      <div class='td'>I</div>
      <div class='td'>J</div>
    </div>
    <div class='tr'>
      <div class='td'>F</div>
      <div class='td'>G</div>
      <div class='td'>H</div>
      <div class='td'>I</div>
      <div class='td'>J</div>
    </div>
  </div>
</div>

Within the table above, the tooltips attached to the Z and X header cells are experiencing issues. Specifically:

Column Z: The tooltip for this column is being truncated due to the presence of overflow: hidden. It's imperative that the table remains horizontally scrollable, making it impossible to remove the overflow CSS property. However, ensuring the tooltip hovers above the table content without obstructing it is equally important.

Column X: An attempt was made using the approach outlined in another post link provided. Method 1 aimed to allow the tooltip to exist outside the bounds of overflow: hidden. Unfortunately, when vertically scrolling through the table, the tooltip also moves which is undesirable. Ideally, the tooltip should maintain a consistent vertical position just above the table.

The initial concept of "tooltips embedded within table headers" didn't yield the desired results. As a possible solution, the consideration of creating a separate tooltip div outside the table's HTML utilizing onMouseOver() and onMouseOut() event handlers to position the tooltip based on mouse location and populate it with text is being explored. This could potentially be the only viable approach moving forward.

Answer №1

Ensure that a .tip-wrapper element is present on tip0. By adding this and adjusting the top position of .tip-wrapper using calc() to -(th height) - (top threshold in rem), for example, calc(-50px - 1.5rem), the issue will be resolved and the tooltip will be correctly positioned above the table.

You can use dynamic units like vh, vmax, % for the th height. Additionally, @media queries might be required to further adjust the tooltip's position.

.td,
.th {
  border: 1px solid black;
  min-width: 10%;
  height: 5vh;
}
.tip-wrapper {
  position: absolute;
  top: calc(-5vh - 1.5rem);
}

.gap {
  height: 100px
}

div.table {
  max-width: 200px;
  overflow: scroll;
  border: 2px solid blue;
  display: inline-block;
  font-family: 'Roboto Mono';
  font-weight: 700;
}

.tr {
  display: flex;
}

.td,
.th {
  border: 1px solid black;
  min-width: 60px;
  height: 50px;
}

.th {
  position: relative;
  font-size: 13px;
  padding: 2px;
  background-color: #888888;
  text-align: center;
  border-right: 1px solid #555555;
  display: inline-block;
  box-sizing: border-box;
}

.tip-wrapper {
  position: absolute;
  top: calc(-50px - 1.5rem);
}

.tip0 {
  visibility: hidden;
  position: fixed;
  z-index: 1;
  max-width: 325px;
  min-width: 160px;
  color: #333333;
  text-align: left;
  background: white;
  border: 1px solid black;
}

.tip1 {
  visibility: hidden;
  position: fixed;
  z-index: 1;
  max-width: 325px;
  min-width: 160px;
  color: #333333;
  text-align: left;
  background: white;
  border: 1px solid black;
}

.tooltip:hover .tip0,
.tooltip:hover .tip1 {
  visibility: visible;
}
<div class='gap'>Gap</div>
<div class='table'>
  <div class='table-headers'>
    <div class='tr'>
      <div class='th tooltip'>
        Z
        <div class='tip-wrapper'>
          <div class='tip0'>
            Tip For Column Z is a long tip with enough text to overflow above the page top
          </div>
        </div>
      </div>
      <div class='th'>Y</div>
      <div class='th tooltip'>
        X
        <div class='tip-wrapper'>
          <div class='tip1'>
            Tip For Column Z is a long tip with enough text to overflow above the page top
          </div>
        </div>
      </div>
      <div class='th'>W</div>
      <div class='th'>V</div>
    </div>
  </div>
  <div class='table-body'>
    <div class='tr'>
    </div>
    <div class='tr'>
      <div class='td stick'>A</div>
      <div class='td'>B</div>
      <div class='td'>C</div>
      <div class='td'>D</div>
      <div class='td'>E</div>
    </div>
    <div class='tr'>
      <div class='td'>F</div>
      <div class='td'>G</div>
      <div class='td'>H</div>
      <div class='td'>I</div>
      <div class='td'>J</div>
    </div>
    <div class='tr'>
      <div class='td'>F</div>
      <div class='td'>G</div>
      <div class='td'>H</div>
      <div class='td'>I</div>
      <div class='td'>J</div>
    </div>
    <div class='tr'>
      <div class='td'>F</div>
      <div class='td'>G</div>
      <div class='td'>H</div>
      <div class='td'>I</div>
      <div class='td'>J</div>
    </div>
    <div class='tr'>
      <div class='td'>F</div>
      <div class='td'>G</div>
      <div class='td'>H</div>
      <div class='td'>I</div>
      <div class='td'>J</div>
    </div>
  </div>
</div>

Answer №2

Unique Solution

If you want to replicate your table canvas, you can create a sibling element that mimics it and then apply custom overflow properties to achieve the desired effect:

document.addEventListener('DOMContentLoaded', _ => {
  const tool = document.querySelector('.tooltip-canvas > tooltip')
  const toolEls = Array.from(document.querySelectorAll('.table [tooltip]'))
  toolEls.forEach(t => {
    t.onmouseenter = _ => {
      tool.setAttribute('tooltip', t.getAttribute('tooltip'))
      tool.style.left = `${t.clientLeft}px`
      tool.style.top = `${t.clientTop - 2}px`
    }
    t.onmouseleave = _ => tool.removeAttribute('tooltip')
  })
})
.gap {
  height: 50px
}

.table-wrap {
  position: relative;
  display: inline-block;
}

.table-wrap > .tooltip-canvas {
  position: absolute;
  pointer-events: none;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

.table-wrap > .tooltip-canvas > tooltip {
  content: attr(tooltip);
  position: absolute;
  z-index: 1;
  max-width: 325px;
  min-width: 160px;
  color: #333333;
  text-align: left;
  background: white;
  border: 1px solid black;
  opacity: 0;
  transform: translateY(-100%);
  transition: opacity .25s;
}
.table-wrap > .tooltip-canvas > tooltip[tooltip] {
  opacity: 1;
}

.table-wrap > .tooltip-canvas > tooltip:before {
  content: attr(tooltip)
}

div.table { 
  max-width: 200px;
  overflow: scroll;
  border: 2px solid blue;
  display: inline-block;
  font-family: 'Roboto Mono';
  font-weight: 700;
}

.tr {
  display:flex;
}

.td, .th {
  border: 1px solid black;
  min-width: 60px;
  height: 50px;
}

.th {
  position: relative;
  font-size: 13px;
  padding: 2px;
  background-color: #888888;
  text-align: center;
  border-right: 1px solid #555555;
  display: inline-block;
  box-sizing: border-box;
}
<div class='gap'>.</div>
<section class='table-wrap'>
  <div class='table'>
    <div class='table-headers'>
      <div class='tr'>
        <div class='th' tooltip='Heres the ToolTip For Column Z, getting cut off (bad)'>
          Z
        </div>
        <div class='th'>Y</div>
        <div class='th' tooltip='Heres the Tooltip For Column X, which doesn&spquot;t stay at the top (bad)'>
          X
        </div>
        <div class='th'>W</div>
        <div class='th'>V</div>
      </div>
    </div>
    <div class='table-body'>
      <div class='tr'>
      </div>
      <div class='tr'>
        <div class='td stick'>A</div>
        <div class='td'>B</div>
        <div class='td'>C</div>
        <div class='td'>D</div>
        <div class='td'>E</div>
      </div>
      <div class='tr'>
        <div class='td'>F</div>
        <div class='td'>G</div>
        <div class='td'>H</div>
        <div class='td'>I</div>
        <div class='td'>J</div>
      </div>
    </div>
  </div>
  <aside class='tooltip-canvas'>
    <tooltip></tooltip>
  </aside>
</section>

Answer №3

Make a single adjustment to the top value in tip0:

.tip0 {
  visibility: hidden;
  position: absolute;
  top: 40%;
  z-index: 1;
  max-width: 325px;
  min-width: 160px;
  color: #333333;
  text-align: left;
  background: white;
  border: 1px solid black;
}

.gap {
  height: 100px
}

div.table { 
  max-width: 200px;

  overflow: scroll;
  border: 2px solid blue;
  display: inline-block;
  font-family: 'Roboto Mono';
  font-weight: 700;
}

.tr {
  display:flex;
}

.td, .th {
  border: 1px solid black;
  min-width: 60px;
  height: 50px;
}

.th {
  position: relative;
  font-size: 13px;
  padding: 2px;
  background-color: #888888;
  text-align: center;
  border-right: 1px solid #555555;
  display: inline-block;
  box-sizing: border-box;
}

.tip-wrapper {
  position: absolute;
}

.tip0 {
  visibility: hidden;
  position: fixed;
  z-index: 1;
  max-width: 325px;
  min-width: 160px;
  color: #333333;
  text-align: left;
  background: white;
  border: 1px solid black;
}

.tip1 {
  visibility: hidden;
  position: fixed;
  z-index: 1;
  max-width: 325px;
  min-width: 160px;
  color: #333333;
  text-align: left;
  background: white;
  border: 1px solid black;
}

.tooltip:hover .tip0, .tooltip:hover .tip1 {
  visibility: visible;
}
<div class='gap'>Gap</div>
<div class='table'>
  <div class='table-headers'>
    <div class='tr'>
      <div class='th tooltip'>
        Z
        <div class='tip0'>
          Tip For Column Z is a long tip with enough text to overflow above the page top
        </div>
      </div>
      <div class='th'>Y</div>
      <div class='th tooltip'>
        X
        <div class='tip-wrapper'>
          <div class='tip1'>
            Tip For Column Z is a long tip with enough text to overflow above the page top
          </div>
        </div>
      </div>
      <div class='th'>W</div>
      <div class='th'>V</div>
    </div>
  </div>
  <div class='table-body'>
    <div class='tr'>
    </div>
    <div class='tr'>
      <div class='td stick'>A</div>
      <div class='td'>B</div>
      <div class='td'>C</div>
      <div class='td'>D</div>
      <div class='td'>E</div>
    </div>
    <div class='tr'>
      <div class='td'>F</div>
      <div class='td'>G</div>
      <div class='td'>H</div>
      <div class='td'>I</div>
      <div class='td'>J</div>
    </div>
    <div class='tr'>
      <div class='td'>F</div>
      <div class='td'>G</div>
      <div class='td'>H</div>
      <div class='td'>I</div>
      <div class='td'>J</div>
    </div>
    <div class='tr'>
      <div class='td'>F</div>
      <div class='td'>G</div>
      <div class='td'>H</div>
      <div class='td'>I</div>
      <div class='td'>J</div>
    </div>
    <div class='tr'>
      <div class='td'>F</div>
      <div class='td'>G</div>
      <div class='td'>H</div>
      <div class='td'>I</div>
      <div class='td'>J</div>
    </div>
  </div>
</div>

Answer №4

When placing a tooltip above a table

Make adjustments to the position attribute within .tip0 as shown below by removing the top attribute:

.tip0 {
        visibility: hidden;
        position: fixed;
        margin: -56px -4px;
        z-index: 1;
        max-width: 325px;
        min-width: 160px;
        color: #333333;
        text-align: left;
        background: white;
        border: 1px solid black;
    }

Additionally, include margin in .tip1 like so:

.tip1 {
    visibility: hidden;
    position: fixed;
    margin: -56px -4px;
    z-index: 1;
    max-width: 325px;
    min-width: 160px;
    color: #333333;
    text-align: left;
    background: white;
    border: 1px solid black;
}

For showing the tooltip inside the table

To ensure the tooltip stays inside the table, add the following margin attribute within .tip0 and .tip1:

margin: -17px 0px;

Also, remove the top attribute from .tip0

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

An issue with JSPDF arises when used on mobile devices

Currently, I am working on a project to create a responsive web application, which involves utilizing JSPDF for generating PDF reports directly from HTML. For a demonstration of the functionality, you can check out this Demo. Unfortunately, when trying t ...

What is the best way to maintain an input String when refreshing a page using Selenium Webdriver?

When using Selenium webdriver, I am facing an issue where the value in an input element is not retained after refreshing the page. Interestingly, when testing manually, the scenario works as expected. Is there a way to ensure that the input string remain ...

When using $dialogs.create on my website, a popup form appears with specific formatting limitations dictated by the defining code

When a user clicks a button on my website, a function in the controller is triggered. Here is the function that runs when the button is pressed: $scope.launch = function(idOfSpotOfInterest, schedOfSpotOfInterest){ var dlg = null; dlg = $dialogs. ...

Applying a left margin has caused the right border to disappear

After adding a margin-left to the box, I noticed that my right border is missing. You can see the issue in this example. However, when I remove the margin-left property, everything looks fine as shown in this example. Is there any way to solve this proble ...

Trouble with Bootstrap Popover's visibility

My current setup involves a popover that is not initializing properly. The code I am using is shown below: HTML: <div data-toggle="popover" data-placement="bottom" data-content="xyz">...</div> JavaScript: $(function () { $('[data-t ...

Troubleshooting a problem with CSS animations disappearing

I've been experimenting with CSS animations and I've run into a bit of a snag. I'm looking to create a div that fades in with a delay - meaning it won't be visible until the animation starts. Here's what I have so far: http://jsfi ...

Button on aspx page not functioning properly when clicked

I seem to be experiencing an issue with buttons. To check if the function is being triggered, I used alert("") and found that it does enter the function when the button is clicked. However, after the alert, any other code inside the function seems to not w ...

jQuery mobile menu: Scroll to content after closing the menu

I am currently working on a project where I am using mmenu for the first time. It's functioning as expected, but there is one particular issue that I would really like to have resolved. Here is the URL: What I am hoping to achieve is that when a men ...

Setting breakpoints on rows in Bootstrap 5: A guide

Looking for ways to modify the diagram in the image using Bootstrap 5 specifically for mobile devices ...

CSS - Yet another perplexing question that shouldn't have arisen

While working on building this website in CSS, I hadn't encountered any major issues up until now. Suddenly, I'm facing a problem with basic positioning within my body-3 class div. Instead of pushing it downward and elongating the page as expecte ...

Customizing font sizes for individual fonts within the same font family

I am designing a website in a language other than English. This means that the text on the webpage will be a mixture of English and other languages. In order to make sure the text displays correctly, I have set the font-family like this: p{ font-family: ...

How to make an entire video clickable on Android for seamless playback?

I have implemented an HTML5 video in my mobile web application. Currently, users need to click the small play icon at the bottom left of the video to start playing it. Is there a way to make the entire video clickable so it plays when clicked anywhere on t ...

Issue with conditional comment in IE 8 not functioning as expected

Struggling with changing the SRC attribute of my iFrame specifically for users on IE 8 or older. This is the code I have written: <script> var i_am_old_ie = false; <!--[if lte IE 8]> i_am_old_ie = true; <![endif]--> </script> ...

Customizing the appearance of the browser's autocomplete feature as we input information into the form field

The image illustrates the issue of the background turning white when the browser autofills. However, I am seeking a solution similar to the transparent input below. ...

When JQuery is written in a separate file, it does not get applied in the HTML file

I've encountered an issue that seems to have similarities to others, but despite trying various solutions and writing JQuery code in a JS file, I can't seem to get it to work properly. When I include the path for the JS and JQuery version in the ...

Calculate the total price from a combination of HTML and JavaScript options without altering the values

I'm currently facing an issue in my form where the final price needs to be updated when a different option is selected. I've searched extensively for the problem without success. I've used similar code before, just with different variables a ...

The width of each column in this dataset is variable and unknown

I need to organize a varying number of items into columns. The sizes of both the items and container are unknown, as well as how many columns will fit or what width they should be. I want the browser to arrange the items in as many columns as possible with ...

What is the best way to access the value of an HTML tag in React?

Currently in the process of developing a feature for the price tab using React. These components are designed to allow users to add price classes to their shopping cart. One challenge I'm facing is how to retrieve the HTML string of an HTML tag. Here& ...

svg xlink attribute not functioning properly when embedded as svg object within html

Within the SVG, I have multiple A elements linking to various pages. When the SVG is loaded into a browser as a standalone, the links function properly. However, when it is embedded as an object within an HTML page, the links do not work. It seems like th ...

Troubleshooting my Xpath query for HTML - where did I make a mistake?

Within the <BODY> tags, there is a piece of HTML that I'm attempting to target using scrapy: <section class="content"> <div class="social clearfix"> <div class="profile profile-nano pull-left"> <a hr ...