How to use Popper for tooltips instead of Bootstrap

Why I make this?

I wanted to use tooltips on the Data for Education Systems website. I normally use Bootstrap for styling but the Just the Docs theme I am using eliminates the need for that. Unfortunately, and naturally, there is no built-in way of creating tooltips in the theme.

Adding Bootstrap for this tiny feature seemed an overkill. In any case, Bootstrap relies on Popper for tooltips as well.

It took me a little while to figure out how to use Popper with a few extra bells and whistles. So I wrote this code snippet down for my future self.

What it look like?

Here is a sentence with some text with a tooltip.

How to do this?

Install Popper into your project. I prefer to use the CDN version. Like this –

1
<script src="https://unpkg.com/@popperjs/core@2"></script>

Now, depending on how you are adding your content (Markdown or Raw HTML), you’ll have to write your tooltip text in the following manner –

1
Here is a sentence with some <span class="popover" tooltip-title="Thanks for setting me freeeee!" tooltip-position="top" tooltip-time="2500">text with a tooltip</span>.

What we are doing here is wrapping the “text with a tooltip” in a span element, adding the ‘popover’ class to it, and writing the tooltip text in the tooltip-title attribute.

Plus, you can also define the preferred position of the tooltip using the tooltip-position attribute. The default is ’top’. Note that Popper will reposition the tooltip so it is always visible. So even if you set the position as ’top’, if the user scrolls down the page, the tooltip will be shown below the element.

And, you can also define the time after which the tooltip should disappear using the tooltip-time attribute. The default is 4000 milliseconds.

Next, you need a bit of JavaScript to make the tooltip work. Here’s what you need to do –

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// Handling Popovers/Tooltips

// Add the 'onclick' attribute to all elements with the 'popover' class
// and assign them a unique ID
const popovers = document.querySelectorAll('.popover');
popovers.forEach(popover => {
  popover.setAttribute('onclick', 'toggleTooltip(this)');
  popover.id = 'popover-' + Math.floor(Math.random() * 1000000);
});

// Initiate an array to store the self-destruct timers for each tooltip
const tooltipTimers = [];

// The function that toggles the tooltip
function toggleTooltip(el, action) {
  // If the tooltip is already visible, remove it
  if (el.classList.contains('tooltip-visible') || action === 'remove') {
    const tooltip = document.body.querySelector('#tooltip-' + el.id);
    if (tooltip) { tooltip.remove(); }
    el.classList.remove('tooltip-visible');
  } else {
    // If the tooltip is not visible, create it
    const tooltipText = el.getAttribute('tooltip-title');
    const tooltip = document.createElement('div');
    tooltip.innerText = tooltipText;
    tooltip.classList.add('tooltip');
    tooltip.classList.add('show');
    tooltip.setAttribute('role', 'tooltip');
    tooltip.setAttribute('id', 'tooltip-' + el.id);
    document.body.appendChild(tooltip);
    
    // Call popper with the tooltip and the element that triggered it
    Popper.createPopper(el, tooltip, {
      placement: el.getAttribute('tooltip-position') || 'top',
    });
    // Add the 'tooltip-visible' class to the element that triggered the tooltip
    // so we can track it and remove the tooltip when the user clicks it again
    el.classList.add('tooltip-visible');
    
    // Set a timer to remove the tooltip after 4 seconds
    const removeTooltipTimer = setTimeout(() => {
      toggleTooltip(el, 'remove');
    }, el.getAttribute('tooltip-time') || 4000);

    // Store the timer in the tooltipTimers array
    tooltipTimers.push(removeTooltipTimer);
  }
}

And finally, a bit of styling –

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21

.tooltip {
  background-color: #333;
  color: white;
  padding: 5px 10px;
  border-radius: 4px;
  font-size: 13px;
  max-width: 200px;
  opacity: 0;
  transition: opacity 0.3s ease-in-out;
}

.show {
  opacity: 1;
}

.popover {
  border-bottom: 1px dashed #7253ed;
  cursor: pointer;
  color: #7253ed !important;
}

I know there are several things that can be improved with this code. But this covers the very minimum that you need to get started. You can extend this snippet as you like!