0

The idea is to show the text in the span element as tooltip when hovered over the image using only CSS. The tooltip should appear above the image and to be centered relative to each image. There could be any number of images inside the div.

NOTE: I cannot change the structure of the HTML.

.parent-div {
  position: relative;
}

img {
  display: inline-block;
  position: inherit;
}

img+span {
  visibility: invisible;
  width: 120px;
  background-color: white;
  color: black;
  text-align: center;
  border-radius: 6px;
  padding: 5px 5px;
  width: 120px;
  top: -80%;
  left: 9%;
  margin-left: -16%;
  position: absolute;
}

img+span:hover {
  visibility: visible;
}
<div class="parent-div">
  <img src="../icon.svg" alt="">
  <span>Text1</span>
  <img src="../icon2.svg" alt="">
  <span>Text2</span>
</div>

But each span element position itself relative to the main div element, meaning that they appear above of the first icon and on top of one another.

I want the span element to be positioned relative to each img element.

j08691
  • 204,283
  • 31
  • 260
  • 272
  • Don't know if possible without altering the HTML (or using javascript). Maybe there is a way. Just a couple of pointers to start: It's `visibility: hidden` and you need to use `img:hover + span`. – tobiv Aug 22 '22 at 15:19
  • Agreed with @tobiv. It may be possible (although I don't quite understand how), but it would be like inventing a bicycle. Seems like changing HTML structure would be the only adequate solution to this. – hpertaia Aug 22 '22 at 15:23
  • Are all the images fixed width? – Michel Aug 22 '22 at 15:31
  • And can you tell us _why_ you can't change the html structure? It would make life a lot easier for you if you could. – Michel Aug 22 '22 at 15:47

2 Answers2

1

Here is sort-of-an-answer for a known/limited number of images and known image width. Using the nth-of-type selector, you can calculate a left value for the tooltip – you'd have to create all the selectors manually though, or use a preprocessor to generate a (hopefully) large enough number of them. And don't forget to also add a top value for when the images start to span multiple rows…

.parent-div {
  position: relative;
}

img {
  display: inline-block;
  position: inherit;
}

img + span {
  position: absolute;
  top: 0;
  left: 0;
  visibility: hidden;
  background: black;
  color: white;
  padding: 5px;
}

img:nth-of-type(2) + span {
  left: calc(1 * 155px);
}
img:nth-of-type(3) + span {
  left: calc(2 * 155px);
}
img:nth-of-type(4) + span {
  left: calc(3 * 155px);
}
/* and so on ... */

img:hover + span {
  visibility: visible;
}
<div class="parent-div">
  <img src="https://via.placeholder.com/150">
  <span>Text1</span>
  <img src="https://via.placeholder.com/150">
  <span>Text2</span>
  <img src="https://via.placeholder.com/150">
  <span>Text3</span>
</div>
tobiv
  • 821
  • 1
  • 8
  • 20
1

This is only working with known image width (in the example 120px);

.parent-div {
  position: relative;
  width: 430px;
}

img {
  float: left;
  width: 120px; height: 100px;
  margin-top: 40px;
  box-sizing: border-box;
  border: 1px solid orange;
}

img + span {
  visibility: hidden;
  display: block;
  float: left;
  width: 120px;
  margin-left: -120px;
  margin-top: 10px;
  box-sizing: border-box;
  padding: 5px 5px;
  background-color: white;
  color: black;
  text-align: center;
  border-radius: 6px;
  border: 1px solid green;
  background: pink;
}
img:hover{
border: 1px solid red;
}
img:hover + span {
  visibility: visible;
}
<div class="parent-div">
      <img src="../icon.svg" alt="">
      <span>Text1</span>
      <img src="../icon2.svg" alt="">
      <span>This is a very long tooltip text with some other text</span>
      <img src="../icon.svg" alt="">
      <span>Text3</span>
      <img src="../icon2.svg" alt="">
      <span>Text4</span>
      <img src="../icon.svg" alt="">
      <span>Text5</span>
      <img src="../icon2.svg" alt="">
      <span>Text6</span>
    </div>
Michel
  • 4,076
  • 4
  • 34
  • 52
  • This breaks when the some text is longer than tooltip width – tobiv Aug 22 '22 at 15:49
  • 1
    @tobiv Fixed (sort of). But this, as any (inluding yours) solution will always be hacky, prone to errors and a surrogate for wrapping each image + span in a container or using something fancy [like this](https://stackoverflow.com/a/25813336/1685196) – Michel Aug 22 '22 at 15:59
  • Agreed, still a creative answer though! – tobiv Aug 22 '22 at 16:01