Własne tooltips

Baloniki (tooltip) to małe okienka zawierające podpowiedzi (w domyślnym ustawieniu z jasnożółtym tłem) które ukazują się gdy najedziemy na jakiś element. W standardowym Html'u możemy takie elementy definiować za pomocą atrybutu title:


<a href="..." title="Kliknij ten guzik aby...">Kliknij</a>

Niestety atrybut title nie daje nam możliwości zbytniego upiększania i formatowania siebie (i bardzo dobrze!). Aby pokazywać własne "ładne" okienka z podpowiedziami, musimy je zrobić sami - co z resztą nie jest wcale trudne.

Tworzenie baloników za pomocą CSS

Najprostsza metoda! Wystarczy wykorzystać fakt, że dla elementów :before i :adter jako content możemy pobierać wartości atrybutów. Wystarczy więc tekst tooltipa podać jako atrybut taga np. data-tooltip, a po najechaniu na element kursorem pokazywać ten tekst w elemencie :before.

Kod przykładowego linka z tooltipem ma postać:


<a href="...." data-tooltip="Przykładowy tekst tooltipa" class="aTooltip">Magiczny link</a>

.aTooltip {
    position:relative;
}

.aTooltip::before {
    content: attr(data-tooltip);
    bottom:60px;
    position: absolute;
    left:50%;
    font-size:13px;
    text-align: center;
    display:inline-block;
    padding:15px 10px;
    color:#fff;
    background:#222;
    width:200px;
    border-radius:3px;
    transform:translate(-50%, 0);
    opacity:0;
    visibility:hidden;
    transition:0.4s opacity;
}
.aTooltip::after {
    width:0;
    height:0;
    border:5px solid transparent;
    border-top-color: #222;
    position: absolute;
    left:50%;
    bottom:50px;
    transform:translate(-50%, 0);
    content:'';
    opacity:0;
    visibility:hidden;
    transition:0.4s opacity;
}
.aTooltip:hover::before {
    visibility:visible;
    opacity:1;
}
.aTooltip:hover::after {
    visibility:visible;
    opacity:1;
}

Pokaż tooltip

Tworzenie baloników w JS

Powyższe rozwiązanie nie zawsze się sprawdzi. Przy elementach o małych powierzchniach pokazywanie podpowiedzi na sztywnej pozycji działa całkiem dobrze. Problem pojawia się przy dużych elementach. Najeżdżamy na element z prawej strony, a tooltip pokaże się gdzieś daleko na środku naszego elementu. Aby to naprawić zrobimy tooltipy, które po najechaniu kursorem na dany element, podążają za kursorem myszy.

Po najechaniu kursorem na element z tekstem do wyświetlenia, pobieramy ten tekst z atrybutu data-tooltip, a następnie wstawiamy go do dynamicznie tworzonego tooltipa, którego wstawimy w element body. Podczas poruszania się kursorem po elemencie będziemy przesuwać tooltip w miejsce kursora myszki. Po opuszczeniu elementu kursorem tooltip usuwamy.


function createTooltip() {
    var tekst = this.getAttribute('data-tooltip'); //Pobieramy tekst podpowiedzi
    var tooltip = document.createElement('div'); //Tworzymy tooltipa
    var body = document.querySelector('body');

    tooltip.appendChild(document.createTextNode(tekst));
    tooltip.id = 'tooltip';
    tooltip.className = 'tooltip';
    body.appendChild(tooltip);
}

function moveTooltip(e) {
    var tooltip = document.querySelector('#tooltip');
    if (tooltip != null) {
        var x, y;

        //pobieramy pozycję myszki wraz ze scrollem okna
        if (e.pageX || e.pageY) {
            x = e.pageX;
            y = e.pageY;
        } else {
            x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
            y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
        }

        tooltip.style.left = x + 'px';
        tooltip.style.top = y - tooltip.offsetHeight - 20 + 'px';
    }
}

function deleteTooltip() {
    var tooltip = document.querySelector('#tooltip');
    if (tooltip != null) {
        tooltip.parentNode.removeChild(tooltip);
    }
}

Teraz wystarczy pobrać wszystkie linki z klasą aTooltip i przypisać im nasze funkcje:


document.addEventListener("DOMContentLoaded", function() {
    var elements = document.querySelectorAll('.aDynamicTooltip[data-tooltip]');

    for (var x=0; x<elements.length; a++) {
        elements[x].addEventListener('mouseover', createTooltip);
        elements[x].addEventListener('mousemove', moveTooltip);
        elements[x].addEventListener('mouseout', deleteTooltip);
    }
});
Stylowanie takiego tooltipa ma postać:

    .tooltip {
        top:-999px;
        left:-999px;
        position: absolute;
        font-size:13px;
        display:inline-block;
        padding:15px 10px;
        color:#fff;
        background:#222;
        width:200px;
        border-radius:3px;
        text-align: center;
        font-family:sans-serif;
        transform:translate(-50%, 0);
    }
    .tooltip::after {
        width:0;
        height:0;
        border:5px solid transparent;
        border-top-color: #222;
        position: absolute;
        left:50%;
        bottom:-10px;
        transform:translate(-50%, 0);
        content:'';
    }

Demo:

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusantium animi dolores earum, enim esse facilis hic modi perspiciatis porro qui quibusdam quo ratione repellat, sunt ullam unde veniam. Alias, suscipit! Lorem ipsum dolor sit amet. Accusantium animi dolores earum, enim esse facilis hic modi perspiciatis porro qui quibusdam quo ratione repellat, sunt ullam unde veniam. Alias, suscipit!


Trening czyni mistrza

Poniżej zamieszczam kilka zadań, które w ramach ćwiczenia możesz wykonać:

  1. Do naszych tooltipów dodaj obsługę dodatkowego atrybutu, który będzie określał dodatkową klasę, którą dostanie tooltip. Klasa ta będzie zmieniać kolor tooltipa
  2. Obsłuż przypadek, kiedy tooltip wychodzi poza ekran. W funkcji moveTooltip() wykorzystaj właściwości window.innerWidth i window.innerHeight