CSS3 aiuta davvero molto nel semplificare il disegno di tooltip: se non fosse per il layout flexbox saremmo ancora obbligati a dover ricorrere ad espedienti come un margine negativo, per centrare un gruppo di elementi. Ma cosa dire riguardo quel piccolo triangolo che caratterizza un tooltip? A volte le vecchie soluzioni non perdono contemporaneità.
Un Triangolo da un Bordo
D'accordo, con CSS un bordo può dare forma ad un triangolo. Ma Come?
Il bordo di un elemento HTML non è reso dal browser come un unico elemento grafico, in effetti un bordo è costituito da quattro sezioni distinte, ognuna delle quali può avere caratteristiche specifiche. Inoltre negli angoli, dove si incontrano sezioni adiacenti, il rendering è tutto tranne che continuo.
Se provi a disegnare un bordo sufficientemente spesso, e dai ad ogni sezione un colore diverso, vedrai con i tuoi occhi di cosa sto parlando: quattro trapezi isosceli che compongono il bordo.

Puoi ottenere il risultato sopra con uno snippet come questo:
1.sample-element {
2 border-top-color: coral;
3 border-right-color: cadetblue;
4 border-bottom-color: darkorchid;
5 border-left-color: lightblue;
6 border-style: solid;
7 border-width: 20px;
8}
Hai scovato il triangolo? Ancora no? Allora prova a far collassare su se stesso l'elemento HTML rimuovendo contenuto e padding
, o in alternativa, impostando a zero width
, height
e padding
.
Risultato: quattro triangoli a nostra disposizione.

La buona notizia è che questa tecnica è applicabile anche agli pseudo-elementi!
Il Punto di Inizio
Dopo questa breve premessa, possiamo iniziare a programmare!
Siccome è buona abitudine non strafare con il markup, andremo a disegnare il tutto con tre <span>
. Perché non usare dei <div>
? Perché l'elemento span
ci permetterà di inserire il nostro tooltip sia in elementi HTML inline che block senza il rischio di invalidare il markup.
1<span class="tooltip-wrapper">
2 <span class="tooltip">I am a Tooltip!</span>
3 <span class="help-point">?</span>
4</span>
Per iniziare, scriviamo le nostre prime linee di CSS per dar forma ad un disco, con un punto interrogativo nel mezzo, a partire all'elemento .help-point
:
1.tooltip-wrapper .help-point {
2 background-color: #333;
3 border-radius: 50%;
4 color: #fff;
5 cursor: default;
6 display: flex;
7 font-size: 0.65rem;
8 font-weight: bold;
9 height: 1rem;
10 width: 1rem;
11
12 /* Centra verticalmente il punto interrogativo */
13 align-items: center;
14
15 /* Centra orizzontalmente il punto interrogativo */
16 justify-content: center;
17}
Il codice appena scritto si traduce in questo:

Dare Forma al Tooltip
Il tooltip in se è composto da due parti:
- un rettangolo posizionato in modo assoluto, avente un'ampiezza fissa e modellato a partire dall'elemento
.tooltip
- un triangolo posizionato in modo assoluto, nato dallo pseudo-elemento
.tooltip::before
grazie alla tecnica descritta all'inizio dell'articolo

Siccome .tooltip
è posizionato in modo assoluto, l'elemento contenitore (.tooltip-wrapper
) collasserà alla dimensione dell'elemento .help-point
. In questo modo, nel momento in cui applichiamo delle "regole flexbox" per centrare il tooltip relativamente a .tooltip-wrapper
, otterremo che il tooltip sarà automaticamente centrato anche rispetto all'elemento .help-point
.
Ecco il codice:
1.tooltip-wrapper {
2 position: relative;
3
4 /**
5 * Centra il tooltip orizzontalmente
6 * rispetto a .tooltip-wrapper.
7 */
8 display: inline-flex;
9 justify-content: center;
10 }
11 .tooltip-wrapper:hover .tooltip {
12 display: flex;
13 }
14 .tooltip-wrapper .tooltip {
15 background-color: #333;
16 border-radius: 4px;
17 box-shadow: 0px 2px 4px #07172258;
18 color: #fff;
19 display: none;
20 font-size: 0.68rem;
21 line-height: 1.35em;
22 padding: 0.5em 0.7em;
23 position: absolute;
24 text-align: center;
25 width: 7rem;
26 z-index: 1;
27
28 /**
29 * 100% dell'altezza di .tooltip-wrapper
30 *
31 * 0.6em è l'altezza del triangolo ( .tooltip::before )
32 *
33 * 2px è uno spazio vuoto arbitrario tra
34 * la punta del triangolo e .help-point
35 */
36 bottom: calc( 100% + 0.6em + 2px );
37
38 /**
39 * Centra il triangolo orizzontalmente
40 * rispetto l'elemento .tooltip
41 */
42 justify-content: center;
43 }
44 .tooltip-wrapper .tooltip::before {
45 content: "";
46 display: block;
47 border-style: solid;
48 position: absolute;
49
50 /**
51 * Impostare a 0 l'ampiezza del bordo
52 * inferiore assicura che il tooltip scompaia
53 * anche quando il cursore viene spostato verso
54 * l'alto, fuori dall'elemento .tooltip-wrapper
55 */
56 border-width: 0.6em 0.8em 0;
57
58 /* Mostriamo solo il triangolo superiore */
59 border-color: transparent;
60 border-top-color: #333;
61
62 /* 100% dell'altezza di .tooltip */
63 top: 100%;
64 }
L'intera Cascata
Ovviamente ci sono varianti al disegno di un tooltip proposto in questo articolo, ma i concetti base continuano ad essere validi.
Per riepilogare, il markup da cui siamo partiti è questo:
1<span class="tooltip-wrapper">
2 <span class="tooltip">I am a Tooltip!</span>
3 <span class="help-point">?</span>
4</span>
E la cascata, riassettata, di regole CSS usate per dare al tooltip l'aspetto voluto è quella che segue. Non dimenticare di armeggiare con questo codice, di rifattorizzarlo, e di usarlo come punto di partenza per qualcosa di creativo!
1.tooltip-wrapper {
2 display: inline-flex;
3 justify-content: center;
4 position: relative;
5 }
6 .tooltip-wrapper:hover .tooltip {
7 display: flex;
8 }
9 .tooltip-wrapper .tooltip {
10 background-color: #333;
11 border-radius: 4px;
12 bottom: calc( 100% + 0.6em + 2px );
13 box-shadow: 0px 2px 4px #07172258;
14 color: #fff;
15 display: none;
16 font-size: 0.68rem;
17 justify-content: center;
18 line-height: 1.35em;
19 padding: 0.5em 0.7em;
20 position: absolute;
21 text-align: center;
22 width: 7rem;
23 z-index: 1;
24 }
25 .tooltip-wrapper .tooltip::before {
26 border-width: 0.6em 0.8em 0;
27 border-color: transparent;
28 border-top-color: #333;
29 content: "";
30 display: block;
31 border-style: solid;
32 position: absolute;
33 top: 100%;
34 }
35 .tooltip-wrapper .help-point {
36 align-items: center;
37 background-color: #333;
38 border-radius: 50%;
39 color: #fff;
40 cursor: default;
41 display: flex;
42 font-size: 0.65rem;
43 font-weight: bold;
44 height: 1rem;
45 justify-content: center;
46 width: 1rem;
47 }
