JSFiddle - React, Tailwind, and code Playground

by oece

HTML

<div id='tooltip' class='tooltip'>
    <div class='border'>
        <div class='inner'>42%</div>
    </div>
</div>

<p><span data-tooltip="I'm tooltip!">hover me</span> or maybe <span data-tooltip='HTML5'>me</span>?</p>
<p>This is small example of tooltips without any <span data-tooltip='java-script library that almost any front-end<br />developer is using nowadays, and most of them<br />not able to code without it. Btw get it <a href="http://jquery.com/" target="_blank">here</a>.'>jQuery</span> with pure <span data-tooltip='java-script'>JS</span> and <span data-tooltip='Hyper Text Markup Language<br />fifth revision'>HTML5</span> tooltip element. Tooltip it self is aligned in the middle, so only left and top have to be defined using styles.</p>
<p>No any image were used to produce this example</p>
<p>Two tooltips in a row <span data-tooltip='there is issue sometimes with event mouseover<br /> triggers before mouseout of previous element.'>A</span><span data-tooltip='but not with that tooltip!'>B</span></p>
<p>What about <span data-tooltip='<img src="http://www.mrsaghafi.com/images/HTML5_Logo_32.png" />'>image</span>? Probably <span data-tooltip='aaaa'>any</span> html.</p>
<br />
<p><span data-tooltip='<a href="http://cv.moka.co/" target="_blank">click here</a>'>Contact Me</span>? I can do cool thing for you.</p>

CSS

body {
    background: #444;
    color: #eee;
    font-family: Helvetica;
    margin: 20px;
    height: 1500px;
}
p {
    margin: 8px 0;
}
span {
    text-decoration: underline;
    cursor: default;
}
span:hover {
    color: #d1ff00;
}
div.tooltip {
    position: fixed;
    padding-top: 7px;
    display: none;
}
div.tooltip > div.border {
    position: absolute;
    padding: 4px 4px 3px;
    background: #333;
    position: relative;
    
    border-bottom: 1px solid #555;
    
    -webkit-border-radius: 4px;
    -moz-border-radius: 4px;
    border-radius: 4px;
}
div.tooltip > div.border:before {
    content: '';
    position: absolute;
    top: -7px;
    left: 50%;
    margin-left: -7px;
    width: 0;
    height: 0;
    border-bottom: 7px solid #333;
    border-left: 7px solid transparent;
    border-right: 7px solid transparent;
}
div.tooltip > div.border > div.inner {
    min-width: 4px;
    padding: 2px 4px;
    text-align: center;
    color: #d1ff00;
    background: #444;
    font-size: 14px;
    font-family: Helvetica;
    
    page-break-after: avoid;
    page-break-before: avoid;
    page-break-inside: avoid;
    white-space: nowrap;
    
    border-top: 1px solid #555;
    border-bottom: 1px solid #222;
    
    -webkit-border-radius: 2px;
    -moz-border-radius: 2px;
    border-radius: 2px; 
}
div.tooltip > div.border > div.inner:after {
    content: '';
	position: absolute;
    top: -1px;
    left: 50%;
    margin-left: -6px;
    width: 0;
    height: 0;
    border-bottom: 6px solid #444;
    border-left: 6px solid transparent;
    border-right: 6px solid transparent;
}
div.tooltip > div.border > div.inner a {
    color: #d1ff00;
    text-decoration: underline;
}

JavaScript

// find tooltip element
var tooltip = document.getElementById('tooltip');

// prevent tooltip from hiding
tooltip.stopHide = function() {
    if (this.timer) {
        clearTimeout(this.timer);
        this.timer = null;
    }
}
// trigger tooltip to hide (100 ms after calling)
tooltip.startHide = function() {
    this.stopHide();
    this.timer = setTimeout((function() {
        this.style.display = 'none';
    }).bind(this), 100);
}
// position tooltip
tooltip.position = function(x, y) {
    this.style.left = Math.round(x - tooltip.offsetWidth / 2) + 'px';
    this.style.top = Math.round(y) + 'px';
}

// on mouse over tooltip prevent it from hiding
tooltip.addEventListener('mouseover', function() {
    this.stopHide();
}, false);
// on mouse out from tooltip start hiding
tooltip.addEventListener('mouseout', function() {
    this.startHide();
}, false);


// find all elements with data-tooltip attribute
var elements = document.querySelectorAll('[data-tooltip]');
// iterate through all elements
var i = elements.length;
while(i--) {
    // on mouse over element, prevent tooltip from hiding, position and show it
    elements[i].addEventListener('mouseover', function() {
        tooltip.stopHide();
        // get position of element
        var rect = this.getBoundingClientRect();
        // set tooltip html from element attribute data-tooltip
        if (tooltip.querySelector('div.inner').innerHTML != this.getAttribute('data-tooltip')) {
        	tooltip.querySelector('div.inner').innerHTML = this.getAttribute('data-tooltip');
        }
        // show tooltip
        tooltip.style.display = 'block';
        // set position for tooltip
        tooltip.position(rect.left + rect.width / 2, rect.bottom);
    }, false);
    // on mouse out start hiding tooltip
    elements[i].addEventListener('mouseout', function() {
        tooltip.startHide();
    }, false);
}