1

I'm trying to add absolutely positioned tooltips to a simple CSS three column layout - but the tooltip always gets cut off by subsequent columns.

The tooltip also breaks across columns if it runs above or below the upper or lower limits of the wrapper element.

Is there any way to ensure that the tooltip is always on top of the columns - and also that it never breaks across columns and is allowed to run outside the bounds of the wrapper element?

Edit - I should clarify that the list will be of unknown/variable length, and I'd prefer to avoid having to rely on Javascript to format the list (e.g. by splitting it in 3 and wrapping each section) if possible. The list should also wrap vertically, as in the snippet, and not horizontally across columns.

.wrapper {
  display: block;
  width: 50%;
  background-color: white;
  border: 2px solid red;
  -webkit-column-count: 3;
  -moz-column-count: 3;
  column-count: 3;
  column-gap: 2em;
  -webkit-column-gap: 2em;
  -moz-column-gap: 2em;
  -webkit-column-rule: 2px solid red;
  -moz-column-rule: 2px solid red;
  column-rule: 2px solid red;
  margin-bottom: 5em;
}

.wrapper span {
  position: relative;
  display: inline-block;
  width: 100%;
  -webkit-column-break-inside: avoid;
  page-break-inside: avoid;
  break-inside: avoid;
  padding: 1em;
  cursor: pointer;
  transition: 0.2s color linear
}

.wrapper span:hover {
  color: red;
}

.wrapper span:hover .tooltip {
  display: block;
}

.tooltip {
  display: none;
  position: absolute;
  width: 100%;
  top: 0;
  left: 50%;
  padding: 1em;
  border: 2px solid black;
  color: white;
  background-color: lightgray;
}
<div class="wrapper">
  <span>item 1 <p class="tooltip">Tooltip!</p></span>
  <span>item 2 <p class="tooltip">Tooltip!</p></span>
  <span>item 3 <p class="tooltip">Tooltip!</p></span>
  <span>item 4 <p class="tooltip">Tooltip!</p></span>
  <span>item 5 <p class="tooltip">Tooltip!</p></span>
  <span>item 6 <p class="tooltip">Tooltip!</p></span>
  <span>item 7 <p class="tooltip">Tooltip!</p></span>
  <span>item 8 <p class="tooltip">Tooltip!</p></span>
  <span>item 9 <p class="tooltip">Tooltip!</p></span>
  <span>item 10 <p class="tooltip">Tooltip!</p></span>
</div>
D-Money
  • 2,375
  • 13
  • 27
  • May be related to [When using column-count, overflowing content completely disappears in all, but first column, why?](https://stackoverflow.com/questions/29624396/when-using-column-count-overflowing-content-completely-disappears-in-all-but-f) – GolezTrol Oct 02 '17 at 12:59

2 Answers2

1

The problem is your tooltips are position: absolute but the spans aren't. You would have to make all the spans position: absolute as well if you wanted it to work this way.

Here is what I would do:

Instead of using these CSS properties:

-webkit-column-count: 3;
-moz-column-count: 3;
column-count: 3;
column-gap: 2em;
-webkit-column-gap: 2em;
-moz-column-gap: 2em;
-webkit-column-rule: 2px solid red;
-moz-column-rule: 2px solid red;
column-rule: 2px solid red;

I would divide it into three <div class="wrapper"> elements like this:

<div class="wrapper">
...
</div>
<div class="wrapper">
...
</div>
<div class="wrapper">
...
</div>

And change the .wrapper CSS to have these properties:

display: inline-block;
float: left;

So they sit side-by-side.

If you do this the position: absolute of the tooltips will always be above the rest of the HTML.


EDIT: example of server-side rendering pseudocode (no JavaScript needed):

int column = 1;

var firstColumn, secondColumn, thirdColumn;
foreach (var item in items) {
    if (column == 1) { firstColumn.Add(item); column = 2; continue; }
    if (column == 2) { secondColumn.Add(item); column = 3; continue; }
    if (column == 3) { thirdColumn.Add(item); column = 1; continue; }
}

<div class="wrapper">
// Loop through firstColumn, adding spans for each
</div>

<div class="wrapper">
// Loop through secondColumn, adding spans for each
</div>

<div class="wrapper">
// Loop through thirdColumn, adding spans for each
</div>
Omar Himada
  • 2,540
  • 1
  • 14
  • 31
  • Thanks! The problem with this solution is that the list I'm working with will be of unknown length. I could use Javascript to divide the list up and wrap each section as you have shown above - but I would rather not use JS where CSS should work alone. – D-Money Oct 02 '17 at 13:12
  • But if the number of columns is always static (like in your original CSS, -`webkit-column-count: 3;`) then you could just render the new items one by one in the first `.wrapper`, then the second, then the third, in a loop. Not sure what web technology you're using but you could accomplish this in Razor (ASP .NET) and I know Java server pages would allow the same thing. – Omar Himada Oct 02 '17 at 13:16
1

The only solution I could find that did not involve javascript was to use an ugly hack - by adding translateZ(0); to the tooltips they appears 'above' the other columns.

It's not ideal but from my research there doesn't yet seem to be a way to allow overflow between CSS columns.

D-Money
  • 2,375
  • 13
  • 27
  • I just spent hours trying to figure out how to let content overflow, and ` transform: translateZ(0)` did the trick. You saved me so much additional stress. – Robotnicka Apr 20 '18 at 19:29