1

I have an html page with a JS script generating a SVG image made of many polygons (SVG is added inline inside the HTML). I gave some of them a title, so that the user can hoover and get a caption.

Example:

<?xml version="1.0" standalone="no"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<polygon points="0,10 5,7 10,10 10,16 5,19 0,16" fill="rgb(114,132,56)" stroke="rgb(114,132,56)" stroke-width="1"><title>Washington</title></polygon>
</svg>

There is a delay for the browser to display this text.

I would like for it to appear faster.

Is this doable? Or do I have to change the structure to use something like map for image?

I found how to customize the appearance of this tooltip, but not how to change the speed for display.

Pierre
  • 145
  • 1
  • 15

1 Answers1

3

There is no way to change this via CSS. However you can mimic the tooltip with Javascript. Here is an example improving on a solution from @Timmmm. The improvement consists in preserving the title elements for users using a screen reader.

function showTooltip(event) {
  let element = event.target;
  let tooltipElement = document.getElementById('tooltip');
  let title;

  if (!element.dataset.title) {
    let titleElement = element.querySelector('title');
    title = titleElement.innerHTML;
    event.target.setAttribute('data-title', title);
    titleElement.parentNode.removeChild(titleElement);
  } else {
    title = element.dataset.title;
  }
  
  tooltipElement.innerHTML = title;
  tooltipElement.style.display = 'block';
  tooltipElement.style.left = event.pageX + 10 + 'px';
  tooltipElement.style.top = event.pageY + 10 + 'px';
}

function hideTooltip() {
  var tooltip = document.getElementById('tooltip');
  tooltip.style.display = 'none';
}
#tooltip {
  background: cornsilk;
  border: 1px solid black;
  border-radius: 3px;
  padding: 2px 4px;
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
    <polygon  
         onmousemove="showTooltip(event);"
         onmouseout="hideTooltip();"
         points="0,10 5,7 10,10 10,16 5,19 0,16"
         fill="rgb(114,132,56)"
         stroke="rgb(114,132,56)"
         stroke-width="1">
       <title>Washington</title>
    </polygon>
</svg>

<div id="tooltip" style="position: absolute; display: none;"></div>

To optimise for small file size when many shapes are present, both the styles and event binding can be moved out of the SVG and into Css / Javascript:

function showTooltip(event) {
  let element = event.target;
  let tooltipElement = document.getElementById('tooltip');
  let title;
  if (!element.dataset.title) {
    let titleElement = element.querySelector('title');
    title = titleElement.innerHTML;
    event.target.setAttribute('data-title', title);
    titleElement.parentNode.removeChild(titleElement);
  } else {
    title = element.dataset.title;
  }
  
  tooltipElement.innerHTML = title;
  tooltipElement.style.display = 'block';
  tooltipElement.style.left = event.pageX + 10 + 'px';
  tooltipElement.style.top = event.pageY + 10 + 'px';
}

function hideTooltip() {
  var tooltip = document.getElementById('tooltip');
  tooltip.style.display = 'none';
}

document.addEventListener('DOMContentLoaded', function(event) {
  const tooltipTriggers = document.querySelectorAll('polygon');
  Array.from(tooltipTriggers).map(trigger => {
    trigger.addEventListener('mousemove', showTooltip);
    trigger.addEventListener('mouseout', hideTooltip);
  })
});
.tooltip {
  position: absolute;
  background: cornsilk;
  border: 1px solid black;
  border-radius: 3px;
  padding: 2px 4px;
}

svg .grey {
  fill: rgb(114, 132, 56);
  stroke: rgb(114, 132, 56);
  stroke-width: 1;
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
    <polygon
         class="grey"
         points="0,10 5,7 10,10 10,16 5,19 0,16">
       <title>Washington</title>
    </polygon>
</svg>

<div id="tooltip" class="tooltip" style="display: none;"></div>
Hans Spieß
  • 897
  • 7
  • 13
  • Huge thanks! It works with many polygons as well. It makes a much heavier image, but it works great. Thanks! – Pierre May 04 '21 at 19:55
  • 1
    @Pierre glad it helped! To reduce file size, some optimizations can be applied – see my updated answer for an example to do so. – Hans Spieß May 04 '21 at 21:17