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

What is the best way to retrieve data from within HTML tags using PL/SQL?

Within my Oracle PL SQL project, I am dealing with an html file that contains the following comment tag. I need to figure out how to retrieve the value between these comment tags. <comment label="Comments">Text_to_Extract</comment>&l ...

Having issues with Json stringification and serializing arrays

Having an issue with Json when using serializeArray. An example of my HTML form: <form action="" method="post" name="myForm"> ID: <input type="text" name="id" /><br/> State (XX): <input type="text" name="state" /><br/> <p ...

Display item upon hovering and for an extended period upon clicking using jQuery

I am looking to create a functionality where hovering over an area displays item 2 for a certain duration, which is currently working fine with the existing code. However, I also want it to remain visible for a longer period if clicked, but this does not ...

What are the steps to create a responsive form using CSS?

I have a screenshot below that needs to be recreated using HTML/CSS. This design should be consistent in both desktop and mobile views. https://i.stack.imgur.com/cnfHt.png Currently, I have managed to replicate this in a JSFiddle which looks good on desk ...

Tips for stopping the navigator from adding content to an HTML input in an Angular application

I am facing an issue with two input fields in my Angular project. These fields are supposed to take values automatically from the browser, and I have tried using the HTML autocomplete option without success. Here is a snippet of my HTML code: <div clas ...

Have an overlay on a specific area of the webpage while ensuring the remaining sections remain interactive to the user's inputs

Looking for a way to add an overlay in a specific area of a webpage without blocking the other sections? I attempted to use the LightBox feature from primefaces components, but it didn't give me the desired result. I'm struggling to keep the unco ...

Using the symbol for pi in a JavaScript program rather than its numerical value, while still performing calculations with the numerical value behind the scenes

I am working on a calculator project where I want the symbol for pi to be displayed instead of the numerical value. Here is the relevant function: function Pi(pi) { document.getElementById('resultArea').innerHTML += pi; eval(document.ge ...

jQuery function to automatically close any other opened divs when a new div is opened

I have multiple elements that reveal a div when clicked. The issue is that if all elements are clicked, all divs open instead of just the one that was clicked. This is my jQuery code: <script> $(document).ready(function() { $('.servicemark ...

Is it possible to insert both the name and value of a complete attribute within an element using a string in Razor?

There is a common way to achieve this in asp.net MVC Razor Engine: @{ string myValue = "foo" } <h1 hello='@myValue'></h1> However, I am interested in an alternative approach that might result in an error: @{ string myAttri ...

The Java.lang.finalize heap became too large during the Hadoop URL parsing task

I'm currently working on analyzing the content of various homepage URLs by utilizing a Hadoop mapper without a reducer. This mapper fetches the URLs and sends them to a parser class for further analysis. The parser leverages Jericho's html parse ...

The expansion feature of PrimeNG Turbotable

I'm currently facing an issue with the Primeng Turbotable where I am unable to expand all rows by default. You can find a code example of my problem at this link. I have already tried implementing the solution provided in this example, but unfortuna ...

The background image in the hovering textbox shifts and changes size

I've been trying to set a background image on a Kendo UI Textbox. It looks good until you hover over it. But when you do hover over it, this issue arises: How can I resolve this? The background image should remain in place even when I hover and cli ...

Incomplete width allocation for the floating div positioned to the left

I've encountered an issue with the placement of the side-text div in relation to the image. Currently, without specifying the width of the side-text div, it automatically moves to the bottom. To address this problem, I attempted using display:inline- ...

Utilizing getElementsByClassName for web scraping: encountering inaccurate outcomes

I am attempting to extract the inner text from all classes with the className = "disabled" within the provided snippet of HTML Code: HTML code In my effort to achieve this task using MS Access (VBA), the code I have implemented is as follows: Set IE = C ...

Perform the same actions on every element within the ul li

I'm facing an issue with my unordered list, where each list item contains a span element with an image inside. My goal is to set the background-image of each span to be the same as the image it contains, while also setting the opacity of the image to ...

Creating a secondary ordered list with ongoing points - a step-by-step guide

Is there a way to create an unordered list with a continued ordered second level that automatically counts the points? I know about using <ol start="Previous number+1">, but is it possible for the list to continue numbering on its own? The ...

A versatile Material UI paper that adjusts its dimensions dynamically

Utilizing Material-UI's Paper component (https://mui.com/components/paper/), I've encountered a scenario where the content within the Paper element needs to be dynamic. <Paper className="modal" elevation={3}> ...Content </Paper ...

What method can I use to incorporate a custom CSS code in Formfacade to conceal the back button on a Google Form?

Looking for a way to hide the back button on my custom questionnaire created with Google Forms? While there is no built-in option to do this directly on Google Forms, I decided to embed my form into Formfacade. However, I am struggling to find the CSS co ...

The image must be able to fit within the div container without distorting its proportions

Recently, I created a slider that functions flawlessly. However, I am struggling to make the image fit inside the div without distorting its proportions. I've tried various methods but haven't been able to achieve the desired result. Could you p ...

Stop the page from scrolling

I'm trying to find a way to disable page scrolling, so I used this style for the body: overflow: hidden; Surprisingly, it worked perfectly on desktop but had no effect on mobile devices. After checking out this resource, it seems that creating a ch ...