Website-optimalisatie: sprites zijn cool!

 
24 december 2012

Front-end nu. Ga eens naar Amazon en probeer te tellen hoeveel achtergrondplaatjes je tegenkomt. Elke gradient, elk kader (hoekje linksboven, rand boven, hoekje rechtsboven, rand rechts, hoekje rechtsonder, rand onder, hoekje linksonder, rand links), elke button, alles. Zouden ze elke .png apart van hun servers naar jouw browser sturen?

Nee, natuurlijk niet. Wat veel slimmer is, is het bouwen van sprites. Dat zijn bundelingen van (achtergrond)afbeeldingen. Google.com gebruikt bijvoorbeeld deze:

Googles sprite

Google.com's sprite

Het tonen van deze sprite laat meteen zien waartoe deze dient: als client hoef je maar één afbeelding op te halen en dat is een stuk efficiënter. Het scheelt bandbreedte en processortijd aan de serverkant. Ook hoeft een gebruiker die met de muis boven een knop gaat hangen niet te wachten tot de achtergrond voor de on-hover is opgehaald.

Maar hoe doe je zoiets? Hoe implementeer je een sprite?

Laten we als voorbeeld een sprite met icoontjes gebruiken:

© Geomicons

© Geomicons

(Let op, deze iconen zijn niet vrij te gebruiken. Koop ze voor een luttele $ 16 op Geomicons.)

Het is een hels karwei om elk icoontje uit te knippen, een naam te geven en elk icoontje apart te benoemen in de CSS. Dat deden we dus maar niet. We geven het hele ding gewoon een naam. In dit geval icon-sprite-18.png en dat stoppen we in de CSS:

span {
  background: transparent url(icon-sprite-18.png) no-repeat;
}

voor bijvoorbeeld de HTML:

<div id="iconed-text"><span class="notebook"></span>Een notitieblokje</div>

Nu hebben we een span met een achtergrond van 15×21 icoontjes, dus we zijn er nog niet. Wat handig is aan deze sprite, dat elk icoon 18×18 pixels is, en de (eigenlijk overbodige) tussenruimte ook 18 pixels. Het eerste icoon (een notitieblokje) kunnen we met CSS ‘uitknippen’ op de volgende manier:

span {
  display: inline-block;
  width: 18px;
  height: 18px;
  background: transparent url(icon-sprite-18.png) no-repeat;
}

span.notebook {
  background-position: 0 -36px;
}

Nu hebben we de span ingesteld op 18×18 pixels en de achtergrond (de sprite) verschoven naar de positie 0 pixels van links en 36 pixels omhoog (let op de 18 pixels aan witruimte), zodat we bij het eerste icoon uitkomen. Het minteken is nodig omdat CSS linksboven begint te tellen. Mocht je nu het derde icoon op de tweede rij willen, dan is de positie van de achtergrond dus 0 + 2x 36 pixels van links en 36 pixels + 1x 36 pixels van boven:

span.star {
  background-position: -72px -72px;
}

Nu is het onhandige nog dat je elk icoon moet benoemen in CSS en daarbij de juiste positie vinden. Maar daar is een oplossing voor: gebruik SASS!

Met de mixin

$url-icons: url(icon-sprite-18.png);
@mixin getIcon($verticalIndex, $horizontalIndex) {
  $x: 0 - ($horizontalIndex * 36px);
  $y: -36px - ($verticalIndex * 36px);
  background: transparent $url-icons $x $y no-repeat;
  width: 18px;
  height: 18px;
}

en de functie

@for $ver from 0 through 14 {
  @for $hor from 0 through 20 {
    .icon.v#{$ver}.h#{$hor} {
      @include getIcon($ver, $hor);
    }
  }
}

heb je CSS laten genereren waarmee je aan de hand van de positie op de sprite door middel van een klasse gemakkelijk een ander icoon kunt kiezen:

<span class="icon v1 h2"></span>

geeft op deze manier het icoon met het sterretje. Verander de klasse in “icon v4 h3” en je hebt een spaarvarken. Wat dit simpel maakt, is dat je niet naar de Photoshop hoeft om een ander icoontje te kiezen. Niemand hoeft al die icoontjes ‘uit te knippen’ en dat scheelt nogal wat werk. Het volstaat om de HTML-klasse te veranderen. (Print de sprite uit en nummer de rijen, in dit voorbeeld zero-based.)

Een simpeler sprite, met drie achtergronden voor een knop is natuurlijk ook makkelijk. Stel dat je vier knoppen boven elkaar in een sprite hebt, elk 24 pixels hoog en 80 pixels breed. In SASS:

.button {
  width: 80px;
  height: 24px;
  background: transparent url(button-sprite.png) left top no-repeat; // left en top zijn standaard css voor 0 en 0
  &:hover {
    background-position: 0 -24px;
  }
  &.disabled{
    background-position: 0 -48px;
  }
}

Zo. Nu zijn achtergrondplaatjes appeltje-eitje! Succes, en mocht je nog vragen hebben, reageer dan hieronder.


Werken met ?
Kijk dan bij onze mogelijkheden voor starters en/of ervaren IT'ers.


Categorieën: Development, Overige talen en platformen

Tags: , ,


Reacties (4)

  • huizing schreef:

    precies wat ik zocht naar aanleiding van een vraag van een klant, alleen nu implementeren..

    Geplaatst op 06 december 2013 om 0:26 Permalink

  • Leuk artikel! Het is inderdaad sterk aan te raden om gebruik te maken van sprites. Het bevordert de laadtijd (ook goed voor SEO) en is tevens fijner voor uw bezoekers. Ivo, bedankt voor de tip!

    Geplaatst op 27 december 2012 om 11:32 Permalink

  • Ivo Limmen schreef:

    Je hebt hier overigens een reeks online tools voor zoals: http://csssprites.com/ deze maken de CSS en één plaatje van een reeks iconen.

    Geplaatst op 27 december 2012 om 2:57 Permalink

  • Simon Klees schreef:

    Online-blackjack-spelletje maken? Gebruik deze http://www.jfitz.com/cards/classic-playing-cards.png en je bent al bijna klaar! Bijna dan…

    Geplaatst op 24 december 2012 om 13:36 Permalink