Tegne Bilder med CSS-Gradienter

0
25

Hva jeg mener med “CSS-bilder” er bilder som er opprettet bare ved hjelp av HTML-elementer og CSS. De ser ut som om de var SVGs trukket i Adobe Illustrator, men de ble gjort rett i nettleseren. Noen teknikker jeg har sett brukt er fiksing og triksing med grensen radier, safe skygger, og noen ganger klipp-banen. Du kan finne en rekke gode eksempler hvis du søker daglig css-bilder” på CodePen. Jeg trakk litt på meg selv, inkludert denne Infinity Gauntlet, men i ett element med bare bakgrunner og minimal bruk av andre egenskaper.

La oss ta en titt på hvordan du kan lage CSS-bilder på den måten selv.

Metoden

Forstå står bakgrunn syntaks samt hvordan CSS-gradienter arbeid er praktisk talt alt du trenger for å tegne alt i ett element. Som en anmeldelse, argumentene er som følger:

bakgrunn: <‘background-color’> || <bilde> || <posisjon> [ / <størrelse> ]? || <gjenta> || <vedlegg> || <opprinnelse> || <klipp>;

De kan oppstå i hvilken som helst rekkefølge, bortsett fra at det må være en / mellom posisjon og størrelse. Vi må holde de to argumenter i den rekkefølgen som godt, eller annet vi skal få uventede resultater. Ikke alle av disse trenger å være inkludert, og for dette formålet har vi ikke skal bruke farge, gjenta, vedlegg, opprinnelse, eller klipp argumenter. Dette etterlater oss med bildet, størrelse og posisjon. Siden bakgrunn gjenta standard, men vi må plassere background-repeat: no-repeat; rett under alt i bakgrunnen (hvis enkelte bakgrunn burde være gjenta, kan vi gjenta-linear-gradient() og gjenta-radial-gradient()). I så fall, skjelettet CSS vil være dette:

.bildet {
bakgrunn: <bilde> <posisjon> / <størrelse>;
background-repeat: no-repeat;
}

Vi kan til og med bruke flere sett med bakgrunn argumenter! Derfor, vi kan stable og skille dem med komma som dette:

.bildet {
bakgrunn:
<bilde> <posisjon> / <størrelse>,
<bilde> <posisjon> / <størrelse>,
<bilde> <posisjon> / <størrelse>;
background-repeat: no-repeat;
}

Strukturen ovenfor er grunnlaget for hvordan vi vil tegne bilder—ett per linje form. Husk at gjengivelsen rekkefølgen er motsatt av hvordan absolutt – eller fast stilling elementer som er bestilt. Den første vil dukke opp på toppen i stedet for i bunnen. Med andre ord, sirkler (radial gradienter) nedenfor gjengis fra bunn til topp (blå nederst, rød på toppen).

.sirkler {
bakgrunn:
radial-gradient(7em 7em på 35% 35%, rød 50%, transparent 50%),
radial-gradient(7em 7em på 50% 50%, gull 50%, transparent 50%),
radial-gradient(7em 7em på 65% 65%, blå 50%, transparent 50%);
background-repeat: no-repeat;
bredde: 240px;
høyde: 240px;
}

Tegning

Vi vil bruke Sass (SCSS) for å tegne disse bildene slik at vi kan gjøre bruk av variabler for en fargepalett. Som vil gjøre koden kortere, lettere å lese og endre mørkere eller lysere varianter av farger. Vi kan bruke variabler i normal CSS i stedet og glem Sass, men på grunn av Internet Explorer er mangel på støtte, la oss feste med Sass. For å forklare hvordan dette fungerer, vi skal eksperimentere med former ved hjelp av både lineære og radial graderinger.

Sette Opp en Fargepalett

Våre palett vil bestå av RGB-eller HSL farger. Jeg vil forklare senere hvorfor for å holde fargene i ett av disse formatene. For dette eksempelet, vil vi bruke RGB.

$r: rgb(255,0,0); // hsl(0,100%,50%)
$o: rgb(255,128,0); // hsl(32,100%,50%)

Hva jeg liker å gjøre for å holde koden kort og lett å lese er å bruke et minimum av en bokstav for å representere hver farge (f.eks. $r for rød). Hvis du bruker mørkere eller lysere nyanser av en farge, kan jeg legge til en d før base bokstavene for mørk eller en l for lys. Jeg vil bruke $dr for mørk rød og $lr for lys rød. Hvis det er behov for mer enn to andre nyanser, så jeg vil legge til et tall på slutten for å indikere skyggen nivå. For eksempel, $dr1 for mørk rød, $dr2 for en mørkere rød, og $lr1 for lys rød, $lr2 for en lysere rødt. Slik en palett ville se ut som dette (med mørk første, normal neste, og siste lys):

$dr1: rgb(224,0,0);
$dr2: rgb(192,0,0);
$r: rgb(255,0,0);
$lr1: rgb(255,48,48);
$lr2: rgb(255,92,92);
Innstillingen Skalaen og Lerret

Vi vil bruke dem enheter for bildet som mål, slik at bildet kan lett endres proporsjonalt. Siden 1em er lik elementet er skriftstørrelse, hver enhet av bildet vil bli justert i henhold til dette hvis endres. La oss sette en skriftstørrelse på 10px og sett både bredde og høyde for å 24em. Enheter av 10px er den enkleste å tenke på fordi hvis du mentalt gjøre regnestykket, og du vil umiddelbart få 240 × 240px. Deretter er det bare å se hvor kantene av lerretet er, vil vi bruke en 1px grå ramme rundt.

$r: rgb(255,0,0); // hsl(0,100%,50%)
$o: rgb(255,128,0); // hsl(32,100%,50%)

.bildet {
background-repeat: no-repeat;
font-size: 10px;
disposisjon: 1px solid #aaa;
bredde: 24em;
høyde: 24em;
}

Vær oppmerksom på om du bruker mindre skrift størrelser, men; nettlesere har en minimum skriftstørrelse-innstillingen (for accessiblity grunner). Hvis du vil angi en skriftstørrelse på 4px og minimum er 6px, det vil bli tvunget til 6px.

Videre, du kan aktivere respons kun ved å bruke calc() og viewport enheter. Kanskje vi kan bruke noe sånt som calc(10px + 2vmin) hvis du ønsker det, men la oss holde med 10px for nå.

Tegne Figurer

Den morsomme delen begynner her. For å tegne et kvadrat som er 8 × 8em i midten bruker vi en linear-gradient() med to samme-farget stopper.

.bildet {
bakgrunn:
linear-gradient($r, $r) 50% 50% / 8em 8em;

}

For å forme det til noe mer som et trapes, angi en vinkel på 60deg. På samme tid, la oss legge til $T for transparent for våre palett og deretter plassere både stopper for $r $T på 63% (rett før nederst i høyre hjørne blir kuttet av).

$T: transparent;

.bildet {
bakgrunn:
linear-gradient(60deg,$r 63%, $T 63%) 50% 50% / 8em 8em;

}

Innstilling både stopper på samme verdi som gjør den skrå siden så skarp som den andre. Hvis du ser på det mer nøye om, ser det ut til å bli kornete:

For å rette på dette, må vi justere litt på en av de stopper (ved 1%, eller omtrent slik), slik at kanten er glatt nok. Så, la oss endre $r s 63% til 62%.

Dette vil være et problem med runde kanter, så vel mens du arbeider med radial graderinger, som vi skal se senere. Hvis du ser på denne i en nettleser andre enn Safari, alt ser bra ut, selv om overgangen til en ikke-gjennomsiktig farge i stedet (si oransje). Problemet med overgang til åpen i Safari er at du vil legge merke til en bit av svart fôr på den skrå siden.

Dette er fordi den gjennomsiktige søkeord i Safari er alltid sort transparent, og vi ser noen sort som et resultat. Jeg virkelig ønsker Apple ville løse dette, men de vil aldri. For tiden, la oss legge til en ny $redT variabel for rød transparent under $r. Skrap $T vi brukte for gjennomsiktig som vi vil ikke lenger bruker det.

$rT: rgba(255,0,0,0); // hsla(0,100%,50%,0)

Så la oss skifte gjennomsiktig med $redT. Dette tar vare på vår Safari problem!

.bildet {
bakgrunn:
linear-gradient(60deg,$r 62%, $rT 63%) 50% 50% / 8em 8em;

}

Hvis du har vært lurer på hvorfor vi ikke brukte hex farger, Internet Explorer og Kant ikke støtter #rgba og #rrggbbaa notasjoner (jepp, hex har hatt en alfakanal siden slutten av 2016 hvis du visste aldri), og vi vil at dette skal fungere som kryss-nettleser som mulig. Vi ønsker også å bo i tråd med vårt valg av farge-format.

La oss nå flytte form vertikalt til 20% og trekke en oransje sirkel av samme dimensjoner. Også, legg til en annen variabel for sin gjennomsiktig versjon. For den jevne kanten, setter du inn et 1% gapet mellom det solide og transparente appelsiner.

$oT: rgba(255,128,0,0); // hsla(32,100%,50%,0)

.bildet {
bakgrunn:
linear-gradient(60deg,$r 62%, $rT 63%) 50% 20% / 8em 8em,
radial-gradient(8em 8em på 50% 80%, $o 49%, $oT 50%);

}

For å opprettholde konsistens med vår størrelse, den andre fargen stopp bør være på 50% i stedet for 100%.

Lokalisering Figurer

Veien graderinger er plassert basert på om enheten er fast eller en prosentandel. Anta at vi slå både av fargeovergangane i firkanter og forsøke å plassere dem helt på tvers av div horisontalt.

.bildet {
bakgrunn:
linear-gradient($r, $r) 24em 20% / 8em 8em,
linear-gradient($o, $o) 100% 80% / 8em 8em;

}

Den røde firkanten ender opp helt av lerret (uthevet), og høyre side av orange square berører den andre siden. Ved hjelp av faste enheter er som å plassere absolutt posisjonerte elementer eller tegne figurer i HTML5 canvas. Det er sant i den forstand at point of origin er øverst til venstre. Når du bruker prosent, og angi bakgrunn, størrelse, div får “falsk padding” på halvparten av bakgrunnen størrelse. På samme tid, bakgrunnen er point of origin er sentrert (må ikke forveksles med background-origin, som det gjelder boksen hjørner).

Nå, hvis vi slått disse gradienter i radial fargeovergangar som sirkler og anvendte den samme x-stillinger 24em og 100%, som begge ender opp på den andre siden kuttet i to. Dette er fordi poenget med opprinnelse er alltid i sentrum hvis vi skriver bakgrunnen som så:

.bildet {
bakgrunn:
radial-gradient(8em 8em på 24em 20%, $r 49%, $rT-50%),
radial-gradient(8em 8em på 100% 80%, $o 49%, $oT 50%);

}

Hvis vi skrev om bakgrunnen slik at posisjon og størrelse er etter gradient og brukt 100% 100% på midten, vil de bli plassert som den lineære graderinger. Den røde ender opp utenfor, og den oransje berører den høyre kanten. Den “falske” padding “” oppstår igjen med oransje.

.bildet {
bakgrunn:
radial-gradient(100% 100% ved center, $r 49%, $rT 50%) 24em 20% / 8em 8em,
radial-gradient(100% 100% ved center, $o 49%, $oT 50%) 100% 80% / 8em 8em;

}

Det er ikke én riktig måte å plassere figurer, men å plassere den som en absolutt eller fast plassert HTML-element, bruk faste enheter. Hvis du er i behov av en rask måte å plassere en form (ved hjelp av posisjon / størrelse parametere) i dead center, 50% er det beste alternativet som formen opprinnelse vil være i midten. Bruk 100% hvis det skal berøre svært høyre side.

Dimensjonering Figurer

Dimensjonering i CSS bakgrunn fungerer som vi forventer, men det er fortsatt påvirket av den typen enhet som brukes for stilling—fast eller prosent. Hvis vi tar våre ruter på nytt og endre sin bredde og 10em, den røde utvides til høyre, og den oransje utvider seg sidelengs.

.bildet {
bakgrunn:
linear-gradient($r, $r) 12em 20% / 10em 8em,
linear-gradient($o, $o) 50% 80% / 10em 8em;

}

Hvis vi brukte em-enheter for y-posisjon, formen vil vokse nedover eller krympe oppover etter at du har endret høyde. Hvis vi bruker en prosent, så vil det ekspandere både vertikale retninger.

For en stund siden, så vi på to måter å tegne sirkler med radial graderinger. Den første måten er å angi bredden og høyden mellom ( og til og da er stillingen etter at:

.bildet {
bakgrunn:
radial-gradient(8em 8em på 50% 50%, $r 49%, $rT 50%);

}

Den andre måten er å bruke 100% 100% i midten og deretter gi den posisjon og størrelse:

.bildet {
bakgrunn:
radial-gradient(100% 100% 50% 50%, $r 49%, $rT 50%) 50% 50% / 8em 8em;

}

Disse metodene både tegne sirkler, men vil resultere i forskjellige utganger fordi:

  1. Den første måten opptar hele div-siden det ikke var noen reell bakgrunn posisjon eller størrelse.
  2. Gir en reell posisjon og størrelse til den andre setter det en markeringsrammen. Følgelig, det vil oppføre seg akkurat som en lineær gradient form.

Anta at vi erstattet $rT med $o. Du vil se at det oransje lyset vil dekke det var hvitt eller former under det (hvis vi lagt til noen) for den første måten. Ved hjelp av den andre måten, vil du enkelt legge merke markeringsrammen avslørt av den oransje.

I tillegg er formålet med 100% 100% i stedet for å bruke sirkel eller ellipse er å la sirkel for å okkupere hele markeringsrammen. Det gir oss full kontroll over sine dimensjoner. På den måten, det vil forbli den samme hvis du endrer 50% 50% stilling til noe annet. Hvis du bruker en av de to nøkkelord kanten av sirkelen, stopper bare om lag 71% av veien når sentrert og blir mer forvrengt hvis posisjonen er justert. For eksempel, her er hva som skjer når vi endrer x-posisjon til 0 for sirkel og ellipse:

I det lange løp, kan du reimagine syntaksen som radial-gradient(bredde høyde på x-y) eller radial-gradient(100% 100% på x-i-bounding-boksen y-i-bounding-boksen) x-y / bredde høyde. Hvis du trekker bare en sirkel eller oval, kan du forenkle koden med den første måten. Hvis tegning del av en sirkel eller en del av en ring, og deretter den andre veien kommer inn i bildet. Det vil være mange programmer som i eksemplene vi skal lage neste.

Eksempler

Klar til å tegne noe for ekte nå? Vi vil gå gjennom tre eksempler trinn for trinn. De to første vil være statisk—en med massevis av halv-sirkler og andre som arbeider med noen avrundede rektangler. Det siste eksemplet vil være mindre, men fokusert på animasjon.

Statisk Bilde

Dette parasoll vil bli vår første statisk bilde:

Vi kommer til å bruke en palett med rødt ($h og $rT), hvit ($w, $wT), orange ($u og $oT), og mørk oransje ($gjøre $doT).

$r: rgb(255,40,40);
$rT: rgba(255,40,40,0);

$w: rgb(240,240,240);
$wT: rgba(240,240,240,0);

$o: rgb(255,180,70);
$oT: rgba(255,180,70,0);

$gjøre: rgb(232,144,0);
$doT: rgba(232,144,0,0);

La oss sette opp vår tegningen av 30 × 29em.

.parasoll {
// bakgrunn til å gå her
background-repeat: no-repeat;
font-size: 10px;
disposisjon: 1px solid #aaa;
bredde: 30em;
høyde: 29em;
}

Over background-repeat, vil vi begynne å tegne deler av en parasoll. Først, legg til fargeovergangane som utgjør polet (siden verken overlapper hverandre, nederst til øverst rekkefølgen spiller ingen rolle på dette punktet):

.parasoll {
bakgrunn:
// 1
radial-gradient(200% 200% 100% 100%, $gjøre 49%, $doT 50%) 14em 0 / 1em 1em,
radial-gradient(200% 200% 0% 100%, $o 49%, $oT 50%) 15em 0 / 1em 1em,
// 2
linear-gradient(90deg, $gjøre 50%, $o 50%) 14em 1em / 2em 25em,
// 3
radial-gradient(100% 200% 50% 0, $oT 0.95 em, $o 1em, $o 1.95 em, $gjøre 2em, $gjøre 2.95 em, $doT 3em) 14em 26em / 6em 3em,
// 4
radial-gradient(200% 200% 100% 100%, $o 49%, $oT 50%) 18em 25em / 1em 1em,
radial-gradient(200% 200% 0% 100%, $gjøre 49%, $doT 50%) 19em 25em / 1em 1em;

}

  1. Å trekke hver side av toppen av stangen, har vi brukt deler av en sirkel som er 1 × 1em. For å gjøre dem okkupere deres byksende bokser, har vi brukt sirkler som er dobbelt størrelse (200% 200%) er plassert nederst til høyre og nederst til venstre. Vi kan også bruke søkeord par som høyre eller venstre nederst, men det er kortere å bruke prosent ekvivalenter. Merknad 1% avvik mellom de stopper for å sikre glatthet.
  2. For den lange delen, vi brukte en lang rektangel med en brå mørk orange-orange. Det er ikke behov for en brøk lille gapet siden vi ikke arbeider med en kurve eller skrå.
  3. Denne delen av stolpen er litt vanskeligere å trekke enn de andre fordi vi har for å opprettholde 2em diameter. For å trekke dette arc, bruker vi en boks med 6 × 3em slik at det er en 2em plass mellom endene som også 2em. Deretter bruker vi en radial gradient i sentrum toppen der hvert stopp oppstår 1em hver (og spredt med 0,05 em for glatthet).
  4. De to siste er akkurat som den første, bortsett fra at de er plassert på den høyre enden av buen slik at de passer sømløst. Også, farger bytte steder.

Så over tidligere graderinger, legge til følgende fra bunnen til toppen for å trekke toppen av paraply uten spisse endene:

.parasoll {
bakgrunn:
radial-gradient(100% 200% 50% 100%, $r 50%, $rT 50.25%) 50% 1.5 em / 9em 12em,
radial-gradient(100% 200% 50% 100%, $w 50%, $wT 50.25%) 50% 1.5 em / 21em 12em,
radial-gradient(100% 200% 50% 100%, $r 50%, $rT 50.25%) 50% 1.5 em / 30em 12em,

}

For å trekke en halv sirkler som utgjør denne delen, vi har brukt en gradient størrelse på 100% 200%, noe som gjør hver diameter passe inn sin bakgrunn bredde, men har to ganger høyden og sentrert i bunnen. Ved å bestille dem nederst til øverst, slik at de største er på bunnen og minste er på topp, vi får kurvene vi ønsker.

Som vår stabel av fall vokser seg høyere, det vil bli vanskelig etter en stund for å identifisere hvilken bakgrunn eller gruppe av bakgrunner, tilsvarer det en del av bildet. Så for å gjøre det enklere å feste dem ned, kan vi dele dem inn i grupper ledet av en kommentar som beskriver hva hver gruppe er for. Akkurat nå, har vi delt de stakk i grupper for toppen av en parasoll og polen.

.parasoll {
bakgrunn:
/* toppen */
radial-gradient(100% 200% 50% 100%, $r 50%, $rT 50.25%) 50% 1.5 em / 9em 12em,
radial-gradient(100% 200% 50% 100%, $w 50%, $wT 50.25%) 50% 1.5 em / 21em 12em,
radial-gradient(100% 200% 50% 100%, $r 50%, $rT 50.25%) 50% 1.5 em / 30em 12em,

/* polen */
radial-gradient(200% 200% 100% 100%, $gjøre 49%, $doT 50%) 14em 0 / 1em 1em,
radial-gradient(200% 200% 0% 100%, $o 49%, $oT 50%) 15em 0 / 1em 1em,
linear-gradient(90deg, $gjøre 50%, $o 50%) 14em 1em / 2em 25em,
radial-gradient(100% 200% 50% 0, $oT 0.95 em, $o 1em, $o 1.95 em, $gjøre 2em, $gjøre 2.95 em, $doT 3em) 14em 26em / 6em 3em,
radial-gradient(200% 200% 100% 100%, $o 49%, $oT 50%) 18em 25em / 1em 1em,
radial-gradient(200% 200% 0% 100%, $gjøre 49%, $doT 50%) 19em 25em / 1em 1em;

}

Deretter, i mellom toppen og nordpolen, vil vi legge til neste del av bakgrunner til å gjengi den spisse ender. For å finne ut bredder på hvert segment, vi må få avstanden mellom hvert punkt der røde og hvite møte. De må alle legge opp til 30em.

Starter med hvit og smaleste røde halve sirkler, vi trekke den røde bredden av 9em fra den hvite bredden av 21em og dele resultatet med 2 for å få bredden av to hvite segmenter (punkt “b” i figuren). Så, ville resultatet bli 6em ( b = (21 – 9) / 2 = 6 ). Deretter midt røde segmentet ville være 9em (21 – (6 + 6) = 9). Hva vi har igjen nå er det ytre rød segmenter (punkt “a” i figuren). Minus summen av hva vi har nå er fra bredden av større rød halv sirkel og del som følge av 2. Det ville være å gjøre verdien av punkt a: (30em – (6 + 6 + 9)) / 2 = 4.5 em.

.parasoll {
bakgrunn:

/* spisse endene */
radial-gradient() 0 13.5 em / 4.5 em 3em,
radial-gradient() 4.5 em 13.5 em / 6em 3em,
radial-gradient() 50% 13.5 em / 9em 3em,
radial-gradient() 19.5 em 13.5 em / 6em 3em,
radial-gradient() 25.5 em 13.5 em / 4.5 em 3em,

}

For å trekke en halv sirkler som ligner på hvordan vi trakk den øverste delen, starter vi med den gjennomsiktige motstykke av farge for hver form slik at de ligner arc broer. Vi vil også legge til en ekstra 5% til hver gradient bredde (ikke bakgrunnen boksen bredde) slik at hvert punkt dannet av tilstøtende bakgrunn vil ikke altfor skarp og tynn.

.parasoll {
bakgrunn:

/* spisse endene */
radial-gradient(105% 200% 50% 100%, $rT 49%, $r 50%) 0 13.5 em / 4.5 em 3em,
radial-gradient(105% 200% 50% 100%, $wT 49%, $w 50%) 4.5 em 13.5 em / 6em 3em,
radial-gradient(105% 200% 50% 100%, $rT 49%, $r 50%) 50% 13.5 em / 9em 3em,
radial-gradient(105% 200% 50% 100%, $wT 49%, $w 50%) 19.5 em 13.5 em / 6em 3em,
radial-gradient(105% 200% 50% 100%, $rT 49%, $r 50%) 25.5 em 13.5 em / 4.5 em 3em,

}

Til slutt, vil du ikke lenger trenger det 1px solid #aaa disposisjon. Våre parasoll er komplett!

Se Penn Parasoll av Jon Kantner (@jkantner) på CodePen.

Noe Med Avrundede Rektangler

Denne neste eksempel vil være en gamle iPhone-modell i som det er flere detaljer enn de nyere modellene. Tingen om dette er de to avrundede rektangler, som er utenfor og midt på hjem-knappen.

Paletten består av sort ($bk og $bkT) for hjem-knappen kanten, mørk grå ($dg og$dgT) for kroppen, grå ($g $gT) for kamera og høyttaler, lys grå ($lg og $lgT) for utenfor grensen, blå ($bl $blT) for kameralinsen, og en veldig mørk lilla ($p og $pT) for skjermen.

$bk: rgb(10,10,10);
$bkT: rgba(10,10,10,0);

$dg: rgb(50,50,50);
$dgT: rgba(50,50,50,0);

$g: rgb(70,70,70);
$gT: rgba(70,70,70,0);

$lg: rgb(120,120,120);
$lgT: rgba(120,120,120,0);

$bl: rgb(20,20,120);
$blT: rgba(20,20,120,0);

$p: rgb(25,20,25);
$pT: rgba(25,20,25,0);

La oss sette opp vår lerret på 20 × 40em og bruke samme skriftstørrelse vi brukte for parasoll, 10px:

.iphone {
// bakgrunn går her
background-repeat: no-repeat;
font-size: 10px;
disposisjon: 1px solid #aaa;
bredde: 20em;
høyde: 40em;
}

Før vi begynner å tegne vår første avrundet rektangel, vi må tenke på våre border-radius, noe som vil være 2em. Også vi ønsker å sette av litt plass til venstre for låsehendelen og volum-knappene, som vil være 0.25 em. På grunn av dette, rektangel vil være 19.75 × 40em. Vurderer 2em border-radius, vi trenger to lineær graderinger krysser hverandre. Man må ha en bredde av 15,75 em (19.75 em – 2 × 2), og den andre må ha en høyde på 36em (40em – 2 × 2). Plasser første 2.25 em fra venstre, og deretter den andre 0.25 em fra venstre og 2em fra toppen.

.iphone {
bakgrunn:
/* kroppen */
linear-gradient() 2.25 em-0 / 15.75 em 40em,
linear-gradient() 0.25 em 2em / 19.75 em 36em;

}

Siden lys grå grensen vil være 0,5 til em tykk, la oss gjøre hver gradient stoppe umiddelbart bytte fra lys grå ($lg) til mørk grå ($dg) og vice versa på 0,5 em og 0,5 em før slutten (40em – 0.5 = 39.5 em for første gradient, 19.75 em – 0.5 = 19.25 em for den andre). Angi en vinkel på 90deg for andre å gjøre det gå vannrett.

.iphone {
bakgrunn:
/* kroppen */
linear-gradient($lg 0.5 em, $dg 0.5 em, $dg 39.5 em, $lg 39.5 em) 2.25 em-0 / 15.75 em 40em,
linear-gradient(90deg, $lg 0.5 em, $dg 0.5 em, $dg 19.25 em, $lg 19.25 em) 0.25 em 2em / 19.75 em 36em;

}

I hver rute hjørne, som vist ved den oransje boksen i figuren, vil vi plassere de avrundede kantene. For å lage disse figurene, vi bruker radial graderinger som er det dobbelte av størrelsen av deres byksende bokser og plassert i hvert hjørne. Sett dem over kroppen bakgrunn.

.iphone {
bakgrunn:
/* hjørner */
radial-gradient(200% 200% 100% 100%, $dg 1.45 em, $lg 1.5 em, $lg 50%, $lgT 51%) 0.25 em-0 / 2em 2em,
radial-gradient(200% 200% 0% 100%, $dg 1.45 em, $lg 1.5 em, $lg 50%, $lgT 51%) 18em 0 / 2em 2em,
radial-gradient(200% 200% 100% 0%, $dg 1.45 em, $lg 1.5 em, $lg 50%, $lgT 51%) 0.25 em 38em / 2em 2em,
radial-gradient(200% 200% 0% 0%, $dg 1.45 em, $lg 1.5 em, $lg 50%, $lgT 51%) 18em 38em / 2em 2em,

}

For å få 0.5 em-tykke lys grå ender, tenke på hvor gradient starter, og deretter gjøre regnestykket. Fordi lys grå er på slutten, vi trekke fra 0.5 em fra 2em til riktig sted først, og stopp. For den jevne vi ta av en liten bit fra den første 1.5 em og legg til 1% til den andre 50%, slik at de runde kantene blanding med flatskjerm kantene.

Hvis vi nå forstørret bilde ved å endre skriftstørrelsen til 40px eller mer, vi merker sømmene mellom avrundet og flatskjerm kanter (sirklet i oransje):

Siden de ser ut til å være så liten, kan vi lett patch dem ved å gå tilbake til kroppen bakgrunn og litt endring gradient stopper så lenge alt ser fortsatt rett når du endrer skriftstørrelse tilbake til 10px.

.iphone {
bakgrunn:
/* kroppen */
linear-gradient($lg 0.5 em, $dg 0.55 em, $dg 39.5 em, $lg 39.55 em) 2.25 em-0 / 15.75 em 40em,
linear-gradient(90deg, $lg 0.5 em, $dg 0.55 em, $dg 19.175 em, $lg 19.25 em) 0.25 em 2em / 19.75 em 36em;

}

Så i en lineær gradient, vil vi legge til låsehendelen og volum-knappene for å fylle 0,25 em-plass på venstre side. Hvis en 1px plass kommer det til å skje mellom knappene og kroppen, kan vi legge til en liten blø på 0,05 em i bakgrunnen bredde (noe som gjør det til 0.3 em) slik at den ikke kan stikke ut i den mørke grå.

.iphone {
bakgrunn:
/* volume-knapper */
linear-gradient($lgT 5em, $lg 5em, $lg 7.5 em, $lgT 7.5 em, $lgT 9.5 em, $lg 9.5 em, $lg 11em, $lgT 11em, $lgT 13em, $lg 13em, $lg 14.5 em, $lgT 14.5 em) 0 0 / 0.3 em 100%,

}

Det ser ut som vi har brukt tre lys grå-til-lys grå graderinger, men siden det var mulig, bare man var nødvendig. Det er bare masse plutselige overganger mellom transparente og opake lyse gråtoner kjører nedover.

Neste, la oss legge til kanten av hjem-knappen, så vel som flate kantene av plassen inne i den. Nå plassen inne hjem-knappen vil bli 1,5 × 1.5 em og følger i utgangspunktet de samme prosedyre som kroppen: to kryssende lineær graderinger og radials å fylle hjørnene. Å plassere dem horisontalt i midten, calc() kommer i hendig. 50% + 0.125 em vil være uttrykk; hvis vi sentrert bare telefonen på kroppen, vil det være 0.125 em mellomrom på hver side. Derfor flytter vi det 0.125 em-mer til høyre. Den samme x-posisjonering vil gjelde i de øvre to bakgrunner.

.iphone {
bakgrunn:
/* hjem-knappen */
linear-gradient() calc(50% + 0.125 em) 36.5 em / 0.5 em 1.5 em,
linear-gradient() calc(50% + 0.125 em) 37em / 1.5 em-0.5 em,
radial-gradient(3em 3em på calc(50% + 0.125 em) 37.25 em, $bkT 1.25 em, $bk 1.3 em, $bk 49%, $bkT 50%),

}

Ligner på hvordan vi skygget lineær gradient deler av telefonen på kroppen, stopper vil begynne og slutte med lys grå, men med gjennomsiktig i midten. Merker vi forlot 0.05 em mellomrom mellom hver grå-til-transparent-overgang (og vice versa). Akkurat som hjørnene av kroppen, dette for å sikre blanding mellom en runde hjørnet og flatskjerm slutten på innsiden.

.iphone {
bakgrunn:
/* hjem-knappen */
linear-gradient($lg 0.15 em, $lgT 0.2 em, $lgT 1.35 em, $lg 1.35 em) calc(50% + 0.125 em) 36.5 em / 0.5 em 1.5 em,
linear-gradient(90deg, $lg 0.15 em, $lgT 0.2 em, $lgT 1.3 em, $lg 1.35 em) calc(50% + 0.125 em) 37em / 1.5 em-0.5 em,
radial-gradient(3em 3em på calc(50% + 0.125 em) 37.25 em, $bkT 1.25 em, $bk 1.3 em, $bk 49%, $bkT 50%),

}

By the way, fordi den skisserer vil være så liten som du har sett tidligere, kan vi bedre se hva vi gjør ved å øke skriftstørrelsen til minst 20 piksler. Det er som å bruke zoom-verktøyet i bildet redigering programvare.

Nå for å få hjørnene av den grå firkanten for å nøyaktig hvor de skal være, la oss fokusere på den x-stilling først. Vi starter med calc(50% + 0.125 em), så vi legg til eller trekk fra bredden på hver brikke, eller skal jeg si plassen border-radius. Disse bakgrunnene som vil gå over tre siste.

.iphone {
bakgrunn:
/* hjem-knappen */
radial-gradient(200% 200% 100% 100%, $lgT 0.3 em, $lg 0.35 em, $lg 0.48 em, $lgT 0.5 em) calc(50% + 0.125 em – 0.5 em) 36.5 em / 0.5 em-0.5 em,
radial-gradient(200% 200% 0% 100%, $lgT 0.3 em, $lg 0.35 em, $lg 0.48 em, $lgT 0.5 em) calc(50% + 0.125 em + 0.5 em) 36.5 em / 0.5 em-0.5 em,
radial-gradient(200% 200% 100% 0%, $lgT 0.3 em, $lg 0.35 em, $lg 0.48 em, $lgT 0.5 em) calc(50% + 0.125 em – 0.5 em) 37.5 em / 0.5 em-0.5 em,
radial-gradient(200% 200% 0% 0%, $lgT 0.3 em, $lg 0.35 em, $lg 0.48 em, $lgT 0.5 em) calc(50% + 0.125 em + 0.5 em) 37.5 em / 0.5 em-0.5 em,

}

Da vil skjermen bli en 17.25 × 30em rektangel. Akkurat som deler av hjem-knappen, vil vi horisontalt center det å bruke calc(50% + 0.125 em). Fra toppen, det vil være 5em.

.iphone {
bakgrunn:
/* tv */
linear-gradient($p, $p) calc(50% + 0.125 em) 5em / 17.25 em 30em,

}

Til slutt, vil vi legge til kamera og høyttaler. Kameraet er en grei 1 × 1 blå-grå radial med ingen fancy beregninger. Ren-grå høyttaleren selv vil være litt mer involvert. Det vil være et 5 × 1em rektangel og har en 0,5 em-border-radius. For å tegne det, er vi første tegn et rektangel med den første 4ems av bredde-og sentrere det med calc(50% + 0.125 em). Deretter bruker vi 0.5 × 1em halve sirkler der gradient stillingene er 100% 50% 0% 50%. Den beste måten å plassere disse på venstre og høyre av rektangelet er å bruke noen nye calc() uttrykk. For det igjen, vil vi trekke fra halvparten av rektangelet halv bredde halv sirkel bredde fra kroppen center (50% + 0.125 em – 2em – 0.25 em). Høyre vil følge det samme mønsteret, men med tillegg, så 50% + 0.125 em + 2em + 0.25 em.

.iphone {
bakgrunn:
/* kamera */
radial-gradient(1em 1em på 6.25 em 2.5 em, $bl 0.2 em, $g 0.21 em, $g 49%, $gT 50%),
/* høyttaler */
radial-gradient(200% 100% 100% 50%, $g 49%, $gT 50%) calc(50% + 0.125 em – 2em – 0.25 em) 2em / 0.5 em 1em,
radial-gradient(200% 100% 0% 50%, $g 49%, $gT 50%) calc(50% + 0.125 em + 2em + 0.25 em) 2em / 0.5 em 1em,
linear-gradient($g, $g), calc(50% + 0.125 em) 2em / 4em 1em,

}

Fjerne den grå ramme rundt div, og iPhone er komplett!

Se Penn iPhone av Jon Kantner (@jkantner) på CodePen.

Animerte Bilder

Du tenker kanskje at du kunne bruke background-position å animere disse slags bilder, men du kan bare gjøre så mye. For eksempel, det er umulig å animere rotasjon av en individuell bakgrunn av seg selv. Faktisk, background-position animasjoner ikke vanligvis utfører, samt forvandle animasjoner, slik at jeg ikke anbefaler det.

For å animere noen del av et bilde slik vi ønsker, kan vi la det :før eller etter pseudo-elementene være ansvarlig for den del. Hvis vi trenger flere valg, så vi kan gå tilbake til flere barn divs, men ikke trenger en for hver lille detalj. For vår animerte bildet eksempel skal vi lage denne animerte radar:

Vi trekker den statiske delen først, noe som er alt bortsett fra den grå ramme og roterende hånd. Før det, la oss levere våre paletten (merk: Vi trenger ikke en $dgnT for $dgn) og base-koden.

$gn: rgb(0,192,0);
$gnT: rgba(0,192,0,0);
$dgn: rgb(0,48,0);
$gy: rgb(128,128,128);
$gyT: rgba(128,128,128,0);
$bk: rgb(0,0,0);
$bkT: rgba(0,0,0,0);

.radar {
background-repeat: no-repeat;
font-size: 10px;
disposisjon: 1px solid #aaa;
bredde: 20em;
høyde: 20em;
}

Siden dette bildet er kommer til å være helt runde, kan vi trygt kan bruke en border-radius av 50%. Så, vi kan bruke et gjentakende radial gradient å trekke ringer—ca 1/3 måte fra hverandre.

.radar {
bakgrunn:
/* ringer */
gjenta-radial-gradient($dgn, $dgn 2.96 em, $gn 3em, $gn 3.26 em, $dgn 3.3 em);
background-repeat: no-repeat;
border-radius: 50%;

}

Vær også oppmerksom på at ekstra $dgn ved start. For å gjenta graderinger til start, slutt, og loop som forventet, vi trenger å angi start-farge på 0 (eller uten 0).

I motsetning til forrige eksempel, kan vi ikke bruke calc() for å sentrere linjer fordi Internet Explorer vil gjøre det hele klønete når vi bruker en pseudo-element senere. Å trekke fire 0.4 em linjer som krysser hverandre i midten, vet at halvparten av linjen skal være halvparten av div på 10em. Så, vi trekke fra og legge til halvparten av 0.4 (0.4 / 2 = 0.2) på hver side. Med andre ord, de venstre-grønne bør være 9.8 em, og rett skal være 10.2 em. For 45deg diagonaler om, må vi multiplisere 10em med kvadratroten av 2 til å få sine center (10 × √2 ≈ 14.14). Det er lengden på den lengste siden av en 10em høyre trekant. Som et resultat, siden av hver diagonal ville være omtrent på 13.94 og 14.34 em.

.radar {
bakgrunn:
/* linjer */
linear-gradient($gnT 9.8 em, $gn 9.8 em, $gn 10.2 em, $gnT 10.2 em),
linear-gradient(45deg,$gnT 13.94 em, $gn 13.98 em, $gn 14.3 em, $gnT 14.34 em),
linear-gradient(90deg,$gnT 9.8 em, $gn 9.8 em, $gn 10.2 em, $gnT 10.2 em),
linear-gradient(-45deg,$gnT 13.94 em, $gn 13.98 em, $gn 14.3 em, $gnT 14.34 em),

}

For å hindre at pikselering av diagonalene, dro vi en liten 0.04 em gap mellom grønn og transparent grønn. Så, for å skape litt lys, legge til denne gjennomsiktig-til-svart radial gradient:

.radar {
bakgrunn:
/* belysning */
radial-gradient(100% 100%, $bkT, $bk 9.9 em,$bkT 10em),

}

Som fullfører den statiske delen av radar. Nå kan vi trekke den grå ramme og hånd i en annen bakgrunn stabelen under :før og legge til animasjon. Det er en grunn til at vi ikke tok med i bildet her. Fordi hånd beholderen skal passe hele div, ønsker vi ikke det å overlappe ramme.

Denne pseudo-element skal fylle rommet, og for å sikre at den holder seg på det, la oss absolutt posisjon. Vi vil bruke den samme grensen radius slik at det holder seg rundt mens animert i Safari.

.radar {

position: relative;
og:før {
background-repeat: no-repeat;
border-radius: 50%;
innhold: “”;
position: absolute;
bredde: 100%;
høyde: 100%;
}
}

Så, for å tegne hånd, gjør vi det halve størrelsen av dens beholder og oppbevar den på det øverste venstre hjørnet. Til slutt, på toppen av det, kan vi trekke den rammen.

.radar {

og:før {
animasjon: scan 5s lineær uendelig;
bakgrunn:
/* ramme */
radial-gradient($gyT 9.20 em, $gy 9.25 em, $gy 10em, $gyT 10.05 em),
/* del */
linear-gradient(45deg, $gnT 6em, $gn) 0 0 / 50% 50%;

}
}

@keyframes scan {
fra {
forvandle: rotere(0);
}
{
forvandle: rotere(1turn);
}
}

Nå er vår lille gadgeten er komplett!

Se Penn Radar av Jon Kantner (@jkantner) på CodePen.

Fordeler (Pluss en Ulempe)

Denne tilnærmingen tegning av CSS bilder har flere fordeler. Første, HTML vil være svært lett i forhold til en rastrerte bildet. For det andre, det er flott for å håndtere bilder som er umulig å trekke godt uten å bruke eksperimentelle egenskaper og Api-er som ikke kan være mye støtte.

Det er ikke å si at denne metoden er bedre enn å bruke et overordnet element nestede med barn for figurene. Det er en ulempe om. Du må gi opp med å bli i stand til å fremheve enkelte figurer ved hjelp av nettleseren dev verktøy. Du trenger for å kommentere og uncomment en bakgrunn for å identifisere hvilke det er. Så lenge du gruppen og merke hver del av bakgrunner, kan du finne det aktuelle bakgrunn raskere.

Konklusjon

I et nøtteskall, metode for tegning av CSS bildene vi har dekket i dette innlegget gir oss muligheten til å:

  1. Sett opp en palett består av variabler for farger.
  2. Deaktiver bakgrunnen gjenta, angi på en skala med font-size, og et lerret bredde og høyde i em-enheter for mål-element.
  3. Bruk en midlertidig disposisjon for å vise kantene som vi jobber.
  4. Draw hver form fra bunn til topp, fordi bakgrunner er gjengitt i den rekkefølgen. Bakgrunn syntaks for hver form følger bildet posisjon / størrelse (med eller uten posisjon og størrelse).

Det er mye å tenke utenfor den boksen som skjer, samt eksperimentering for å få ønsket resultat. De tre eksemplene vi har opprettet var akkurat nok til å demonstrere konseptet. Vi har sett på hvordan vi for hver bakgrunnen, tegning deler av sirkler, avrundede rektangler, og litt justering gradient stopper for jevn kantene. For å lære mer, føle seg fri til å dissekere og studere andre eksempler jeg har gjort i denne CodePen samling!

Jetpack WordPress plugin går på dette nettstedet, slår ikke bare relaterte innlegg nedenfor, men sikkerhet og sikkerhetskopiering, Markdown-støtte, søk nettstedet, kommentar form, sosiale nettverk-tilkoblinger, og mer!