Brug af sprites i CSS

Sprites i CSS er en gammel teknik, faktisk helt tilbage fra CSS 1, men selvom vi i dag har icon-fonts og SVG’er så er der stadig situationer hvor et raster billede (PNG/JPG) måske er den bedste løsning og så er det med at finde denne gamle klassiker frem og holde sine HTTP requests nede på et fornuftigt antal.

Hvad er sprites overhovedet?

Kort fortalt er sprites blot et sæt af sammensatte billeder, hvor man så bruger et udsnit af billedet for at tegne en bestemt del. Man bruger sprites på en side hvor der er mange små billeder. Hvert billede man har på sin side laver nemlig et HTTP request, så ved at samle billederne i et enkelt billede, så sparer man requests og gør potentielt sin side hurtigere.

Et eksempel på en sprite kunne være disse 4 browser ikoner som jeg her har samlet i en png:

Sprites eksempel med 4 browser ikoner

Ved at sætte de 4 browser ikoner får jeg 2 requests i stedet for 5 på mine eksempel sider:

For sjov skyld så prøvede jeg at sætte network throttling til 50 Kbps og fik en load tid der var ca. 0.7s hurtigere på siden med spriten:
Request og loadtime forskellen mellem sprites og enkelte ikoner

Hvordan bruger man så sprites?

For at lave spriten brugte jeg blot Sketch til at ligge ikonerne ved siden af hinanden og gemte det i en browser-icons.png fil. Man behøver ikke sætte lidt luft ind mellem sine ikoner i spriten, bare man sørger for at man har angivet den rigtige width og height i sin CSS.

Inden omlægningen til sprite, havde CSS for hvert enkelt icon set sådan her ud:

.chrome {
   background: transparent url('chrome.png') no-repeat;
   height: 64px;
   width: 64px; 
}
.safari {
   background: transparent url('safari.png') no-repeat;
   height: 64px;
   width: 64px; 
}
...osv.

Men til vores sprite skal vi angive samme billede som background, og så skal vi bruge en anden CSS attribut, background-position, til at rykke billedet til den ønskede position. Nedenstående illustration viser hvordan background-position fungerer:

sprite-positionCreated with Sketch – for css-siden.dkbackground-position: -64px -64pxbackground-position: 0 0(0, 0)XY64px64pxXY(-64px, -64px)

Det grønne område er det der vil blive vist, og det er bestemt udfra den height og width man har angivet (Jeg har her angivet 64px til begge). Så hvis man ønsker at bruge opera ikonet, så sættes man background-position: -64px -64px.

CSS’en til at bruge spriten for de forskellige browser ikoner bliver således til:

.browser-icon {
   background: transparent url('browser-icons.png') no-repeat;
   height: 64px;
   width: 64px; 
}
.browser-chrome {
   background-position: 0 0;
}
.browser-safari {
   background-position: -64px 0;
}
.browser-firefox {
   background-position: 0 -64px;
}
.browser-opera {
   background-position: -64px -64px;
}

Den ekstra klasse, .browser-icon, har jeg blot tilføjet for at undgå at skulle angive background, width, height på alle de andre klasser. Havde billederne haft forskellige højde og bredde så angiver man blot height og width på den specifikke ikon klasse.

Sprites og retina opløsning

For at få skarpe PNG billeder på retina enheder så fordobler man som regel størrelsen på sine PNG’er, så hvis browser ikonerne havde været 32 x 32 pixels, så ville man så benytte nogle 64 x 64 pixels ikoner til retina display. De større retina billeder skaleres så ned med background-size: 50% når de skal bruges.

Det virker bare ikke til sprites, og her er et eksempel på hvad der vil ske hvis man bruger background-size: 50%, og hvis man ikke gør:

Eksempel på sprite med retina opløsning

background-size: 50% duer ikke her. I stedet så skal man her bruge bredden på det enkelte billede i spriten, samt højden af spriten delt med 2 (begge værdier tages fra retina billedet):

Eksempel på hvordan background-size sættes til retina display

Dvs. at hvis hvert billede i spriten har forskellige bredde, så skal man altså angive den til sin media query der håndterer retina, men heldigvis så er ikonerne i mit eksempel allesammen med samme bredde så jeg kan nøjes med at angive background-size på min overordnede .browser-icon klasse som her:

@media screen and (-webkit-device-pixel-ratio: 2) {
  .browser-icon {
    background-image: url('browser-icons.png');
    background-size: 64px 64px;
  }
}

Det var sprites – men skal sprites laves i manuelt?

Det var lidt om sprites, som sagt en gammel teknik, men stadig en man kan bruge til at optimere lidt på sine hjemmesider. Men skal man så sidde og mappe hvert koordinat i sin sprite ned til CSS’en i hånden og skal man lave spriten i photoshop eller hvad man nu lige her? Nej!

Der findes et hav af redskaber til at lave sine sprites med, her er et lille udkast:

Og der findes mange andre. Jeg bruger selv sprite smith, både derhjemme og på arbejde.

Happy CSS spriting :D

Smid en kommentar

Felter markeret med * skal udfyldes og din e-mail-adresse vil ikke blive offentliggjort.