News & Blog

CSS számlálók használata

News & Blog

A CSS a kezdetekhez képest nagy fejlődésen ment keresztül. Már nem csak statikusan képes tulajdonságokat rendelni az egyes html elemekhez, hanem dinamikusan is tudja bizonyos szinten azok tartalmát megváltoztatni. Erre egy jó példa a CSS számlálók. 

A CSS számlálók gyakorlatilag a CSS változói, melyeket CSS szabályokkal tudunk létrehozni, növelni, megjeleníteni. Ezeket általában elemekhez rendeljük sorszámként. A számlálót a counter-reset tulajdonsággal hozzuk létre. Ha már egy korábban létrehozott számlálót rendelünk ehhez a tulajdonsághoz, akkor a már létezőt felülírjuk egy új kezdőértékkel. (A kezdőérték alapértelmezetten 0, de megadhatunk mást is a változó után írva.)

counter-reset: oldal;
counter-reset: oldal 5;

A létrehozott változót ezután a counter-increment tulajdonsággal tudjuk növelni. Alapértelmezetten 1-gyel növeli, de itt is megadhatunk más értéket a változó után írva.

counter-increment: oldal;
counter-increment: oldal 2;

Ezután már csak ki kell íratnunk az oldal megfelelő helyére, ezt a content tulajdonsággal tehetjük meg. Alapértelmezetten arab számként írja ki, de megadhatjuk, hogy akár római számmal (kis- vagy nagybetűsen), de számos más formátum is rendelkezésre áll. (A különböző lehetőségeket ezen a linken tudjuk megtekinteni: link)

content: counter(oldal);
content: counter(oldal, upper-roman);

Nézzünk meg egy egyszerű példát. Tegyük fel, hogy egy tartalomjegyzékben sorszámmal szeretnénk hivatkozni az egyes oldalakra. Alapesetben ilyenkor ezeket a sorszámokat az alábbi módon bedrótozzuk a kódba:

<a href="#">1.</a>
<a href="#">2.</a>
<a href="#">3.</a>
<a href="#">4.</a>
<a href="#">5.</a>
<a href="#">6.</a>
<a href="#">7.</a>
Kimenet

A fenti megoldás azért nem szerencsés, mert bármikor új hivatkozást szúrunk be a többi közé, újra kell sorszámozni az utána következő elemeket. Állítsuk elő ezeket a sorszámokat inkább CSS számlálóval. A számlálónk neve az oldal lesz, az oldal legelején (a body elemnél) hozzuk létre, és minden hivatkozásnál eggyel megnöveljük. A ::before pszeudo elemmel a hivatkozás tartalma elé íratjuk ki. (Jelen esetben nincsen a hivatkozásnak tartalma, így csak a sorszám jelenik meg.) Elismerem, hogy az oldal kinézete elég egyszerű, a bejegyzés vége tájékán azért megformázzuk egy kicsit. 

<html>
    <head>
        <style>
            body {counter-reset: oldal;}
            a {counter-increment: oldal ;}
            a::before {content: counter(oldal);}
        </style> 
    </head>
    <body>
        <a href="#"></a>
        <a href="#"></a>
        <a href="#"></a>
        <a href="#"></a>
        <a href="#"></a>
        <a href="#"></a>
        <a href="#"></a>
    </body>
</html>
Kimenet

Természetesen lehetőség van egyszerre több számláló kezelésére is. Tegyük fel, hogy egy hosszabb dokumentumban többszintű (a példában 3 szintű) fejezeteket szeretnénk létrehozni a h1h2 és h3 címsorokkal. A fejezeteket sorszámozni szeretnénk, de megint nem szeretnénk bedrótozni a sorszámokat a kódba. Hozzunk létre 3 számlálót (fejezet_1fejezet_2 és fejezet_3), melyek az egyes fejezetszinteket sorszámozzák. A body elemnél inicializáljuk a fejezet_1 változót, melyet a h1 elemnél inkrementálunk. A fejezet_2 változót a h1 eleménél hozzuk létre (illetve nullázzuk), hiszen minden h1-es fejezetcím után újrakezdődik a 2. szintű fejezetek (h2) sorszámozása. Ugyanígy a fejezet_3 változót a h2 elemnél inicializáljuk, és a h3 elemeknél növeljük. (A fejezetcímeket kicsit átszíneztük, hogy jobban látszódjék, melyik melyik szinthez tartozik.)

<html>
    <head>
        <style>
            body{counter-reset: fejezet_1;}
            h1{counter-reset: fejezet_2; counter-increment: fejezet_1;}
            h2{counter-reset: fejezet_3; counter-increment: fejezet_2;}
            h3{counter-increment: fejezet_3;}
 
            h1::before{content: counter(fejezet_1) ". ";}
            h2::before{content: counter(fejezet_1) "." counter(fejezet_2) ". ";}
            h3::before{content: counter(fejezet_1) "." counter(fejezet_2) "." counter(fejezet_3) ". ";}
 
            h1{font-size: 1.8em; background-color: #afafaf; margin: 0px;}
            h2{font-size: 1.4em; background-color: #d2d2d2; margin: 0px; font-weight:300;}
            h3{font-size: 1em; background-color: #e2e2e2; margin: 0px;font-weight:100;}
        </style> 
    </head>
    <body>
        <h1>Őskor</h1>
            <h2>Kína őstörténete</h2>
            <h2>Megalitikus kultúrák</h2>
            <h2>Mezopotámia, Kis-Ázsia és a Közel-Kelet kultúrái</h2>
        <h1>Újkor</h1>
            <h2>Korai újkor</h2>
                <h3>Reformáció</h3>
                <h3>Edo-kor</h3>
                <h3>Qing-kor</h3>
                <h3>Felvilágosodás</h3>
                <h3>Ipari forradalom</h3>
            <h2>Modern kor</h2>
                <h3>Napóleon kora</h3> 
                <h3>Japán modern kor</h3>
                <h3>Kínai modern kor</h3>
                <h3>I. világháború</h3>
                <h3>A két világháború közötti korszak</h3> 
    </body>
</html>
Kimenet

Vegyük figyelembe, hogy minden h1h2 és h3 tag-nél növelni fogja a változókat (illetve inicializálni, amit kell), így ha nem csak a fejezetcímekben használjuk ezeket a tag-eket, akkor célszerű valamivel megjelölni azokat (például egy-egy CSS-osztályt hozzájuk rendelni, és csak az ebbe a CSS osztályba tartozó elemek esetében legyen a számláló kezelve.)

Hasznos dolog, hogy egyszerre több számlálót is használhatunk, de a fenti példában ebből a három különböző számlálóból ténylegesen egy, többszintű számlálót készítettünk. Jó lenne, ha az ilyen többszintű sorszámozást a CSS egyszerűbben is támogatna. Támogatja a beágyazott számlálók használata által. A következő példában egy többszintű sorszámozott lista sorszámozását bízzuk egy ilyen beágyazott számlálóra. Mint látjuk, a sorszámozott lista saját jelölőit kikapcsoltuk (list-style-type: none;), és a számlálót a hagyományos módon inicializáljuk és inkrementáljuk, viszont a kiíratásánál nem a counter hanem a counters függvényt használjuk. Ennek a függvénynek nem csak a számlálót, hanem az egyes szintek közötti elválasztó karaktert is átadjuk. (A végére nem teszi oda ezt a karaktert, így ezt mi illesszük oda manuálisan.) A CSS tudni fogja, hogy a számlálónak melyik szintjét kell növelni éppen. 

<html>
    <head>
        <style>
            ol { counter-reset: szamlalo; list-style-type: none; }
            li { counter-increment: szamlalo;}
            li::before { content: counters(szamlalo,".") ". ";}
        </style> 
    </head>
    <body>
        <ol>
            <li>Alaplapok</li>
            <li>Processzorok
            <ol>
                <li>AMD</li>
                <li>Intel
                    <ol> 
                        <li>Core i3</li>
                        <li>Core i5</li>
                        <li>Core i7</li>
                        <li>Core i9</li>
                    </ol>
                </li>
            </ol>
            <li>Videokártyák</li>
        </ol>
    </body>
</html>
Kimenet

Mi van akkor, ha valamelyik listaelemnél nem szeretnénk a számlálót növelni, illetve a tartalmát megjeleníteni. Tegyük fel, hogy processzor típusok előtt meg akarjuk jeleníteni a “Típusok” feliratot, de értelemszerűen nem akarunk elé sorszámot tenni. Ehhez hozzunk létre egy nemszamol osztályt, és az ilyen osztályú listaelemeknél nem növeljük a számlálót, illetve nem írjuk ki a tartalmát:

<html>
    <head>
        <style>
            ol {counter-reset: szamlalo; list-style-type: none;}
            li {counter-increment: szamlalo;}
            li::before {content: counters(szamlalo,".") ". ";}
            li.nemszamol {counter-increment: none;}
            li.nemszamol::before{content: none;}
        </style> 
    </head>
    <body>
        <ol>
            <li>Alaplapok</li>
            <li>Processzorok
        <ol>
        <li>AMD</li>
        <li>Intel
            <ol>
                <li class="nemszamol">Típusok</li> 
                <li>Core i3</li>
                <li>Core i5</li>
                <li>Core i7</li>
                <li>Core i9</li>
            </ol>
         </li>
         </ol>
            <li>Videokártyák</li>
        </ol>
    </body>
</html>
Kimenet

Igaz, hogy nem tartozik a CSS számlálók témakörébe, de egy kicsit színezzük ki a fenti listát, hogy nézzen már ki valahogy.  

ol {counter-reset: szamlalo; list-style-type: none;}
li {counter-increment: szamlalo; padding-left:0px;}
li::before {content: counters(szamlalo,".") ". ";}
li.nemszamol {counter-increment: none; background-color: orange;}
li.nemszamol::before{content: none;}
body>ol {width: 300px; padding-left:0px;}
ol {background-color: yellow;} 
ol>li{background-color: pink;}
ol>li>ol>li{background-color: lightgreen;}
ol>li>ol>li>ol>li{background-color: lightblue;}
Kimenet

Érezzük, hogy az egyes elemek elérése logikus, de a színek kiválogatása elég véletlenszerű, és nem is tekinthető egységesnek.  A következő példában erre is olvashatunk egy jó trükköt. Korábban már említettem, hogy az automatikusan sorszámozott hivatkozásokra ráférne egy kis formázás. Tegyük most ezt meg. A CSS stílusokat most egyben nézzük meg, és csak az érdekesebb részekhez fűzök magyarázatot.

<html>
    <head>
        <style>
            body {counter-reset: oldal;}
            a {counter-increment: oldal;}
            a::before {content: counter(oldal);}
 
            body {background-color: #1f4261;} 
            div {
                font: 32px  Arial;
                background-color: rgba(255, 255, 255, .1);
                margin-bottom: 16px;
                padding: 16px;
                border-radius: 6px;
                overflow: auto;
            }
            a {
                float: left;
                width: 32px;
                margin: 6px;
                padding: 6px;
                border-radius: 6px;
                border: solid 2px rgba(255, 255, 255, .4);
                text-decoration: none;
                text-align: center;
                color: #fff;
                background-color: rgba(255, 255, 255, .2);
            }
            a:hover {
                border: solid 2px #fff;
                background-color: rgba(255, 255, 255, .4);
                box-shadow: 0 0 10px #fff;
            }
        </style> 
    </head>
    <body>
        <div>
            <a href="#"></a>
            <a href="#"></a>
            <a href="#"></a>
            <a href="#"></a>
            <a href="#"></a>
            <a href="#"></a>
            <a href="#"></a>
        </div>
    </body>
</html>
Kimenet

A sorszámozást megvalósító tulajdonságokkal már korábban foglalkoztunk. Nézzük a háttérszíneket: Az oldal háttérszínét a body elemhez rendeltük, az összes többi elem esetében az átlátszósággal játszunk.  Így érjük el, hogy ugyan különbözőek a háttérszínek, de mégis egységesek, és csak egy helyen kell módosítani, ha változtatni szeretnénk rajta.

A következő furcsaság, hogy a hivatkozásokra alkalmaztuk a floating: left tulajdonságot, noha azok eleve már egymás mellé (balra) vannak rendezve. Akkor miért kellett? Tudni kell, hogy a floating tulajdonságot blokk szintű elemekre lehet alkalmazni, míg a hivatkozások in-line elemek. Az in-line elemekre viszont nem lehet a width tulajdonságot alkalmazni, amit mi meg szeretnénk, vagyis előtte a display: block  tulajdonsággal blokk szintűvé kell alakítanunk. Ezt a tulajdonságot viszont nem alkalmaztuk. A lényeg az, hogy ha a floating tulajdonságot in-line elemre alkalmazzuk, azt blokk szintűként kezeli, így viszont már a width tulajdonságot is alkalmazza anélkül, hogy a display: block tulajdonsággal átalakítottuk volna.

Az utolsó tulajdonság az overflow, ami magyarázatra szorul. Az overflow eredetileg arra való, hogy amennyiben egy blokk szintű elembe nem fér bele a tartalma, akkor a mit kezdjünk a “kilógó” részekkel. Az overflow: hide beállítást arra utasítaná a böngészőt, hogy a kilógó részeket rejtse el. Itt most a hivatkozásokat befoglaló div elembe nem férnek be a hivatkozások, tehát a kilógókat nem kellene látnunk. Mégis látjuk. Miért van ez? Azért, mert a div elemnek nem adtuk meg a height tulajdonságát, így az overflow: hide ilyenkor akkorára nyújtja a div elemet, hogy minden beleférjen. Miért nem adtuk meg inkább a height tulajdonságot? Mert akkor ha a későbbiekben újabb hivatkozásokat helyeznénk el ide, akkor a div magasságát is növelni kellene. Így viszont mindig követi a tartalmat.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük