Hoewel HTML5 Canvas en SVG mogelijk elegante oplossingen zijn voor het bouwen van diagrammen, zullen we in deze zelfstudie leren hoe we onze eigen ringdiagram kunnen bouwen met niets dan duidelijke CSS.
Om een idee te krijgen van wat we gaan maken, bekijk de embedded CodePen-demo hieronder:
We beginnen met een paar heel eenvoudige markeringen; een eenvoudige ongeordende lijst met een span
element in elk van de lijstitems:
Als de markup klaar is, passen we eerst een aantal basisstijlen toe op de ongeordende lijst:
.grafiek-vaardigheden positie: relatief; breedte: 350 px; hoogte: 175 px;
Dan gaan we elke een geven ::na
en een ::voor
pseudo-element, en style ze:
.grafiekvaardigheden :: 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: 'Topvaardigheden'; links: 50%; onder: 10px; transform: translateX (-50%); font-size: 1.1rem; lettertype: vet; kleur: cadetblue;
Besteed aandacht aan de stijlen voor de ::voor
pseudo-element. Dit geeft ons onze halve cirkel.
Tot dusverre geven de bovengenoemde regels ons dit resultaat:
Laten we nu de styling van de lijstitems bespreken.
Met betrekking tot de positie van de lijstitems doen we het volgende:
Verder zijn hier een aantal dingen vermeldenswaard:
z-index
eigendom.transformatie-oorsprong
eigenschapswaarde (d.w.z.. transformatie-oorsprong: 50% 50%
) van de lijstitems. Concreet stellen we transformatie-oorsprong: 50% 0
. Op deze manier, wanneer we de items animeren (roteren), wordt hun middelste bovenhoek het centrum van rotatie.Dit zijn de bijbehorende CSS-stijlen:
.grafiekvaardigheden li positie: absoluut; top 100%; links: 0; width: inherit; hoogte: erven; rand: 45px massief; border-top: geen; grens-onder-links radius: 175 px; border-bottom-right-radius: 175px; transformatie-oorsprong: 50% 0; .chart-vaardigheden li: nth-child (1) z-index: 4; randkleur: groen; .chart-vaardigheden li: nth-child (2) z-index: 3; border-colour: firebrick; .chart-vaardigheden li: nth-child (3) z-index: 2; randkleur: staalblauw; .chart-vaardigheden li: nth-child (4) z-index: 1; randkleur: oranje;
Bekijk wat we tot nu toe hebben gemaakt in de volgende visualisatie:
omspant en lijstitemsMomenteel is de enige lijstitem die zichtbaar is de groene (die heeft z-index: 4;
) de anderen zijn eronder.
Voordat we de stappen voor het animeren van onze lijstitems bespreken, nemen we voor elk item het gewenste percentage op (dat wil zeggen: hoeveel van de donut elk zal dekken). Beschouw de volgende tabel:
Taal | Percentage |
---|---|
CSS | 12 |
HTML | 32 |
PHP | 34 |
Python | 22 |
Vervolgens berekenen we hoeveel graden we hebben om elk item te animeren (roteren). Om het exacte aantal graden voor elk item te achterhalen, vermenigvuldigen we het percentage met 180 ° (geen 360 ° omdat we een a gebruiken halve cirkel ringdiagram):
Taal | Percentage | Aantal graden |
---|---|---|
CSS | 12 | 12/100 * 180 = 21,6 |
HTML | 32 | 32/100 * 180 = 57,6 |
PHP | 34 | 34/100 * 180 = 61,2 |
Python | 22 | 22/100 * 180 = 39.6 |
Op dit moment zijn we klaar om de animaties in te stellen. Eerst definiëren we enkele animatiestijlen die over alle items worden gedeeld, door er enkele regels aan toe te voegen .grafiek-vaardigheden li
:
animatie-vulmodus: naar voren; animatie-duur: .4s; animatie-timing-functie: lineair;
Vervolgens definiëren we de unieke animatiestijlen:
.grafiek-vaardigheden li: nth-child (1) z-index: 4; randkleur: groen; animatie-naam: rotate-one; .chart-vaardigheden li: nth-child (2) z-index: 3; border-colour: firebrick; animatie-naam: rotate-two; animatie-vertraging: .4s; .chart-vaardigheden li: nth-child (3) z-index: 2; randkleur: staalblauw; animatie-naam: rotate-three; animatie-vertraging: .8s; .chart-vaardigheden li: nth-child (4) z-index: 1; randkleur: oranje; animatie-naam: rotate-four; animatie-vertraging: 1.2s;
Merk op dat we een vertraging toevoegen aan alle items behalve de eerste. Op deze manier creëren we mooie sequentiële animaties. Wanneer de animatie van het eerste element bijvoorbeeld is voltooid, wordt het tweede element weergegeven, enzovoort.
De volgende stap is om de daadwerkelijke animaties te specificeren:
@keyframes draaien-één 100% transform: rotate (21.6deg); / ** * 12% => 21.6deg * / @keyframes rotate-two 0% transform: rotate (21.6deg); 100% transform: rotate (79.2deg); / ** * 32% => 57.6deg * 57.6 + 21.6 => 79.2deg * / @keyframes rotate-three 0% transform: rotate (79.2deg); 100% transform: roteren (140.4deg); / ** * 34% => 61.2deg * 61.2 + 79.2 => 140.4deg * / @keyframes rotate-four 0% transform: rotate (140.4deg); 100% transformeren: roteren (180 graden); / ** * 22% => 39.6deg * 140.4 + 39.6 => 180deg * /
Voordat we verder gaan, bekijken we kort hoe de animaties werken:
Het eerste element komt uit transformeren: geen
naar transformeren: roteren (21.6deg)
.
Het tweede element is afkomstig van transformeren: roteren (21.6deg)
(start vanaf de laatste positie van het eerste element) tot transformeren: roteren (79.2deg)
(57.6deg + 21.6deg).
Het derde element gaat van transformeren: roteren (79.2deg)
(start vanaf de laatste positie van het tweede element) tot transformeren: roteren (140.4deg)
(61.2deg + 79.2deg).
Het vierde element is afkomstig van transformeren: roteren (140.4deg)
(start vanaf de laatste positie van het derde element) tot transformeren: roteren (180 graden)
(140.4deg + 39.6deg).
Last but not least, om de onderste helft van de grafiek te verbergen, moeten we de volgende regels toevoegen:
.grafiekvaardigheden / * bestaande regels ... * / overflow: verborgen; .chart-skills li / * bestaande regels ... * / transform-style: preserverve-3d; backface-visibility: verborgen;
De overloop verborgen
eigenschapswaarde zorgt ervoor dat alleen de eerste halve cirkel (degene die is gemaakt met de ::voor
pseudo-element) is zichtbaar. Voel je vrij om die eigenschap te verwijderen als je de beginpositie van de lijstitems wilt testen.
De transformatiestijl: behouden-3d
en achtervlak-visibility: hidden
eigenschappen voorkomen flikkeringseffecten die kunnen optreden in verschillende browsers als gevolg van animaties. Als dit probleem nog steeds bestaat in uw browser, kunt u deze oplossingen ook proberen.
De kaart is bijna klaar! Het enige dat overblijft is om de diagramlabels vorm te geven, wat we in de volgende sectie zullen doen.
Hier is de CodePen-demo die het huidige uiterlijk van onze grafiek laat zien:
In dit gedeelte vormen we de kaartlabels.
Met betrekking tot hun positie doen we het volgende:
positie: absoluut
en gebruik de top
en links
eigenschappen om hun gewenste positie in te stellen.transformeren: roteren (79.2deg)
, en dus het gerelateerde label zal hebben transformeren: roteren (-79.2deg)
.Hieronder staan de bijbehorende CSS-stijlen:
.grafiek-vaardigheden overspanning positie: absoluut; font-size: .85rem; .chart-vaardigheden li: nth-child (1) span top: 5px; links: 10px; transformeren: roteren (-21.6deg); .chart-vaardigheden li: nth-child (2) span top: 20px; links: 10px; transformeren: roteren (-79.2deg); .chart-vaardigheden li: nth-child (3) span top: 18px; links: 10px; transformeren: roteren (-140.4deg); .chart-vaardigheden li: nth-child (4) span top: 10px; links: 10px; transformeren: roteren (-180 graden);
Nu we de labels hebben gepositioneerd, is het tijd om ze te animeren. Twee dingen zijn het vermelden waard hier:
animatie-delay
eigenschap om opeenvolgende animaties te maken. Daarnaast voegen we de achtervlak-visibility: hidden
eigenschapswaarde om ervoor te zorgen dat er geen flikkerende effecten zijn als gevolg van animaties.De CSS-regels die betrekking hebben op de animatie van de kaartlabels worden hieronder weergegeven:
.grafiek-vaardigheden overspannen backface-visibility: hidden; animatie: fade-in .4s lineair voorwaarts; .chart-vaardigheden li: nth-child (2) span animation-delay: .4s; .chart-vaardigheden li: nth-child (3) span animation-delay: .8s; .chart-vaardigheden li: nth-child (4) span animation-delay: 1.2s; @keyframes fade-in 0%, 90% dekking: 0; 100% dekking: 1;
Dit is de laatste grafiek:
Over het algemeen werkt de demo goed in alle browsers. Ik wil alleen twee kleine problemen bespreken die verband houden met de border-radius
eigendom.
Ten eerste, als we onze artikelen verschillende kleuren zouden geven, zou de grafiek er ongeveer zo uit kunnen zien:
Let bijvoorbeeld op de bovenste en onderste hoeken van het derde item. Er zijn twee rode lijnen die uit de randkleur van het vierde item komen. We kunnen die regels zien omdat het vierde item een donkerdere randkleur heeft in vergelijking met de derde. Hoewel dit een klein probleem is, is het goed om je ervan bewust te zijn om de juiste kleuren voor je eigen grafieken te kiezen.
Ten tweede, in Safari ziet het diagram er als volgt uit:
Kijk naar de kleine openingen in de tweede en derde items. Als u iets weet over dit probleem, kunt u ons dit laten weten in de onderstaande opmerkingen!
In deze zelfstudie hebben we het proces doorlopen van het maken van een semi-cirkelvormige ringdiagram met pure CSS. Nogmaals, zoals vermeld in de inleiding, zijn er mogelijk krachtigere oplossingen (bijvoorbeeld HTML5 Canvas en SVG) om dit soort dingen te creëren. Als je echter iets eenvoudigs en lichtgewicht wilt bouwen en een uitdaging wilt, is CSS de juiste keuze!