Även om HTML5 Canvas och SVG kan vara mer eleganta lösningar för att bygga diagram, kommer vi att lära oss hur vi bygger vårt eget donut-diagram med ingenting annat än vanlig CSS.
För att få en uppfattning om vad vi ska skapa, ta en titt på den inbyggda CodePen-demo nedan:
Vi börjar med en mycket grundläggande uppställning. en vanlig oorderad lista med a spänna
element inuti var och en av listobjekten:
Med markeringen klar, tillämpar vi först några grundläggande stilar på den oordnade listan:
.diagramfärdigheter position: relativ; bredd: 350px; höjd: 175px;
Då ska vi ge var och en en ::efter
och a ::innan
pseudo-element, och stil dem:
.diagram färdigheter :: före, .chart-färdigheter :: efter position: absolute; .chart-färdigheter :: före innehåll: "; bredd: ärv, höjd: ärv, gräns: 45px fast rgba (211,211,211, .3), gränsbotten: ingen; gränsen till vänstra radien: 175px; Top-right-radius: 175px; .chart-skills :: efter innehåll: "Top Skills"; vänster: 50%; botten: 10px; transform: translateX (-50%); fontstorlek: 1,1rem; font-weight: bold; färg: cadetblue;
Var uppmärksam på stilar för ::innan
pseudo-elementet. Detta ger oss vår halvcirkel.
Hittills ger ovannämnda regler oss detta resultat:
Låt oss nu diskutera styling av listobjekten.
Med avseende på listposternas ställning gör vi följande:
Dessutom är ett par saker värda att notera här:
z-index
fast egendom.transform-ursprung
fastighetsvärde (dvs.. transformations-ursprung: 50% 50%
) i listobjekten. Specifikt bestämmer vi transformations-ursprung: 50% 0
. På detta sätt, när vi animerar (roterar) föremålen, blir mitt mittövre hörn centrum för rotation.Här är de associerade CSS-stilarna:
.diagramfärdigheter li position: absolute; topp 100%; vänster: 0; bredd: ärv höjd: ärv gräns: 45px solid; border-top: none; gränsen längst ner till vänster: 175px; gränsbotten-högra radie: 175px; transformations-ursprung: 50% 0; .chart-skills li: nth-child (1) z-index: 4; gränsfärg: grön; .chart-skills li: nth-child (2) z-index: 3; gränsfärg: firebrick; .chart-skills li: nth-child (3) z-index: 2; gränsfärg: stålblå; .chart-skills li: nth-child (4) z-index: 1; kantfärg: orange;
Ta en titt på vad vi har byggt hittills i nästa visualisering:
spänner och listobjektFör tillfället är det enda listobjektet som är synligt den gröna (som har z-index: 4;
) de andra är under den.
Innan vi täcker stegen för att animera våra listobjekt, låt oss notera den önskade procentsatsen för varje objekt (dvs: hur mycket av munkningen kommer att täcka). Tänk på följande tabell:
Språk | Procentsats |
---|---|
CSS | 12 |
html | 32 |
PHP | 34 |
Pytonorm | 22 |
Därefter beräknar vi hur många grader vi måste animera (rotera) var och en av objekten. För att ta reda på exakt antal grader för varje objekt multiplicerar vi sin procentandel med 180 ° (inte 360 ° eftersom vi använder en halvcirkel donut diagram):
Språk | Procentsats | Antal grader |
---|---|---|
CSS | 12 | 12/100 * 180 = 21,6 |
html | 32 | 32/100 * 180 = 57,6 |
PHP | 34 | 34/100 * 180 = 61,2 |
Pytonorm | 22 | 22/100 * 180 = 39,6 |
Vid denna tidpunkt är vi redo att skapa animationerna. Först definierar vi några animationsstilar som delas över alla objekt, genom att lägga till några regler till .kartfärdigheter li
:
animations-fyll-läge: framåt; animeringstid: .4s; animation-timing-funktion: linjär;
Då definierar vi de unika animationsstilarna:
.diagram färdigheter li: nth-child (1) z-index: 4; gränsfärg: grön; animationsnamn: rotera-en; .chart-skills li: nth-child (2) z-index: 3; gränsfärg: firebrick; animationsnamn: rotera-två; animationsfördröjning: .4s; .chart-skills li: nth-child (3) z-index: 2; gränsfärg: stålblå; animationsnamn: rotera-tre; animationsfördröjning: .8s; .chart-skills li: nth-child (4) z-index: 1; kantfärg: orange; animationsnamn: rotera-fyra; animationsfördröjning: 1,2s;
Observera att vi lägger till en fördröjning för alla artiklar utom den första. På detta sätt skapar vi trevliga sekventiella animeringar. Till exempel när animationen av det första elementet slutar visas det andra elementet och så vidare.
Nästa steg är att ange de faktiska animationerna:
@keyframes rotera-en 100% transform: rotera (21.6deg); / ** * 12% => 21.6deg * / @keyframes rotera-två 0% transform: rotera (21.6deg); 100% transform: rotera (79,2deg); / ** * 32% => 57.6deg * 57.6 + 21.6 => 79.2deg * / @keyframes rotera-tre 0% transform: rotera (79.2deg); 100% transform: rotera (140,4deg); / ** * 34% => 61.2deg * 61.2 + 79.2 => 140.4deg * / @keyframes rotera-fyra 0% transform: rotera (140.4deg); 100% transform: rotera (180deg); / ** * 22% => 39.6deg * 140.4 + 39.6 => 180deg * /
Innan vi går längre tittar vi kort på hur animationerna fungerar:
Det första elementet går från transformera: ingen
till transformera: rotera (21.6deg)
.
Det andra elementet går från transformera: rotera (21.6deg)
(börjar från det första elementets slutposition) till transformera: rotera (79.2deg)
(57.6deg + 21.6deg).
Det tredje elementet går från transformera: rotera (79.2deg)
(börjar från det sista läget för det andra elementet) till transformera: rotera (140.4deg)
(61,2deg + 79,2deg).
Det fjärde elementet går från transformera: rotera (140.4deg)
(börjar från det tredje elementets slutposition) till transformera: rotera (180deg)
(140.4deg + 39.6deg).
Sist men inte minst, för att dölja den nedre halvan av diagrammet måste vi lägga till följande regler:
.kartfärdigheter / * befintliga regler ... * / överfyllning: dold; .chart-skills li / * befintliga regler ... * / transform-style: conserve-3d; backface-visibility: hidden;
De överflöd: dold
egendomsvärde säkerställer att endast den första halvcirkeln (den som skapats med ::innan
pseudo-elementet) är synligt. Ta bort den här egenskapen om du vill testa den ursprungliga positionen för listobjekten.
De transform-stil: bevara-3d
och backface-visibility: hidden
egenskaper förhindrar flimmer effekter som kan uppstå i olika webbläsare på grund av animeringar. Om problemet fortfarande finns i din webbläsare kan du också prova dessa lösningar.
Diagrammet är nästan klart! Allt som återstår är att ställa in tablettiketterna, som vi gör i nästa avsnitt.
Här är CodePen-demo som visar det aktuella utseendet på vårt diagram:
I det här avsnittet kommer vi att ställa in diagrametiketterna.
Med hänsyn till deras ställning gör vi följande:
position: absolut
och använd topp
och vänster
egenskaper för att ställa in önskad position.transformera: rotera (79.2deg)
, och därmed dess relaterade etikett kommer att ha transformera: rotera (-79.2deg)
.Nedan finns motsvarande CSS-stilar:
.diagram-kompetens span position: absolute; typsnittstorlek: .85rem; .chart-skills li: nth-child (1) span top: 5px; vänster: 10px; transformera: rotera (-21.6deg); .chart-skills li: nth-child (2) span top: 20px; vänster: 10px; transformera: rotera (-79.2deg); .chart-skills li: nth-child (3) span top: 18px; vänster: 10px; transformera: rotera (-140,4deg); .chart-skills li: nth-child (4) span top: 10px; vänster: 10px; transformera: rotera (-180deg);
Nu när vi har placerat etiketterna är det dags att animera dem. Två saker är värda att nämna här:
animering-fördröjning
egenskap för att skapa sekventiella animeringar. Dessutom lägger vi till backface-visibility: hidden
egendom värde för att säkerställa att det inte finns några blinkande effekter på grund av animeringar.CSS-reglerna som hanterar animeringen av diagrametiketterna visas nedan:
.diagram-kompetens span backface-visibility: hidden; animering: fade-in .4s linjär framåt; .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 fade-in 0%, 90% opacitet: 0; 100% opacitet: 1;
Här är det slutliga diagrammet:
Generellt fungerar demon bra i alla webbläsare. Jag vill bara diskutera två små problem som är relaterade till border-radius
fast egendom.
Först, om vi skulle ge olika färger till våra föremål, kan diagrammet se ut så här:
Lägg märke till till exempel den övre och nedre delen av det tredje objektet. Det finns två röda linjer som kommer från gränsfärgen på det fjärde objektet. Vi kan se dessa linjer eftersom det fjärde objektet har en mörkare kantfärg jämfört med den tredje. Även om det här är ett litet problem, är det bra att vara medveten om det för att välja lämpliga färger för dina egna diagram.
För det andra visas i Safari följande:
Titta på de små luckorna som visas i andra och tredje föremål. Om du vet något om detta problem, låt oss veta i kommentarerna nedan!
I denna handledning gick vi igenom processen med att skapa en halvcirkeln donut diagram med ren CSS. Återigen, som nämnts i introduktionen finns det potentiellt mer kraftfulla lösningar (t ex HTML5 Canvas och SVG) där ute för att skapa sådana slags saker. Men om du vill bygga något enkelt och lätt, och njut av en utmaning, är CSS vägen att gå!