Honlapunk csinosítása és okosítása során nem egyszer nyúltunk ahhoz az eszközhöz, hogy egy-egy oldalhoz JavaScript programok segítségével különféle kiegészítő elemeket adtunk hozzá. Ilyen kiegészítő elemek voltak például a zászlók a résztvevők táblájában, a hivatkozások a rendezhető táblák címsoraiban, a cikkek automatikusan generált tartalomjegyzéke, a rádiógombok és jelölőmezők „képesített” változatai és a hibaüzenetek a regisztrációs űrlapon, vagy legutóbb a hivatkozások számozott listája a nyomtatási nézethez.
Ez utóbbiból előző leckénkben – a jelentős mértékben elegánsabb végeredményt nyújtó javascriptes megoldás mellett – bemutattunk egy kissé fapados(nak tűnő), stíluslap-alapú módszert is. Ez a módszer azon alapult, hogy az :after pszeudoelem jelölő használatával megmondtuk a böngészőknek, hogy a cikk azonosítójú ‹div› elemeken belül található valamennyi hivatkozás mögé szeretnénk valamit beilleszteni (div#cikk a:after). Egész pontosan azt kértük a böngészőktől, hogy a hivatkozás mögé, egy szögletes zárójelpár közé írja be a hivatkozás href attribútumának értékét (content: " [" attr(href) "]").
Igazából ez a megoldás az előző leckében csak egy röpke mellékszál volt, hiszen a lényeg az a kis JavaScript program volt, ami összegyűjtötte a hivatkozások céljainak listáját, és egyrészt a linkelemek mögé elhelyezett egy-egy végjegyzet-hivatkozást, másrészt a listát egy végjegyzet-gyűjteményként elhelyezte a dokumentum végén. Ez alkalommal azonban a mellékszereplő lép elő, ugyanis az :after és párja, a :before pszeudoelemek sokszor jelentős mértékben egyszerűbbé tudják tenni a munkánkat, a használatukkal nem egyszer bonyolultabb JavaScript programokat válthatunk ki. Arra azonban érdemes odafigyelnünk, hogy e két pszeudoelemet és a hozzájuk szorosan kapcsolódó content stílustulajdonságot az Internet Explorer 8-asnál régebbi verziói nem igazán ismerik, és érdekes módon egyes alelemeknél a WebKit-alapú böngészők (például Safari, Chrome) is bakiznak. Ugyanakkor úgy tűnik, hogy a böngészőgyártóknak egyre fontosabb a szabványok minél pontosabb követése – márpedig ezek az elemek már a CSS 2.1-es szabványnak is részét képezik –, így ez a helyzet hamarosan javulni fog.
Idézni csak pontosan és szépen
A honlapon elhelyezett írásokban fel-felbukkannak különféle idézetek, amelyek jelölésének mikéntje erősen függ a honlap vagy az oldal szerkesztőjétől. Sajnos az egyik leggyakrabban látott megoldás – még a leglátogatottabb, legnépszerűbb oldalakon is – a kódszerkesztőben beszúrt [Shift]+[2] billentyűkombináció, amelynek eredménye igencsak írógéphatású. A HTML-szabvány megalkotói azonban sok-sok évvel ezelőtt gondoltak erre a problémára is, és az ún. HTML-entitások között többféle idézőjelet találunk, köztük a hagyományos alul-felül párost is („ – ”), így semmi akadálya annak, hogy ezeket használjuk az írógépstílusú idézőjelek között.
Nem biztos, hogy minden esetben a legpraktikusabb megoldás, de az igazán igényes oldalszerkesztők az idézeteket nem (csak) idézőjelekkel, mondhatni „optikai módon”, hanem az erre kitalált ‹cite›‹/cite› vagy ‹q›‹/q› jelölőkkel szemantikailag is kiemelhetik a szövegből. Előbbi párost választva az idézett szöveg a legtöbb böngészőben alapértelmezés szerint dőlt betűkkel, míg az utóbbi párost használva idézőjelek között jelenik meg. Vagyis ez utóbbi megoldás tűnik a befutónak, ám egyrészt az Internet Explorer ezt a címkét sajnos nem ismeri, másrészt számunkra – már csak a tanulás kedvéért – most az előbbi tűnik a jobb választásnak.
Ha oldalunkon az idézett szövegeket ‹cite›‹/cite› párosokkal jelöltük meg, akkor tulajdonképpen – hasonlóan ahhoz, mintha ‹q›‹/q›-t használtunk volna – nincs is szükség arra, hogy a citált szövegrészt idézőjelekkel kezdjük és fejezzük be. Ezekről ugyanis majd a stíluslapunk fog gondoskodni.
A dolog egyébként sokkal egyszerűbb, mint gondolnánk, ugyanis a korábban a href attribútum beszúrására használt content stílustulajdonságnak adhatjuk az open-quote és a close-quote értékeket is. Előbbit értelemszerűen az idézet elé, míg utóbbit az idézet mögé fogjuk beillesztetni:
cite:before { content: open-quote; }
cite:after { content: close-quote; }
Ráadásul a quotes stílustulajdonság segítségével azt is megadhatjuk, hogy ezek az idézőjelek milyen karakterek is legyenek: cite { quotes: "201e" "201d" "0ab" "0bb"; }
Az idézőjelek közé elviekben (majdnem) bármilyen karaktert, sőt akár karaktersorozatot is írhatunk, azonban pont az idézőjeleket kicsit nehézkesebb bevinni, mivel ezeknek az ún. Unicode-ját kell megadnunk egy visszafelé forduló per jel mögé írva. De ez csak elsőre tűnik ijesztőnek, ugyanis ezeket a kódokat pillanatok alatt megnézhetjük a Windowsok régi segédprogramjával, a Karaktertáblával. Ebben ugyanis bármely karakterre kattintva az ablak bal alsó sarkában leolvashatjuk a kiválasztott írásjel kódját, amit csak be kell másolnunk a stíluslapunkba. A quotes-nak egyébként több idézőjelpárt is megadhatunk, amelynek természetesen csak abban az esetben van értelme, ha egymásba ágyazott idézeteket használunk.
Ha ez utóbbira nincs szükségünk, akkor tulajdonképpen még egyszerűbbé is tehetjük a dolgot azzal, hogy közvetlenül megadjuk a böngészőnek, hogy milyen karaktert, karaktersorozatot illesszen be az idézet – vagy tulajdonképpen bármelyik HTML-elem – elé vagy mögé, hiszen a content stílustulajdonságnak egy aposztrófok vagy normál idézőjelek közé tetszőleges szövegeket írhatunk. Így tulajdonképpen azt is megtehettük volna, hogy az idézőjelet egyszerűen úgy rakjuk ki az idézetek elé és mögé, hogy:
cite:before { content: "201e"; }
cite:after { content: "201d"; }
Az eredmény látszólag pontosan ugyanaz lenne. Hasonló módon például azt is megtehetjük, hogy egy táblázatban az egyes cellák tartalma elé vagy mögé pontosan ugyanazokat a szövegeket írjuk – anélkül, hogy ezeket a HTML-kódunkban minden egyes sorban szerepeltetnünk kellene. Az alábbi CSS-kódrészlet például egy táblázat minden sorának második oszlopába az ott található szám mögé odaírja, hogy „ db”:
tr td:nth-child(2):after {
content: " db";
}
Képek beszúrása
Remélhetőleg sokan emlékeznek még arra, hogy konferenciánk honlapján előbb egy kis JavaScript program, később – az IE6 száműzését követően – attribútumszelektorok segítségével kis ikonokat tettünk a különböző állománytípusokra és a honlapunkon kívülre mutató hivatkozások mögé. Ezek az ikonok az egyes hivatkozások jobbra igazított háttérképeként jelentek meg az oldalon – legalábbis a képernyőn. Ugyanis, ahogyan azt legutóbbi két leckénkben már többször is említettük, a háttérképek nyomtatása a böngészőkben alapértelmezés szerint ki van kapcsolva, így ezek a kis hasznos jelölők az oldal papírra vetése során elvesznek.
Éppen ezért adja magát a kérdés, hogy nem lehetne-e ezeket az ikonokat valahogy a háttérképek helyet inkább „rendes képként” beszúrni a hivatkozások mögé? A költői kérdésre a válasz természetesen az, hogy lehet – és nemcsak JavaScripttel, hanem a stíluslap megfelelő módosításával is. Ehhez először is a korábbi attribútumszelektor mögé illesszük az :after pszeudoelemet (a[href$=".pdf"]:after), majd mondjuk meg a böngészőnek, hogy a hivatkozás mögé ne egy attribútumot, egy idézőjelet vagy egy szöveget, hanem egy képet szúrjon be, amelynek a formátuma gyakorlatilag megegyezik például a háttérképeknél megismerttel (content: url(../images/icon_pdf.gif);). Ezt követően még jöhet egy kis formázás, hogy a kép ne tapadjon hozzá a szöveghez, valamint esetleg egy kicsit lejjebb is kerüljön, és már készen is vagyunk:
a[href$=".pdf"]:after {
content: url(../images/icon_pdf.gif);
margin-left: 2px;
vertical-align: -3px;
}
Az eredmény megfelelő formázás esetén látszólag semmiben sem tér el a korábban használt megoldásétól – egészen addig, amíg az oldalt ki nem nyomtatjuk, vagy meg nem nézzük a nyomtatási előnézeti képet. Az így beszúrt képek ugyanis majdnem ugyan olyanok, mintha a HTML-kódba a hivatkozások mögé egy-egy ‹img› elemet írtunk volna be. Az egyetlen – néha nem is olyan jelentéktelen – eltérés, hogy ezeket az elemeket (képeket, szövegeket) az oldal dokumentummodelljében (DOM) nem fogjuk megtalálni sem a böngészők fejlesztőeszközeivel (például Firebug), sem JavaScript programokkal.
De ilyen képeket természetesen nemcsak elemek mögé, hanem eléjük is beilleszthetünk, egy felsorolásban például ilyen módon is kicserélhetjük az unalmas „bogyókat” különböző képekre. Igen, ennek van egy sokkal egyszerűbb megoldása is (list-style-image: url(../images/bullet.gif);), de ebből nem sokat tanulnánk.
Ahogyan azt kicsit feljebb említettük, a content stílustulajdonsággal tulajdonképpen virtuális elemeket illeszthetünk a kódunkba, amelyek gyakorlatilag úgy viselkednek – és úgy is kezelhetők –, mintha JavaScriptből egy-egy ‹span› objektumot hoznánk létre a kiválasztott elemek előtt vagy mögött, és abban helyeznénk el a megadott tartalmakat. Ennek megfelelően, ha egy felsoroláselem elől eltávolítjuk a „bogyót” (list-style-type: none;), majd a contenttel beszúrunk elé egy képet, akkor az eredmény pontosan úgy néz ki, mint amikor a list-style-position stílustulajdonsághoz az inside értéket rendeljük. Ha a listánkat egy kicsit áttekinthetőbbé szeretnénk tenni (list-style-position: outside;), akkor a virtuális ‹span›-unkat bizony balra folyatott (float: left;) blokkszintű elemmé kell alakítanunk (display: block;), majd végezzünk el rajta némi formázást, és már készen is van az új, képes díszponttal jelölt felsorolásunk.
Automatikus sorszámozás
Hosszabb írásaink szerkesztése során sokszor jól jönne a címsorok automatikus sorszámozása, valami hasonló, mint amilyeneket a szövegszerkesztőkben már megszoktunk. Mondhatni természetesen erre is lehetőségünk van, ráadásul szinte ugyanolyan jól konfigurálhatóan, mint amilyen lehetőségeket például a Word Többszintű lista beállításai ablak kínál.
Ehhez persze annyit segítenünk kell a böngészőnek, hogy a címsorokat nemcsak formázással különböztetjük meg a szöveg többi részétől, hanem szisztematikusan használjuk a ‹h1›–‹h9› jelölőket is. A – mostanra most már nyugodtan kijelenthetjük, hogy – igencsak sokoldalú content stílustulajdonságnak létezik egy counter tulajdonsága, amelyhez két fontos másik stílustulajdonság kapcsolódik szorosan: a counter-reset, amellyel a számlálókat állíthatjuk alaphelyzetbe, és a counter-increment, amellyel a számlálókat léptethetjük.
Értelemszerűen a sorszámozás azzal kezdődik, hogy – egy befoglaló elem stílustulajdonság-csoportján belül – egy számlálót alaphelyzetbe állítunk a counter-resettel, például: counter-reset: cimsor1;
A számláló neve elviekben tetszőleges lehet, azonban érdemes betartani a váltózóneveknél beváltakat, vagyis lehetőleg betűvel kezdődjön és ne tartalmazzon ékezetes betűket és speciális írásjeleket (például csillag, plusz, per, kisebb-nagyobb jel stb.). Ennek az utasításnak a hatására a számláló nullára áll, de ha szeretnénk más értéket megadni, arra is van lehetőségünk (például counter-reset: cimsor1 8;), amire például több oldalra darabolt írásoknál lehet szükség.
Azt, hogy az egyes számlálók értékét mikor kell növelnie a programnak, nekünk kell megmondanunk, többnyire közvetlenül a használat előtt:
h1:before {
counter-increment: cimsor1;
content: counter(cimsor1) ". ";
}
Ahogyan a counter-reset alapértelmezés szerint nullára állítja számlálónkat, úgy a counter-increment mindig egyet ad hozzá, amit szintén megváltoztathatunk a számláló mögé írt értékkel, így a counter-increment: cimsor1 2; stílusdeklarációval kettesével fogjuk a címsor1 értékét növelni, de speciális helyzetekben akár azt is megtehetjük, hogy negatív értéket megadva (például counter-increment: cimsor1 -1;) visszafele számoljunk.
Miután egy oldalon tetszőleges, egymástól független vagy saját szabályrendszerrel kialakított hierarchikus számlálókat (például a ‹h1› nullázza a cimsor2-t, a ‹h2› a cimsor3-at stb.), így igen összetett megoldásokat is használhatunk. Egy content elemen belül ugyanis több számlálót is szerepeltethetünk, például egy ‹h3› címsornál a teljes tartalom így fog felépülni: content: counter(cimsor1) "." counter(cimsor2) "." counter(cimsor3) ". ";
Sőt mi több, a szabvány (és szerencsére a böngészők is) azt is lehetővé teszi, hogy különböző számformátumokat használjuk. Így megtehetjük azt is, hogy egyes számlálók értékét római számokkal (lower-roman és upper-roman), betűkkel (lower-latin és upper-latin), esetleg görög betűkkel (lower-greek), grúz (georgian) vagy örmény (armenian) számozással jelenítsük meg (például counter(cimsor1, upper-latin);).
Természetesen az automatikus sorszámozást nemcsak címsorok, hanem például (hierarchikus) listák esetében is használhatunk, de ilyenkor nagyon oda kell figyelnünk arra, hogy amíg a címsoroknál a különböző elemnevek segítik a különböző számlálók alaphelyzetbe állítását és léptetését, addig a listáknál az azonos nevű elemek egymáshoz rendelődése lehet csak segítségünkre. Ehhez a különböző ún. kombinátorokat, de leginkább a › jelt használhatjuk hatékonyan – például az ol#counter › li › ol szelektor egy counter azonosítójú listán belül található második szintű listát fog jelölni, de az azon belül található harmadik szintet ez már nem érinti.
Valószínűleg a CSS 2.1 szabvány alkotói is gondoltak arra, hogy egy összetettebb lista ilyetén számozása kissé komplikálttá válik, ezért hasonló esetekben – bár kevésbé testre szabhatóan – használhatjuk az alábbi rövidített formulát is:
ol {
list-style-type: none;
counter-reset: item;
}
ol li:before {
counter-increment: item;
content: counters(item, ".") ". ";
}
A cikkben szereplő kódok és mintaoldalak letölthetők innen.