Position Tooltips and Popovers using Popper.js

JavascriptProgramming ScriptsWeb DevelopmentFront End Technology

Popper.js is a JavaScript library that is used when we want to build poppers and tooltips and manage them. It helps us in positioning tooltips and popovers in most modern web applications. In this tutorial, we will show how you can use Popper.js to position tooltips, but it should be noted that Popper is not just all about tooltips, yet is somewhat the foundation on which it is built.

Let's Start with a Small Example

Let's create a simple tooltip with a button to understand how we can use popper.js.

The first step is to install popper.js on our machine. While there are multiple ways with which it can be done, in this tutorial, we will just use the CDN links. We need to put the following code snippet inside the <body> tag, just before closing the <body> tag.

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

index.html

Example

Now let's start working on the core index.html file.

Start with creating a file named index.html. In this file, you need to create two elements, where the first element will be a button and the second element will be a tooltip, which we add the positioning logic to. Consider the index.html file shown below.

<!DOCTYPE html> <html> <head> <title>Popper Tooltip Example</title> </head> <body> <button id="button" aria-describedby="tooltip">My button</button> <div id="tooltip" role="tooltip">My tooltip</div> <script src="https://unpkg.com/@popperjs/core@2"></script> <script> const myButton = document.querySelector('#button'); const myTooltip = document.querySelector('#tooltip'); const popperInstance = Popper.createPopper(myButton, myTooltip); </script> </body> </html>

Updated index.html File

Example

While the HTML part may be done for the basic view template, the styling part is pending. In the styling part, we will add the following styles to the current page.

<!DOCTYPE html> <html> <head> <title>Popper Tutorial</title> <style> body { text-align: center; margin: 0 auto; } #tooltip { background: #333; color: white; font-weight: bold; padding: 4px 8px; font-size: 13px; border-radius: 4px; display: none; } </style> </head> <body> <button id="button" aria-describedby="tooltip">My button</button> <div id="tooltip" role="tooltip">Simple tooltip</div> <script src="https://unpkg.com/@popperjs/core@2"></script> <script> const myButton = document.querySelector('#button'); const myTooltip = document.querySelector('#tooltip'); const popperInstance = Popper.createPopper(myButton, myTooltip); </script> </body> </html>

If we run the html file shown above in the browser, we should see a button and a tooltip with the text "Simple tooltip". The tooltip that we created is currently not actually a tooltip, and in order for us to make it a tooltip, we need to have an arrow that is pointing toward the reference elements.

We can put an arrow element with a "data-popper-arrow" by writing the code snippet shown below.

<div id="tooltip" role="tooltip">
   Simple tooltip
   <div id="arrow" data-popper-arrow></div>
</div>

After this, we need to update the styling as well. We can do that by pasting the code shown below in the <style> tag. Consider the updated styling shown below.

#arrow,
#arrow::before {
   position: absolute;
   width: 8px;
   height: 8px;
   background: inherit;
}
#arrow {
   visibility: hidden;
}
#arrow::before {
   visibility: visible;
   content: '';
   transform: rotate(45deg);
}

Now comes the interesting part where we need to update the popper's current placement and we can do that with the help of the data-popper-placement attribute. Consider the styling shown below.

#tooltip[data-popper-placement^='top'] > #arrow {
   bottom: -4px;
}
#tooltip[data-popper-placement^='bottom'] > #arrow {
   top: -4px;
}
#tooltip[data-popper-placement^='left'] > #arrow {
   right: -4px;
}
#tooltip[data-popper-placement^='right'] > #arrow {
   left: -4px;
}

If we run the above code now, we will be able to see the arrow pointing to the button from the tooltip as well. Though the arrow might be pointing towards the button, it is overlapping the button and to change that, we need to introduce an offset. Consider the code snippet shown below.

const popperInstance = Popper.createPopper(button, tooltip, {
      modifiers: [{
         name: 'offset',
         options: {
            offset: [0, 8],
         },
      },
   ],
});

Now there will be an offset between the button and the tooltip.

Next, comes the part where we want to add the functionality in which we want to make sure that the tooltip is only visible when we hover over the button. This can be achieved by first putting the following styling inside the <style> tag.

#tooltip {
   display: none;
}
#tooltip[data-show] {
   display: block;
}

The first property in which we are making the "display:none;" it is for an already present tag with "id = tooltip". Next comes the JavaScript functionality part. Consider the code shown below.

function show() {
   tooltip.setAttribute('data-show', '');
   popperInstance.update();
}

function hide() {
   tooltip.removeAttribute('data-show');
}

const showEvents = ['mouseenter', 'focus'];
const hideEvents = ['mouseleave', 'blur'];
showEvents.forEach((event) => {
   button.addEventListener(event, show);
});

hideEvents.forEach((event) => {
   button.addEventListener(event, hide);
});

Now everything is done. The final index.html code is shown below.

Final index.html File

Example

<!DOCTYPE html> <html> <head> <title>Popper Tutorial</title> <style> body { text-align: center; margin: 0 auto; } #tooltip { background: #333; color: white; font-weight: bold; padding: 4px 8px; font-size: 13px; border-radius: 4px; display: none; } #tooltip[data-show] { display: block; } #arrow, #arrow::before { position: absolute; width: 8px; height: 8px; background: inherit; } #arrow { visibility: hidden; } #arrow::before { visibility: visible; content: ''; transform: rotate(45deg); } #tooltip[data-popper-placement^='top']>#arrow { bottom: -4px; } #tooltip[data-popper-placement^='bottom']>#arrow { top: -4px; } #tooltip[data-popper-placement^='left']>#arrow { right: -4px; } #tooltip[data-popper-placement^='right']>#arrow { left: -4px; } </style> </head> <body> <button id="button" aria-describedby="tooltip">My button</button> <div id="tooltip" role="tooltip">Simple tooltip <div id="arrow" data-popper-arrow></div> </div> <script src="https://unpkg.com/@popperjs/core@2"></script> <script> const myButton = document.querySelector('#button'); const myTooltip = document.querySelector('#tooltip'); const popperInstance = Popper.createPopper(myButton, myTooltip, { modifiers: [{ name: 'offset', options: { offset: [0, 8], }, }, ], }); function show() { tooltip.setAttribute('data-show', ''); popperInstance.setOptions((options) => ({ ...options, modifiers: [ ...options.modifiers,{ name: 'eventListeners', enabled: true }, ], })); popperInstance.update(); } function hide() { tooltip.removeAttribute('data-show'); popperInstance.setOptions((options) => ({ ...options, modifiers: [ ...options.modifiers,{ name: 'eventListeners', enabled: false }, ], })); } const showEvents = ['mouseenter', 'focus']; const hideEvents = ['mouseleave', 'blur']; showEvents.forEach((event) => { button.addEventListener(event, show); }); hideEvents.forEach((event) => { button.addEventListener(event, hide); }); </script> </body> </html>

In the above code, inside the createPopper function, we can even add a property called placement whose value can define the position of our tooltip.

Conclusion

In this tutorial, we explained how you can use popper.js and its features to work with tooltips and position them.

raja
Updated on 11-Oct-2022 13:20:21

Advertisements