Először is egy olyan fogalommal kell megismerkednünk, amellyel szerencsére azóta tisztában vagyunk, hogy megtanultunk olvasni, csak eddig nem sejtettük, hogy ezt így hívják. Vonatkoztassunk is el egy pillanatra az internetről, és koncentráljunk egy, a kezünkben lévő újságra.
NORMÁLFOLYAM
Ha ránézünk egy újságoldalra, rengeteg szöveget és képet látunk; a szöveg bekezdésekből, a bekezdések szövegsorokból, azok szavakból, a szavak pedig betűkből állnak. Amikor elkezdjük olvasni az adott oldalt, a szöveg normálfolyamát követjük: kiindulunk az oldal bal felső sarkától és sorról sorra, hasábról hasábra haladunk balról jobbra, fentről lefelé, amíg el nem érjük az oldal jobb alsó sarkát, amikor is jöhet a következő.
Egy magyar nyelvű dokumentum normálfolyamában a szöveg balról jobbra, fentről lefelé olvasható
A dokumentum normálfolyama (idegen kifejezéssel: normal flow) tehát egy olyan elfogadott szabályrendszer, amely alapvetően meghatározza, hogy hogyan jelenik meg az információ az adott közegben. A weboldalak esetében a normálfolyam meghatározza, hogy a képernyőn hogyan – milyen előre pontosan tudható, kiszámítható módon – jelennek meg a weboldalelemeink. Minden bekezdés, minden címsor, minden felsorolás és ezekben levő minden egyes betű a dokumentum normálfolyamának megfelelően jelenik meg a képernyőn – amíg mi magunk másképp nem rendelkezünk.
Kiegészítő: az oldal nyelve
Felmerülhet a kérdés, hogy honnan tudja a böngésző, hogy a megjeleníteni kívánt weboldal milyen nyelvű és annak mi a normál folyása? Onnan, hogy megmondjuk neki: erre való a HTMLoldalt nyitó ‹html› tag lang és xml:lang attribútuma. Vessünk egy pillantást eddigi példáink elejére, és látni fogjuk, hogy a ‹html› tag mindegyikben azonos volt:
A lang attribútumot eddig nem használtuk, ami önmagában nem jelentett hibát – láttuk, hogy weboldalaink enélkül is érvényesek voltak, megfeleltek az általunk kiválasztott XHTML szabványnak –, azonban ártani nem árt. Sőt, minél több információt adunk meg az oldalról, annál jobb.
DOBOZOK MÉG EGYSZER
A fentiek tükrében tekintsük át újra a dobozmodellt. Azt már tudjuk, hogy a CSS-ben a doboz kifejezés egy jobbára téglalap alakú területet jelöl, amelyben weboldalelemeink tartalma megjelenik a képernyőn. Emlékeztetőül nézzünk meg egy példát, és ezúttal hívjuk segítségül kedvenc Firefox kiegészítőnket, a Firebugot, amely készségesen hajlandó nemcsak megjeleníteni magát a dobozt az oldalban, hanem annak adatait is.
Egy bekezdésszöveg dobozának vizsgálatában ismét nagy hasznunkra van a Firebug kiegészítő
A felső részen kékkel jelöli a ‹p› tag tényleges szöveges tartalmát, sárgával pedig a 16 képpont magas felső-alsó margót. A kiegészítő jobb oldalán, a Layout nézetben megjeleníti a bekezdésszövegünk által alkotott doboz legfontosabb paramétereit. (Sajnos a magyar nyelvű Firefoxban a Firebug is automatikusan magyarra vált, amivel csak az a gond, hogy a honosítás nem sikerült túl fényesen. Épp ezért a képeket angol nyelvű Firefoxban és Firebugban készítettük, hogy az eredeti szakkifejezések látszódjanak.) Láthatjuk, hogy a szöveges tartalom 761x36 képpont méretű, felül és alul 16-16 pontos margóval (margin) és ezúttal nincs sem keret (border), sem pedig attól való eltartás (padding). Az ábrán legfelül látható offset nevű rész a doboz elhelyezkedését mutatja az oldalon belül: az oldal tetejétől 254, a bal oldalától pedig 8 képpontra található.
Kiegészítő: az offset titka
A második képen látható, hogy a vizsgált bekezdésünk 254 képpontra van a weboldal tetejétől és 8 képpontra a bal szélétől. A függőleges eltolódást nyilván a bekezdést megelőző weboldalelemek okozzák, a vízszintest viszont első ránézésre semmi nem indokolja. A bekezdésnek nincs semmiféle olyan tulajdonsága (például margója), amely ezt okozhatná – viszont akkor vajon miért nem az oldal szélén kezdődik, miért van beljebb 8 képponttal?
Ha szabad a gazda, a Firebug bal oldali ablakrészében kattintsunk rá a ‹body› tagre. Az ábrán rögtön látható, hogy magának a weboldalnak van mind a négy oldalon 8 pixeles margója, és ez okozza az összes benne levő HTML elem vízszintes eltolódását!
A bekezdésszöveg tehát egy doboz. Azt is könnyű belátnunk, hogy az őt befoglaló ‹div› is az, mint ahogy a ‹div›-et befoglaló, esetleges másik weboldalelem is, és így tovább felfelé a weboldal struktúrájában, amíg el nem jutunk egészen magáig a ‹body› tagig, amiről szintén megállapíthatjuk, hogy egy doboz. Oda lyukadunk ki, hogy az egész oldal tulajdonképpen egy óriási doboz, amit több kisebb-nagyobb doboz alkot (pont, mint egy nagy kirakós gyerekjáték esetében). Mit mondhatunk ugyanakkor a ‹p› tag tartalmáról? Meglepő módon, a CSS szerint ők is dobozok. A többesszám indokolt, mert a bekezdésünk normál és dőlt (pontosabban dőlt betűvel megjelenő, kiemelt) szöveget, illetve egy hivatkozást is tartalmaz – ezek is mind külön dobozoknak számítanak, még ha első ránézésre nem is értjük, hogy hogyan. Egyelőre vonjuk le a végkövetkeztetést: a HTML oldalon belül a CSS számára minden doboz. Viszont nem minden doboz egyforma – és itt jött a képbe a múltkor a gyevi bíró!
BLOKK- ÉS SORSZINTŰ ELEMEK ÉS DOBOZOK
A bekezdés egy úgynevezett blokkszintű elem, míg a tartalma – a szöveg, a kiemelt szöveg és a hivatkozás –, úgynevezett inline vagy sorszintű elemekből áll. A legfőbb különbség a kétféle elem- és doboztípus között az, ahogyan a weboldal normálfolyamában viselkednek.
A blokkszintű elemek blokkdobozokat alkotnak, amelyek függőlegesen, egymás alatt jelennek meg a weboldal normálfolyásában
A blokkszintű weboldalelemek által alkotott blokk dobozok függőlegesen követik egymást az oldalban, tehát egymás alatt jelennek meg. A képen látható példában egy ‹div›-et, két bekezdést és egy felsorolást (rendezetlen listát) helyeztünk el az oldalban. A stíluslapon mindegyiknek vékony keretet, 2 pixeles margót és ugyanekkora eltartást (a kerettől) állítottunk be. Az azonos struktúraszinten levő oldalelemek – ‹div›, ‹p›, ‹p›, ‹ul› – négy jól elkülönülő blokk dobozként jelennek meg egymás alatt, míg az egy szinttel beljebb levő, az ‹ul›-be beágyazott két listaelem (‹li›) maga is két, jól elkülönülő blokk doboz, persze a lista dobozán belül (‹ul›).
A sorszintű elemek vízszintesen, egymás mellett jelennek meg a weboldal normálfolyásában
A sorszintű elemek is egymás után jelennek meg az oldalban, ám a blokkokkal ellentétben, ők vízszintesen követik egymást. Ezt rendkívül egyszerű belátni, ha arra gondolunk, hogy minden egyes betű vagy karakter, amit egy szöveg részeként meg szeretnénk jeleníteni a weboldalban, egy-egy sorszintű elem, ami az előtte álló másik sorszintű elemmel – az előző betűvel – egy sorban fog megjelenni, egészen addig, amíg el nem érik a sor végét, amikor is a következő áthuppan a következő sorba. Tipikus sorszintű elem a hivatkozás (‹a›), a szövegek kiemelésére használt ‹strong› és ‹em›, de a kép is (‹img›). Utóbbi talán egy kicsit meghökkentő első olvasásra, hiszen egy képre hajlamosak lehetünk úgy gondolni, mint egy nagyobb blokkra a weboldalon belül. Pár leckével korábban már megtanultuk, hogy az ‹img› taget csak akkor használjuk, ha a képnek a tartalomhoz van köze (mint például egy szövegblokkban megjelenő illusztráció), díszítőelemként soha!
Mivel a kép is sorszintű elem, rá is ugyanezek a szabályok vonatkoznak
A sorszintű elemek tehát kicsit másképp viselkedő, sor (jellegű) dobozokat alkotnak. Érdemes tudni, hogy maga az összefüggő szöveg is egy ilyen doboznak számít. Ha tehát ránézünk az alábbi címsorra,
‹h3›Sok beszédnek sok az alja‹/h3›
két dobozt kell látnunk: a ‹h3› tag által létrejövő blokk, és a szöveges tartalom által létrejövő sor dobozt. A korábbi bekezdéses példánk pedig tobzódik a dobozokban: maga a bekezdés ugye létrehoz egy blokkszintű, míg a tartalma számos sorszintű dobozt. Külön doboznak számít a sor elején álló névelő, az „és az”, valamint a „nevében üdvözöljük...” sima szöveges részek, továbbá a két kiemelt (‹em›...‹/em› által határolt) szöveg és természetesen a végén levő hivatkozás is. Összesen hét doboz. Egyébként a Firebug ennek megértésében is sokat segít: bal oldali ablaktáblájában, forráskódban úgy jeleníti meg a bekezdés tartalmát, hogy minden olyan rész, ami külön sorszintű dobozt alkot, külön sorba kerül.
A Firebug segít megérteni a „dobozanatómiát”: a blokkdobozt alkotó bekezdésen belül 6 másik sor dobozt találunk (a számozást már mi tettük oda)
A SZABÁLY AZ SZABÁLY
Nézzünk néhány egyszerűen megjegyezhető szabályt, amit be kell tartanunk, ha az XHTML szabványnak megfelelő, szabályos weboldalakat szeretnénk készíteni. Például sorszintű elem sohasem állhat önmagában, mindig csak egy blokkszintű elemen belül szerepelhet az oldalban. Nem csinálhatunk tehát olyan oldalt, amely mindössze egyetlen képből vagy hivatkozásból áll, mert az nem lesz szabályos, mint a mellékelt ábra mutatja.
Sorszintű elem nem állhat önmagában egy weboldalon belül, azt mindig egy blokkszintű elembe kell foglalnunk
A Validator pontosan meg is mondja, mi a baj: a dokumentum típusa (azaz az XHTML 1.0 strict szabvány) szerint nem állhat ‹a› tag azon a ponton, hiányzik valamilyen blokkszintű elem előle, és fel is sorol néhány lehetőséget a javításra. Ha a hivatkozást betesszük, mondjuk, egy ‹div›-be, máris meg lesz velünk elégedve
A Validator örömmel nyugtázza, hogy kiköszörültük a csorbát
Szintén fontos szabály, hogy sorszintű elem nem tartalmazhat blokkszintű elemet! Egy hivatkozás sosem tartalmazhat bekezdést, ez kizárólag fordítva fordulhat csak elő: előbb nyitunk egy bekezdést, aztán azon belül jöhet a hivatkozás! Akár a bekezdés teljes szövegét is hivatkozássá alakíthatjuk így.
Sorszintű elem nem tartalmazhat blokkszintű elemet – ez kizárólag csak fordítva fordulhat elő...
...ettől még megoldható, hogy az egész bekezdésünk egyben hivatkozás is legyen
Sorszintű elem természetesen tartalmazhat más sorszintű elemet is, amire a legegyszerűbb példa, ha egy szövegrészt annyira szeretnénk hangsúlyozni, hogy „rádobjuk” a ‹strong› és az ‹em› tageket is, amitől az adott szöveg – alapbeállítások szerint – vastag dőlt betűkkel fog megjelenni. Ilyenkor nagyon vigyázzunk, hogy mindig az utoljára nyitott taget zárjuk be először!
Sorszintű elemek egymásba ágyazva – megengedett, ha figyelünk a tagek helyes sorrendben történő bezárására
A blokkszintű elemek esetén már nem ilyen egyszerű a helyzet, ugyanis mindegyikre külön-külön meg van szabva, hogy mit tartalmazhat és mit nem. Ha valakit ez részletesebben érdekel, mélyedjen el az XHTML és a CSS-szabványok leírásában és/vagy kísérletezzen bátran mindig keze ügyében tartva a Validatort, hogy ellenőrizni tudja az oldal szabályosságát.
FORMÁZZUNK DOBOZT!
Tekintsük át, hogy milyen alapvető formázási lehetőségeink vannak a blokkszintű weboldalelemek által létrehozott blokkdobozok esetében. Az előző lecke óta tudjuk, hogy ennek a doboznak van margója, kerete, eltartása és természetesen mérete – szélessége és magassága – is.
Szélesség, magasság
A blokkdobozok szélességét a width, magasságát a height CSS-tulajdonsággal tudjuk beállítani. Ha nem adjuk meg őket, a blokkdoboz addig „nyújtózik”, amíg azt az őt befoglaló elem engedi. Ha például a weboldalunk egyetlen bekezdésszövegből áll, aminek nem állítunk be konkrét méreteket, akkor vízszintesen „faltól-falig”, függőlegesen pedig egészen addig tart, ameddig a benne levő szöveg ér. A stíluslapok nyelvén ez a következőképpen néz ki:
p {
width: auto;
height: auto;
}
Hogy a „faltól-falig” milyen széles lesz, azt az őt befoglaló elem mérete határozza meg – ebben az esetben ez a ‹body›, azaz maga a weboldal. Mivel a ‹body› is egy blokkdoboz, ő is addig nyújtózik, amíg lehet, neki viszont csak a böngésző megjelenítési területe szab határt, ezt igyekszik kitölteni.
A blokkszintű elem által létrehozott blokkdoboz vízszintesen kitölti a rendelkezésére álló „teret”
Ha megnézzük az idevágó képet, láthatjuk, hogy bár a bekezdés utolsó sora nem ér el egészen a weboldal jobb széléig, ettől még a blokkdoboz természetesen arra a területre is kiterjed. (A bekezdés háttérszínét sárgára színeztük, hogy nagyjából képet kapjunk a blokkdobozunkról.)
A doboz méretét megadhatjuk abszolút vagy relatív módon. Az előbbi esetben konkrétan meghatározzuk, hogy milyen széles legyen, például:
width: 500px;
Ha viszont azt szeretnénk, hogy pont fele olyan széles legyen, mint a weboldal, nyilván nem fogunk nekiállni képpontokat számolgatni, hanem relatív beállítást használunk:
width: 50%;
A fölső bekezdés szélességét a p1 osztálydefinícióval 500 képpont szélesre, az alsót a p2-vel a rendelkezésére álló terület felére állítottuk be
A példában létrehoztunk két osztályt (p1, p2). Az egyiknek 500 képpont szélesre állítottuk a szélességét, a másiknak 50%-ra. A HTML-kód mindössze három, eredetileg teljesen egyforma bekezdésből áll, amelyek közül a másodikat hozzárendeljük a p1, a harmadikat pedig a p2 osztályhoz. Így kapjuk meg a fenti végeredményt.
Az első bekezdés magassága pont akkora, mint amekkorát a tartalom igényel (auto), a második 100, a harmadik 30 képpont magas – utóbbi kevésnek bizonyul ezért a tartalma kifolyik a dobozból
Míg a doboz tartalma tiszteletben tartja a beállított szélességet és valóban csak addig terjeszkedik, amekkorára engedjük, a magassággal egész más a helyzet. A példában az első bekezdésnél nincs beállított magasság, így az alapértelmezett auto értéket használja, tehát a doboz pont akkora lesz, amekkorát a benne levő tartalom megkíván. A p1 osztályt ezúttal úgy állítottuk be, hogy 100 képpont magas legyen, látszik is, hogy jóval nagyobb, mint a benne levő szöveg mérete. A harmadik esetben (p2 osztály) 30 képpontra állítottuk a magasságot és ezzel konfliktust okoztunk a bekezdés mérete és a tartalma között – utóbbinak ugyanis több helyre van szüksége, ezért túlcsordul.
Arról, hogy ez a túlcsordulás ténylegesen megjelenjen-e az overflow CSS-tulajdonság rendelkezik, amelynek alapbeállítása a visible, azaz látható. Egészítsük ki a p2 osztály definícióját a
overflow: hidden;
beállítással, és látni fogjuk, hogy a beállított 30 képpontos magasságnál a CSS „elkaszálta” a bekezdésünket.
A tartalmat az overflow stílustulajdonsággal taníthatjuk móresre: a 30 képpont még mindig kevés, de most nem folyik ki belőle semmi
Margók
A margó a legszélső „öv”, amely négy oldalról körbeveszi a blokkdoboz tartalmát. Ennek megfelelően négy különálló CSS-tulajdonság írja le a méretét (felső, alsó, bal, jobb):
margin-top: 20px;
margin-bottom: 0px;
margin-left: 10px;
margin-right: 50px;
Ha külön-külön kell beállítanunk valamelyik margóméretet, akkor ezek közül használhatjuk valamelyiket. Van azonban egy másik lehetőség is, a rövidebb margin tulajdonság, amellyel egyszerre adhatjuk meg akár mind a négy margóméretet. Érdekessége, hogy többféleképpen is működhet. Az alaphelyzet, amikor valóban megadjuk mind a négy méretet, mégpedig felülről indulva és az óramutató járásával megegyező irányban, felső, jobb, alsó, bal sorrendben. A
margin: 20px 0px 10px 50px;
pontosan ugyanazt eredményezi, mint a külön-külön megadott fenti példa.
Margóbeállítás kétféleképpen, de ugyanazzal az eredménnyel – a piros keret az alsó bekezdés margóit mutatja
Ha szimmetrikus margókat akarunk beállítani, hagyjuk el az utolsó két értéket. Ilyenkor az első a felső-alsó, a második a bal-jobb margókra vonatkozik. A
margin: 10px 5px;
tehát 10-10 képpontos felső és alsó, és 5-5 pixeles bal-jobb oldali margót állít be.
Végül a harmadik lehetőség, amikor egyetlen értéket adunk meg, amely – kitalálható – minden oldalra vonatkozni fog, tehát a
margin: 10px;
mind a négy oldalon 10 pixeles margót állít be.
Nagyon fontos szabály a margókkal kapcsolatban – volt már róla szó korábban –, hogy két blokkdoboz között a felső-alsó margók átfedik egymást! Ha tehát egymást követő két bekezdésünknél 10-10 pixeles felső-alsó margókat állítunk be, kettejük között csak 10 képpont üres hely keletkezik. Amennyiben a találkozó margók eltérő méretűek, a nagyobb méretűnek megfelelő hely lesz a két doboz között.
Keret
A keret a második a doboz tartalmát övező „héjak” körül. A keret megjelenését alapvetően három tulajdonság befolyásolja: beállíthatjuk a színét, a kinézetét (stílusát) és a vastagságát.
border-color: red;
border-style: solid;
border-width: 20px;
Ezzel egy 20 pixel vastag, normál piros keretet állítottunk be a doboz mind a négy oldalán (a solid azt jelenti, hogy teljes vonalból áll a keret, nincs megszakítva).
Bekezdés 30 pixeles margóval és piros, 20 pixeles kerettel
Ezek a stílusdefiníciók hasonlóan használhatók – egy, kettő vagy négy értéket megadva –, ahogy azt a margó esetében a margin tulajdonságnál láttuk. Természetesen lehetőség van arra is, hogy a keret egyes oldalainak tulajdonságát ne csoportosan, hanem egyesével adjuk meg. Az oldal nevét a border- után kell beszúrnunk, például:
border-top-color: green;
border-left-style: double;
border-right-width: 5px;
A felső keretet zöldre, a bal keretet duplacsíkosra, végül a jobb oldalit 5 képpont szélesre állítjuk.
Könnyen kiszámítható, hogy már így is tetemes számú kerettulajdonságunk van, de ez még semmi! A beállításokat ugyanis össze lehet vonni oldalak szerint is, így tehát van border-top, border-bottom, border-left és border-right tulajdonság is, sőt van maga a border, ami hasonló módon, összevontan rendelkezik valamennyi keretoldal tulajdonságairól. Az egyes jellemzőket ilyenkor méret–stílus–szín sorrendben kell megadnunk, például a
border: 4px dotted blue;
a keret mind a négy oldalát 4 képpont vastag, kék pöttyözöttre állítja. Ha valakit bővebben érdekel a téma, nézze meg a W3C webes iskolájának idevágó fejezetét a www.w3schools.com/css/css_border.asp címen, ahol például a border-style leírásánál megtekinthetők a lehetséges keretstílusok. A nagyon extrémekkel vigyázzunk, mert nem biztos, hogy minden böngésző támogatja őket!
Eltartás
Az eltartás (padding) a keret és a doboz tartalma közötti rész, és az előző leckében megbeszéltük, hogy milyen fontos szerepet tölt be, miért nem szabad megfeledkezni róla. CSS-szempontból pontosan ugyanúgy állítható, mint a margók:
padding-top: 10px;
padding-bottom: 0px;
padding-left: 5px;
padding-right: 5px;
és ugyanúgy megvan az összevont padding CSS-tulajdonság is, amellyel egyszerre állíthatjuk akár külön-külön, akár egyszerre az összes eltartás méretét.
A margó és az eltartás közötti fontos különbség, hogy az eltartás „alatt” a doboz saját háttere, míg a margó „mögött” esetleg a weboldalelemünket befoglaló elem hátterét látjuk. Ezzel majd a háttér beállítása kapcsán később részletesen is foglalkozunk.