We are going to create a plugin that can show nice tooltips in this tutorial, this is done with pure JavaScript. A tooltip is a small message that is supposed to help a user to enter a valid value in an input element.
This plugin is supposed to work on all devices and on all screen sizes. A tooltip will be shown on mouseenter or a click, a visible tooltip will disappear on mouseleave or a click. Tooltips is shown below the target as default but will be shown over the target if the tooltip is below the visible viewport.
This plugin has been tested and is working with Google Chrome (75.0.3770.100), Mozilla Firefox (67.0.4) and Microsoft Edge (42.17134.1.0), without any polyfill. It works in Internet Explorer (11.829.17134.0) with a polyfill for Element.prototype.closest and Element.prototype.remove. If you want to support older browsers, check out our post on transpilation and polyfilling of JavaScript.
JavaScript
This plugin is static and only have private methods, it relies entirely on events. Event listeners is added for elements that has tooltip as a rel attribute, the tooltip is added inside the tags of the element.
(function () {
'use_strict';
// Get all targets
var targets = document.querySelectorAll('[rel="tooltip"]');
// Loop targets
for (var i = 0; i < targets.length; i++) {
// Add listeners
targets[i].addEventListener('mouseenter', function ()
{
addTooltip(this, document.querySelector('.annytab-tooltip'));
}, false);
targets[i].addEventListener('mouseleave', function ()
{
removeTooltip(this, document.querySelector('.annytab-tooltip'));
}, false);
targets[i].addEventListener('click', function () {
// Get the active tooltip
var tooltip = document.querySelector('.annytab-tooltip');
// Get the target
var target = event.target.closest('[rel="tooltip"]');
// Check if the tooltip exists or not
if (tooltip === null)
{
// Add a tooltip
addTooltip(target, tooltip);
}
else
{
// Remove a tooltip
removeTooltip(target, tooltip);
}
}, false);
} // End of for (var i = 0; i < targets.length; i++)
// Add a tooltip
function addTooltip(target, tooltip)
{
// Get the title
var title = target.getAttribute('title');
// Make sure that title not is null or empty
if (title === null || title === '' || tooltip !== null)
{
return false;
}
// Remove the title of the target
target.removeAttribute('title');
// Add a tooltip
tooltip = document.createElement('div');
tooltip.setAttribute('class', 'annytab-tooltip');
tooltip.innerHTML = title;
target.insertAdjacentElement('beforeend', tooltip);
// Initiate the tooltip
tooltip.style.right = '0px';
tooltip.style.top = target.offsetTop + target.offsetHeight + 10 + 'px';
var bounding = tooltip.getBoundingClientRect();
// Check if the tooltip is below the viewport
if (bounding.bottom > (window.innerHeight || document.documentElement.clientHeight))
{
tooltip.style.top = '';
tooltip.style.bottom = target.offsetTop + target.offsetHeight + 10 + 'px';
tooltip.classList.add('top');
}
else
{
tooltip.classList.add('bottom');
}
} // End of the addTooltip method
// Remove a tooltip
function removeTooltip(target, tooltip)
{
if (tooltip !== null)
{
// Reset the title and remove the tooltip
target.setAttribute('title', tooltip.innerHTML);
tooltip.remove();
}
} // End of the removeTooltip method
})();
Styling (CSS)
A tooltip is added with a annytab-tooltip class and can be placed at the bottom of the target or at the top of the target. No styling for box-sizing is added here, box-size styling makes elements size correctly in browsers.
.annytab-tooltip {
text-align: left;
color: #ffffff;
background: #000000;
position: absolute;
z-index: 100;
font-size: 16px;
line-height: 24px;
padding: 15px;
max-width: 100%;
border-radius: 4px;
border: 1px solid #000000;
}
.annytab-tooltip.bottom::after {
position: absolute;
width: 0;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-bottom: 10px solid #000000;
content: '';
top: -11px;
right: 10px;
}
.annytab-tooltip.top::after {
position: absolute;
width: 0;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-top: 10px solid #000000;
content: '';
bottom: -11px;
right: 10px;
}
How to use this plugin
We add a div element with an icon, a title and a tooltip rel attribute after each input that should have a tooltip. The tooltip will be added inside this element, this is important to avoid a flickering behavior. Polyfills is needed for this plugin to work in Internet Explorer 11 and older browsers.
<!DOCTYPE html>
<html>
<head>
<title>Tooltips</title>
<style>
input, div, a, textarea, select {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
font-family: Arial, Helvetica, sans-serif;
}
.annytab-form-label {
display: block;
width: 100%;
max-width: 500px;
padding: 0px 2px 0px 2px;
font-size: 16px;
line-height: 24px;
font-weight: bold;
margin: 10px 0px 0px 0px;
}
.annytab-input-group {
display: table;
position: relative;
width: 100%;
max-width: 500px;
padding: 0px;
margin: 10px 0px 0px 0px;
border: 1px solid #d9d9d9;
border-radius: 8px;
height: 34px;
}
.input-group-cell {
display: table-cell;
text-align: center;
padding: 0px;
vertical-align: middle;
}
.input-group-control {
display: block;
background-color: transparent;
width: 100%;
border: 0px;
margin: 0px;
font-size: 16px;
line-height: 16px;
padding: 10px 5px 10px 5px;
}
</style>
</head>
<body style="width:100%;font-family:Arial, Helvetica, sans-serif;">
<div style="display:block;padding:10px;">
<div class="annytab-form-label">Name</div>
<div class="annytab-input-group">
<div class="input-group-cell" style="width:460px;text-align:left;">
<input name="txtName" type="text" class="input-group-control" value="" placeholder="Marvin Swansson" />
</div>
<div class="input-group-cell" style="width:40px;border-left:1px solid #d9d9d9;cursor:help;"
title="Enter your name in this textbox." rel="tooltip">
<i class="far fa-question-circle fa-fw fa-lg"></i>
</div>
</div>
<div class="annytab-form-label">City</div>
<div class="annytab-input-group">
<div class="input-group-cell" style="width:460px;text-align:left;">
<input name="txtCity" type="text" class="input-group-control" value="" placeholder="Stockholm" />
</div>
<div class="input-group-cell" style="width:40px;border-left:1px solid #d9d9d9;cursor:help;"
title="Enter the name of the city in which you live at the moment." rel="tooltip">
<i class="far fa-question-circle fa-fw fa-lg"></i>
</div>
</div>
<div class="annytab-form-label">Color</div>
<div class="annytab-input-group">
<div class="input-group-cell" style="width:460px;text-align:left;">
<input name="txtColor" type="text" class="input-group-control" value="" placeholder="Red" />
</div>
<div class="input-group-cell" style="width:40px;border-left:1px solid #d9d9d9;cursor:help;"
title="Enter the name of your favorite color in this textbox. Your favorite color says a lot about you, it tells us which color you like the most :)." rel="tooltip">
<i class="far fa-question-circle fa-fw fa-lg"></i>
</div>
</div>
</div>
@*Scripts*@
@*<script crossorigin="anonymous" src="https://polyfill.io/v3/polyfill.min.js?features=Element.prototype.closest%2CElement.prototype.remove"></script>*@
<script src="/js/font-awesome/all.min.js"></script>
<link href="/css/annytab.tooltip.css" rel="stylesheet" />
<script src="/js/annytab.tooltip.js"></script>
</body>
</html>