Come costruire un grafico ad anello semicircolare con i CSS

Sebbene HTML5 Canvas e SVG possano essere soluzioni più eleganti per la creazione di grafici, in questo tutorial impareremo come costruire il nostro grafico ad anello con nient'altro che semplici CSS.

Per avere un'idea di cosa creeremo, dai un'occhiata alla demo di CodePen incorporata di seguito:

Markup HTML

Iniziamo con un markup molto semplice; una semplice lista non ordinata con a campata elemento all'interno di ciascuna voce dell'elenco: 

  • CSS
  • HTML
  • PHP
  • Pitone

Aggiunta di stili all'elenco

Con la marcatura pronta, per prima cosa applichiamo alcuni stili di base all'elenco non ordinato:

.grafico-competenze posizione: relativo; larghezza: 350 px; altezza: 175 px; 

Quindi, daremo a ciascuno uno ::dopo e a ::prima pseudo-elemento, e lo stile:

.chart-skills :: before, .chart-skills :: after position: absolute;  .chart-skills :: before content: "; width: inherit; height: inherit; border: 45px solid rgba (211,211,211, .3); border-bottom: none; border-top-left-radius: 175px; border -top-right-radius: 175px; .chart-skills :: after content: "Top Skills"; left: 50%; bottom: 10px; transform: translateX (-50%); font-size: 1.1rem; font-weight: bold; colour: cadetblue;

Prestare attenzione agli stili per il ::prima pseudo-elemento. Questo ci dà il nostro semicerchio.

Pseudo elementi

Finora, le suddette regole ci danno questo risultato:

Aggiunta di stili agli elementi dell'elenco

Discutiamo ora sullo stile degli articoli della lista.

Posizionamento 

Per quanto riguarda la posizione delle voci dell'elenco, facciamo quanto segue:

  • Posizionali proprio sotto il loro genitore e
  • dare loro gli stili appropriati in modo da creare un semicerchio al contrario.

Inoltre, un paio di cose vale la pena notare qui:

  • Le voci dell'elenco sono posizionate in modo assoluto, quindi siamo in grado di impostarle z-index proprietà.
  • Modifichiamo il valore predefinito trasformare origine valore della proprietà (es. trasformazione-origine: 50% 50%) delle voci dell'elenco. Nello specifico, abbiamo impostato trasformazione-origine: 50% 0. In questo modo, quando animiamo (ruotiamo) gli oggetti, il loro angolo superiore centrale diventerà il centro di rotazione.

Ecco gli stili CSS associati:

.abilità grafiche li position: absolute; i primi 100%; a sinistra: 0; larghezza: eredita; altezza: eredita; bordo: 45 px solido; border-top: nessuno; border-bottom-left-radius: 175 px; border-bottom-right-radius: 175 px; trasformazione-origine: 50% 0;  .chart-skills li: nth-child (1) z-index: 4; border-color: verde;  .chart-skills li: nth-child (2) z-index: 3; border-color: firebrick;  .chart-skills li: nth-child (3) z-index: 2; border-color: steelblue;  .chart-skills li: nth-child (4) z-index: 1; border-color: arancione; 

Dai un'occhiata a ciò che abbiamo costruito finora nella prossima visualizzazione:

si estende e elenca gli oggetti

Attualmente, l'unica voce della lista che è visibile è quella verde (che ha z-index: 4;) gli altri sono al di sotto.

animazioni

Prima di esaminare i passaggi per l'animazione delle voci dell'elenco, prendiamo nota della percentuale desiderata per ciascun articolo (ovvero: la parte della ciambella che coprirà ciascuna). Considera la seguente tabella:

linguaggio Percentuale
CSS 12
HTML 32
PHP 34
Pitone 22

Successivamente, calcoliamo quanti gradi dobbiamo animare (ruotare) ciascuno degli elementi. Per scoprire il numero esatto di gradi per ogni oggetto, moltiplichiamo la sua percentuale di 180 ° (non 360 ° perché stiamo usando a semicerchio grafico ad anello):

linguaggio Percentuale
Numero di gradi
CSS 12 12/100 * 180 = 21,6
HTML 32
32/100 * 180 = 57,6
PHP 34 34/100 * 180 = 61,2
Pitone 22 22/100 * 180 = 39,6

A questo punto siamo pronti per impostare le animazioni. Innanzitutto, definiamo alcuni stili di animazione condivisi tra tutti gli elementi, aggiungendo alcune regole a .abilità di grafico li:

 animazione-fill-mode: avanti; durata dell'animazione: .4s; animazione-temporizzazione-funzione: lineare; 

Quindi, definiamo gli stili di animazione univoci:

.grafico-skills li: nth-child (1) z-index: 4; border-color: verde; nome-animazione: ruotare-uno;  .chart-skills li: nth-child (2) z-index: 3; border-color: firebrick; nome-animazione: ruota-due; ritardo di animazione: .4s;  .chart-skills li: nth-child (3) z-index: 2; border-color: steelblue; nome-animazione: ruotare-tre; ritardo di animazione: .8s;  .chart-skills li: nth-child (4) z-index: 1; border-color: arancione; nome-animazione: ruotare-quattro; ritardo di animazione: 1,2 s; 

Si noti che aggiungiamo un ritardo a tutti gli elementi tranne il primo. In questo modo, creiamo belle animazioni sequenziali. Ad esempio, quando termina l'animazione del primo elemento, viene visualizzato il secondo elemento e così via. 

Il prossimo passo è specificare le animazioni effettive:

@keyframes rotate-one 100% transform: ruotare (21.6deg); / ** * 12% => 21.6deg * / @keyframes rotate-two 0% transform: ruotare (21.6deg);  100% transform: rotate (79.2deg); / ** * 32% => 57.6deg * 57.6 + 21.6 => 79.2deg * / @keyframes rotate-three 0% transform: ruotare (79.2deg);  100% transform: rotate (140.4deg); / ** * 34% => 61.2deg * 61.2 + 79.2 => 140.4deg * / @keyframes rotate-four 0% transform: ruotare (140.4deg);  100% transform: ruotare (180 gradi); / ** * 22% => 39,6 gradi * 140,4 + 39,6 => 180 gradi * /

Prima di andare avanti, vedremo brevemente come funzionano le animazioni:

Il primo elemento va da trasformare: nessuno a transform: ruotare (21.6deg).

Il secondo elemento va da transform: ruotare (21.6deg)  (inizia dalla posizione finale del primo elemento) a transform: ruotare (79.2deg) (57.6deg +21.6deg). 

Il terzo elemento va da transform: ruotare (79.2deg)  (inizia dalla posizione finale del secondo elemento) a trasformare: ruotare (140,4 gradi) (61.2deg + 79.2deg).

Il quarto elemento va da trasformare: ruotare (140,4 gradi)  (inizia dalla posizione finale del terzo elemento) a trasformare: ruotare (180 °) (140,4 gradi + 39,6 gradi).

Nascondere!

Ultimo ma non meno importante, per nascondere la metà inferiore del grafico, dobbiamo aggiungere le seguenti regole:

.abilità di grafici / * regole esistenti ... * / overflow: nascosto;  .chart-skills li / * regole esistenti ... * / transform-style: preserve-3d; backface-visibility: hidden; 

Il overflow: nascosto il valore della proprietà garantisce che solo il primo semicerchio (quello creato con il ::prima pseudo-elemento) è visibile. Sentiti libero di rimuovere quella proprietà se vuoi testare la posizione iniziale degli articoli della lista. 

Il stile di trasformazione: preserve-3d e controfaccia-visibility: hidden le proprietà prevengono effetti di sfarfallio che possono verificarsi in diversi browser a causa di animazioni. Se il problema persiste nel tuo browser, potresti provare anche queste soluzioni.

Il grafico è quasi pronto! Non resta che definire le etichette del grafico, che faremo nella prossima sezione.

Ecco la demo di CodePen che mostra l'aspetto attuale del nostro grafico:

Aggiunta di stili alle etichette

In questa sezione, modificheremo le etichette del grafico.

Posizionamento

Per quanto riguarda la loro posizione, facciamo quanto segue:

  • Dare loro posizione: assoluta e usa il superiore e sinistra proprietà per impostare la loro posizione desiderata.
  • Utilizza valori negativi per ruotarli. Naturalmente, questi non sono valori casuali. In realtà, questi vengono estratti dall'ultimo frame dell'articolo genitore. Ad esempio, include l'ultimo fotogramma del secondo elemento dell'elenco transform: ruotare (79.2deg), e così avrà la sua etichetta correlata transform: ruotare (-79,2 gradi).

Di seguito sono riportati gli stili CSS corrispondenti:

.capacità delle carte in classifica posizione: assoluta; font-size: .85rem;  .chart-skills li: nth-child (1) span top: 5px; a sinistra: 10px; transform: ruotare (-21.6deg);  .chart-skills li: nth-child (2) span top: 20px; a sinistra: 10px; transform: ruotare (-79,2 gradi);  .chart-skills li: nth-child (3) span top: 18px; a sinistra: 10px; transform: ruotare (-140.4deg);  .chart-skills li: nth-child (4) span top: 10px; a sinistra: 10px; transform: ruotare (-180 gradi); 

animazioni

Ora che abbiamo posizionato le etichette, è ora di animarle. Vale la pena menzionare due cose qui:

  • Per impostazione predefinita, tutte le etichette sono nascoste e diventano visibili quando viene animato l'elemento principale. 
  • Analogamente agli articoli genitore, usiamo il animazione ritardo proprietà per creare animazioni sequenziali. Inoltre, aggiungiamo il controfaccia-visibility: hidden valore della proprietà per garantire che non ci siano effetti di sfarfallio dovuti alle animazioni.

Le regole CSS che si occupano dell'animazione delle etichette del grafico sono mostrate di seguito:

.span delle carte nautiche backface-visibility: hidden; animazione: fade-in .4s forward lineari;  .chart-skills li: nth-child (2) span animation-delay: .4s;  .chart-skills li: nth-child (3) span animation-delay: .8s;  .chart-skills li: nth-child (4) span animation-delay: 1.2s;  @keyframes dissolvenza in apertura 0%, 90% opacità: 0;  100% opacità: 1; 

Ecco il grafico finale:

Supporto e problemi del browser

In generale, la demo funziona bene su tutti i browser. Voglio solo discutere di due piccoli problemi relativi al border-radius proprietà.

Innanzitutto, se dovessimo dare colori diversi ai nostri articoli, il grafico potrebbe essere simile a questo: 

Si noti ad esempio gli angoli superiore e inferiore del terzo elemento. Ci sono due linee rosse che provengono dal colore del bordo del quarto oggetto. Possiamo vedere quelle linee perché il quarto elemento ha un colore del bordo più scuro rispetto al terzo. Sebbene si tratti di un piccolo problema, è bene esserne consapevoli per poter scegliere i colori appropriati per i propri grafici.

In secondo luogo, in Safari il grafico appare come segue:

Guarda le piccole lacune che compaiono nel secondo e nel terzo elemento. Se sai qualcosa riguardo questo problema, faccelo sapere nei commenti qui sotto!

Conclusione

In questo tutorial, abbiamo esaminato il processo di creazione di un grafico a ciambella a semicerchio con puro CSS. Di nuovo, come menzionato nell'introduzione, ci sono soluzioni potenzialmente più potenti (ad esempio HTML5 Canvas e SVG) disponibili per creare questo tipo di cose. Tuttavia, se vuoi creare qualcosa di semplice e leggero e goderti una sfida, il CSS è la strada da percorrere!