CSS Tooltip

Pogledaćemo na koji način možemo da napravimo tooltip komponentu samo pomoću CSS tehnologije. Obradićemo i moguće probleme ovog pristupa, kao i na koji način ih rešiti.

Šta je tooltip?

Tooltip ili infotip ili hint je komponenta koja u kombinaciji sa kursorom služi da nam pruži dodatne informacije.

Kada korisnik kurosorm pređe preko objekta, pojavljuje se tooltip sa informacijama o stavci preko koje je prešao kursorom.

Treba imati na umu da tooltip nije isto što i popover. Popover može da sadrži i multimedijalni sadržaj, dok tooltip samo sadrži tekst.

Ugrađeni tooltip

Veb pregledač ima već ugrađeni tooltip. On se postavlja tako što postavite atribut title na neki element.

<span title="Ovo je tooltip">Pređi preko mene</span>
Pređi preko mene

Nažalost, ovaj tooltip nije moguće stilski promeniti, pa je zato pogodno napraviti naš tooltip.

Verzija 1

Ovo je verzija koju najčešće viđamo kao rešenje za tooltip pomoću CSS-a

U HTML-u nam je tooltip predstavljen preko jednog elementa, gde tooltip kontrolišemo preko atributa.

<span data-tooltip="Ovo je tooltip">Pređi preko mene</span>

Korisnički navedeni atributi moraju da počinju sa data-

Klasa nam uopšte nije potrebna već ćemo selekciju vršiti preko selektora atributa.

[data-tooltip] {
    position: relative;
  	cursor: pointer;
}

Selektujemo sve elemente koji imaju atribut data-tooltip. Dodelićemo mu poziciju koja će biti relative zato što će unutar sebe imati apsolutne elemente. Takođe smo dodali opciju cursor kako bismo naznačili korisniku kada pređe kursorom preko elementa da postoji neka dodatna informacija.

Unutar tooltip elementa moramo da dodamo pseudo element :before, koji će sadržati sam tekst tooltipa.

On treba da bude apsolutne pozicije zato što će plutati iznad teksta. Sadržaj ćemo uzeti iz samog atributa, pomoću attr() 'funkcije' u CSS-u.

[data-tooltip]::before {
    content: attr(data-tooltip);
    
    position: absolute;
    bottom: 100%; /* Gurnemo ga do vrha */
    left: 50%; /* Stavimo na pola */
    transform: translate(-50%, -4px); /* Centriraj vertikalno i pomeri na gore 4px */
    
    padding: .5em 1em;
    border-radius: 4px;
    background-color: rgba(20, 20, 20, 0.9);
    color: #fff;
    
  
    white-space: nowrap;
    z-index: 7;
}

Ovim smo sada dobili jedan vrlo lep tooltip.

Pređi preko mene

Preostalo nam je da napravimo animaciju. Iskoristićemo dva svojstva u CSS-u visibility i opacity.

Preko svojstva visibility ćamo sakriti tooltip tako da ne smeta elementima iznad, zato što ako koristimo samo svojstvo opacity onda ako postoji element na mestu našeg tooltipa koji treba da se pojavi, korisnik neće moći da dođe do tog elementa, pošto se tooltip nalazi ispred njega. opacity svojstvo će nam služiti samo radi animacije.

[data-tooltip]::before {
    visibility: hidden;
    opacity: 0;
    transition: opacity .3s ease-in-out;
}

Dodamo :hover događaj, kad se pređe preko [data-tooltip] da se pojavi :before.

[data-tooltip]:hover::before {
  visibility: visible;
  opacity: 1;
}
Pređi preko mene

Dobili smo traženi rezultat.

Dodatne opcije

Pozicija

Ovo je najprostiji primer gde se tooltip uvek pojavljuje iznad samog sadržaja ali lako možemo nadograditi ovaj tooltip da se sadržaj pojavljuje sa bilo koje strane.

Ja ću napraviti samo jedan primer, vrlo je lako uraditi za ostale pozicije.

Prvo moramo uvesti dodatni atribut koji određuje poziciju, na primer data-tooltip-position.

<span data-tooltip="Ovo je tooltip" data-tooltip-position="desno">Pređi preko mene</span>

U CSS-u izaberemo element koji ima data-tooltip-position i čija je vrednost desno.

[data-tooltip-position="desno"]:before {
  bottom: 50%; /* Pola visine */
  left: 100%; /* Gurnemo skroz desno */
  transform: translate(4px, 50%); /* Centriraj horizontalno i pomeri na desno 4px */
}

Ostale

Moguće je dodati još neke opcije kao što su:

  • Dodavanje strelice
  • Različite boje (uspešno, upozorenje, info, opasnost)
  • Različite širine
  • Različite animacije

Nedostaci

Ovaj pristup iako vrlo jednostavan i elegantan ima jedan nedostatak, a to je da ako njegov roditelj ima overflow: hidden tooltip se neće videti.

<div class="overflow">
  <span data-tooltip="Ovo je tooltip">Pređi preko mene</span>
</div>
.overflow {
  overflow: hidden;
  border: 1px solid Tomato;
  padding: 20px;
}
Pređi preko mene

Ovaj problem sa ovakvom HTML struktorom nije moguće rešiti.

Verzija 1.1

Ova verzija nije konkretno rešenje već će nam pomoći da dođemo do krajnjeg rešenja.

Kako bi implementirali ovu verziju potrebno je da izmenimo malo strukturu.

<span>Pređi preko mene
	<span class="tooltip">Ovo je tooltip</span>
</span>

.tooltip će biti absolutno pozicioniran.

.tooltip {
    position: absolute;
  	background-color: DodgerBlue;
}

Sada da probamo naš primer:

<div class="overflow">  
	<span>Pređi preko mene
      <span class="tooltip">Ovo je tooltip</span>
  	</span>
</div>
Pređi preko mene Ovo je tooltip

Hmmm, nekako čudno tooltip nije više isečen, o čemu se radi?

Ovde je tooltip relativan u odnosu na neki drugi element a ne na onaj koji ga ograničava.

Nedostaci

Jedan veliki nedostatak ovog pristupa, koji ga ustvari čini ne primenljivim, je to što u slučaju da koristimo svojstva za pozicioniranje (top, right, left i bottom) dobićemo potpuno neočekivane rezultate, zato što je tooltip relativan na neki drugi element (često body).

Verzija 2.0 (Final)

Probaću da modifikujem verziju 1.1 i napravim nešto funkcionalno. Način na koji možemo da rešimo problem pomeranja samog tooltipa ako nije relativan na ono što želimo jeste da ga obmotamo jednim apsolutnim divom i sam tooltip pomeramo sada relativno. Možda zvuči komplikovano, ali uopšte nije ukoliko se razume šta se ustvari dešava.

Postaviću novu strukturu:

<span>Pređi preko mene!
  <span class="tooltip-wrapper">
    <span class="tooltip">Ovo je tooltip</span>
  </span>
</span>

.tooltip-wrapper će imati istu ulogu kao .tooltip u verziji 1.1, biće samo apsolutno pozicioniran.

.tooltip-wrapper {
  position: absolute;
}

Dok će unutar njega postojati još jedan element koji će biti relativan, upravo zbog pomenutog problema nemogućnosti pomeranja.

.tooltip {
    position: relative;
    right: 100%; /* Sada pomeramo tooltip */
    bottom: 2em;

    padding: .5em 1em;
    border-radius: 4px;
    background-color: rgba(20, 20, 20, 0.9);
    color: #fff;
  }

Dobijemo upravo ono što smo tražili

Pređi preko mene! Ovo je tooltip

Dodaću na .tooltip-wrapper-u plavu boju kako bismo lakše shvatili gde se on ustvari nalazi.

Pređi preko mene! Ovo je tooltip

Nedostaci

Ovaj pristup, iako pruža rešenje, meni lično nije sintaksno lep, struktura je komplikovana.

Verzija 2.1 (Final final)

U cilju poboljšanja verzije 2.0 napravio sam verziju 2.1 koja ima malo uprošćenu strukturu. Rešenje je kombinacija rešenja 2.0 i 1.0.

<span>Pređi preko mene!
  <span class="tooltip-wrapper" data-tooltip="Ovo je tooltip"></span>
</span>

Kao u verziji 1.0 ću iskoristiti pseudo elemente da dodam sam tooltip, samo što ga sada dodajem u naš .tooltip-wrapper koji je apsolutan.

.tooltip-wrapper {
    position: absolute;
}

.tooltip-wrapper::before {
    content: attr(data-tooltip); /* Kao u verziji 1.0 */
    position: relative;
    right: 100%;
    bottom: 2em;

    padding: .5em 1em;
    border-radius: 4px;
    background-color: rgba(20, 20, 20, 0.9);
    color: #fff;
}

Kranji rezultat:

Pređi preko mene!

Zaključak

Prošli smo kroz par načina pravljenja tooltip-a u CSS-u, neki su bili dobri, neki loši, ali smo kroz svaki valjda naučili nešto.

Tooltip je, takođe, moguće napraviti preko javaskripte, pisaću i o tome vrlo uskoro, sa željom da uporedim oba pristupa što se tiče preformansi.