ugrás a tartalomhoz

Automatizált CSS sprite készítés SmartSprites-szal

Török Gábor · 2009. Május. 23. (Szo), 22.25
A CSS sprite-ok elsődleges célja, hogy a webdesignt felépítő sok kis grafikai elemet egy (vagy néhány) nagyobb méretű képbe rendezzük, így csökkenthetjük a kiszolgáló felé küldött kéréseket. A CSS sprite-okat noha kézzel is létre lehet hozni – ld. nemrég boncolt blogmarkot, ahol a szerző ezt a design kialakítás első lépései közé javasolja –, hosszabb távon felmerül a kérdés, vajon lehetne ezt a folyamatot némiképp automatizálttá tenni. Itt jön a képbe a SmartSprites.

A CSS sprite-ok manuális létrehozásának előnye egyértelműen a rugalmasság: teljes mértékben saját szájízünk szerint rendezhetjük el a vásznon az elemeket, így sokszor jobb hatékonyságot érhetünk el (például a keletkező „zaj” tekintetében), mint egy gépi eszköz. Ha ezt a módszert választjuk, célszerű lehet a munkatársakkal megállapodni, hogy azonos metodika alapján dolgozzuk ki a sprite-okat – netán a stíluslapokban megjegyzéseket is elhelyezhetünk, hogy a sprite-ok jövőbeni módosításakor támpontot kapjunk. Viszont ha élünk azzal a feltevéssel, hogy a későbbiekben módosítani szükséges a sprite-ot – tegyük fel, arculat frissítéskor egy vagy több grafikai elem változik –, kézi vezérlés esetén előfordulhat, hogy a teljes sprite-ot újra kell gondolnunk, ez pedig magával vonja a CSS szinkronba hozását is. Talán ezen a ponton terelhetnénk a folyamatot szabályozottabb mederbe.)

A SmartSprites egy Java alapú CSS sprite generáló eszköz (elérhető PHP CLI port is). Használata során egy előre definiált forgatókönyv szerint zajlik a sprite-ok készítése. Kényelmesen illeszthető az alkalmazott build folyamathoz, maga az eszköz transzparensen települ rá a sprite-mentes kialakításra.

A SmartSprites használatakor első ízben szokásosan feldaraboljuk a designt grafikai elemekre és azokhoz igazodva megírjuk a stíluslapot. Ezt követően a stíluslapokon azokhoz a képekhez, amelyeket sprite-okba szeretnénk összefogni, speciális megjegyzéseket helyezünk el a SmartSprites számára. Az eszköz futtatásakor ezekből a megjegyzésekből szerzi ismereteit és ezek alapján készíti el automatizáltan a sprite-ot, sprite-okat.

Vegyük az alábbi kódot a stíluslapunkban:

#menu li a
{
    background-color: #000;
    background-repeat: repeat-x;
    background-image: url("images/menu.png");
}

#menu li a:hover
{
    background-color: #fff;
    background-repeat: repeat-x;
    background-image: url("images/menu_hover.png");
}
Ugyanezt írjuk fel a SmartSprites használatát feltételezve:

/** sprite: sprite-vert; sprite-image: url("images/sprite-vert.png"); sprite-layout: vertical; */

#menu li a
{
    background-color: #000;
    background-repeat: repeat-x;
    background-image: url("images/menu.png"); /** sprite-ref: sprite-vert; sprite-alignment: repeat; */
}

#menu li a:hover
{
  background-color: #fff;
  background-repeat: repeat-x;
  background-image: url("images/menu_hover.png"); /** sprite-ref: sprite-vert; sprite-alignment: repeat; */
}
A különbség néhány CSS komment, amelyekben speciális SmartSprites direktívákat használunk.

Futtassuk le az eszközt a fenti stíluslapon, amely eredményeképpen létrejön a sprite-vert.png képfájl és a stylesheet-sprite.css, ez utóbbi az alábbi tartalommal:

#menu li a
{
    background-color: #000;
    background-repeat: repeat-x;
    background-image: url("images/sprite-vert.png");
    background-position: left -0px;
}

#menu li a:hover
{
    background-color: #fff;
    background-repeat: repeat-x;
    background-image: url("images/sprite-vert.png");
    background-position: left -25px;
}
A SmartSprites használatakor a háttér tulajdonságokhoz nem alkalmazható a gyorsírásos forma, mert az eszköz a neki szánt direktívákat a background-image meghatározás után keresi (ráadásul szigorúan ugyanabban a sorban). Ez persze inkább sajátosság, mint igazi hátrány; viszont erre a jövőben kifejezetten ügyelni kell, ahogy arra is, hogy a generált stíluslapon a kifejtett background-position meghatározása rögtön a kép forrása alá kerül, ezért az eredeti stíluslap forrásában azt mindig elé írjuk, különben egyből felülbíráljuk azt. (Normális esetben a SmartSprites bírálja felül a mi szabályunkat.)

Csaltam még egy helyen. A felhozott példában a háttérkép ismétlődésének típusát a :hover kiválasztóval hivatkozott elemnél nem változtattam, én még is kiírtam. Erre a SmartSprites direktívák megértése végett volt szükség. Ugyanis az eszköz a stíluslap szabályait (a background-image-et kivéve) nem dolgozza fel, csak a számára explicit megfogalmazott parancsokkal foglalkozik. Így noha a böngésző számára egyértelmű lesz a kiválasztók rangsorolása miatt az alkalmazandó érték, a SmartSprites az (általa alapértelmezettnek vett) ismétlődés tiltást fogja alapul venni. SmartSprites nélkül a következőt is írhattuk volna; azonos hatás a böngészőben, viszont nem dolgozható fel az eszközzel.

#menu li a
{
    background: #000 url("images/menu.png") repeat-x;
}

#menu li a:hover
{
    background-color: #fff;
    background-image: url("images/menu_hover.png");
}
(Ez akkor kifejezetten kellemetlen, amikor közös osztályba emeljük adott elemek háttérképének sajátosságát, és példának okáért csak a képek elérési útvonalát adnánk meg egyedileg; ekkor is minden elemnél szükséges valamennyi sprite direktíva kifejtése.)

A SmartSprites két típusú elrendezéssel tudja a sprite-okat létrehozni: valamennyi grafikát egymás alá vagy valamennyit egymás mellé pakolja. Olyan sprite-ot, ahol mindkét irányban vannak grafikai elemek – lásd az unos-untalan hivatkozott Google sprite-ot – nem tudunk vele kialakítani.

Ami viszont már inkább bug mint feature, hogy ha a CSS forrásban egy képre több helyütt is hivatkozunk, és mindegyikhez elkészítjük a megfelelő SmartSprites direktívákat, akkor mindannyiszor rákerül a sprite-ra, ahányszor előfordult a stíluslapon. (Ha viszont nem jelöljük meg a sprite részeként az ismételten felhasznált grafikákat, akkor meg egyáltalán nem kerülnek a sprite-ra.)

Ezen a néhány sajátos viselkedésen túl azonban két kiemelt érvet hozok fel a SmartSprites használata mellett. Egyrészt a CSS sprite-ok használata – okosan – jó. Ezzel az eszközzel kialakíthatunk egy olyan munkafolyamatot, amellyel biztonságos és következetesen készíthetünk sprite-okat. Mint már említett, a generálás procedúrája automatizálható, így beépíthető a meglévő build folyamatba, tehát a sprite készítés a továbbiakban lényegileg egy „forgatókönyv” megírását fogja jelenteni. Ha változnak a grafikai elemek (a stíluslap szükség szerinti módosítása után) a SmartSprites-szal vezényszóra előállíthatók az új sprite-ok.

Másfelől a SmartSprites a sprite-ok megértésében is sokat segít. Ha első ízben felvértezzük a stíluslapunkat a megfelelő direktívákkal, és elvégeztetjük az eszközzel a transzformációt, váratlan meglepetések érhetnek. Rájöhetünk például, hogy hiába eredményeznek kifogástalan megjelenést a böngészőben a CSS szabályaink, nem feltétlenül kompatibilisek sprite-ok használatához, szükséges lehet néhányat módosítanunk. Sprite-ok használata mellett például a háttérkép pozíciót csak előre kalkulált értékekben fejezhetjük ki, mert egy sprite esetén nincs értelme a center-nek, vagy egész egyszerűen nem tehetünk felülre igazított, csak vízszintesen ismétlődő háttérképet sem a body-ra, mert alul kikandikálnának a sprite többi versenyzői is.

A SmartSpritesnak tehát van néhány apróbb hibája, de ezek várhatóan idővel eltűnnek majd, az eszköz bizonyosan fog még fejlődni. Ha éles munkára nem is alkalmazzuk, a sprite-ok készítésének elsajátításához értékes tutor. Személy szerint én egyre több weboldalnál már bevetem. Más sprite készítő eszközzel még nem dolgoztam, de várom a tapasztalataitokat.
 
1

Jó projekt

yaanno · 2009. Május. 25. (H), 22.20
Szép ismertető, köszönet érte. Kicsit belenéztem a forrásba is, elég komoly vállalkozásnak tűnik, egy alpha állapotúnak mondott toolhoz képest igen sokat tud.
2

énis, énis...

TeeCee · 2009. Május. 27. (Sze), 16.36
...egyszóval én is csináltam egy ilyet, de az egyszerű, mint egy faék!
Egy könyvtár alkönyvtáraiben lévő PNG-ket (modulnév/*.png) átnyálazza, és amelyik 16,22,32,48,64,128px széles és ugyanolyan magas, azt automatikusan összeragasztja az átlátszóság megtartásával és egy CSS-be belerakja ennek a háttérképnek a szükséges eltolását. Egy méretű ikonok egy fájlba kerülnek (icon48.png). A class-név tartalmazza a méretet és a modul, valamint a fájlnevet kiterjesztés nélkül, pl: i22-mailing-add-attachment. 'i'-vel kezdődik, mert 'icon', vagy 'ikon' :D
Mielőtt valaki megkérdi: intranetes alkalmazás, azért van benne borzasztó nagy ikon is!

Mivel a kinézet csak *.tpl állományokban van, tervek szerint készülni fog egy előszűrő is, hogy milyen class-ok nincsenek használva, illetve milyen ikonok vannak IMG-taggal berakva a CSS-es megoldás helyett.

És valóban: nagy segítség tud lenni egy ilyen! Pláne, hogy minden sablonban van, ezután már egy óra alatt egy elég nagy lista összes IMG-jét kiszedtem és helyébe CSS-es gomb és smiley került.