Detalj koji možda najviše problema pravi početnicima i nekima koji su navikli na tabelarni prikaz je CSS box model i razumevanje istog.
Definicija Box modela bi mogla glasiti ovako: Box Model je programski okvir koji nam CSS pruža radi formatiranja i/ili redefinisanja bilo kog datog HTML elementa.
Drugim rečima, browser čita sirov HTML kod, interpretira, a zatim prikazuje korisniku. CSS "uskače" između HTML-a i browsera, menjajući prikaz. CSS kreira imaginarnu kutiju (engl. box) oko elementa, oko sadržaja, omogućujući nam da tu kutiju stilizujemo kako želimo, u svim njenim aspektima. Odatle je nastao izraz CSS Box model.
Ranije, tokom ’90-ih godina prošlog veka i početkom prošle decenije tabele su bile osnovni alat za bilo kakvo raspoređivanje elemenata na strani jer nije bilo CSS-a. Pojavom pune podrške za CSS od 2000. godine stvari počinju da se menjaju i polako dolazimo do pravog razdvajanja sadržaja i stilizacije. Danas se tabele koriste isključivo za šta su i namenjene, za tabelarni prikaz podataka. Svi moderni sajtovi koriste div elemente za razdvajanje celina sadržaja, a onda te elemente uređujemo, tj. stilizujemo putem CSS-a. Ipak, i danas možemo videti sajtove na netu koji i dalje koriste prevaziđene tehnike, ali to je neko drugo pitanje.
Prikazani regioni na jednom od najčešćih rasporeda
Na slici iznad prikazan je jedan čest raspored na modernim sajtovima, odnosno njihovim stranama. Svaki pravougaonik predstavlja jedan div, jednu celinu.
Uglavnom se postavlja okružujući div koji "nosi" celu stranu (wrapper), a onda se drugim divovima odvajaju određene celine. Sve što se tiče rasporeda, dimenzija, boja i ostalih vizuelnih detalja, spada u domen CSS-a. Bez stilizacije, ista strana bi bila predstavljena, raspoređena kao na sledećoj slici. U tom slučaju browser prikazuje čist sadržaj.
Regioni bez CSS-a
Svaki elemenat na strani, pa čak i inline elementi spadaju pod box model i zato je veoma važno pravilno ga razumeti i razjasniti.
Radi lakšeg predstavljanja, u ovoj lekciji svi elementi u dokumentu su dati kao pravougaoni boks čiji je sadržaj okružen svojstvima: Margin, Padding i Border.
Box Model se sastoji od pet osnovnih svojstava elemenata:
Margine su uvek transparentne i odvajaju element od drugih elemenata na stranici. Okviri (Borders) mogu biti različitih stilova i definišu granice elementa. Padding odvaja sadržaj elementa (Content) od njegovih okvira. Background podešavanja elementa se odnose na oblast unutar okvira zajedno sa Padding i Content delom (na slici Padding deo je prikazan u nešto tamnijoj sivoj boji, mada je realno nevidljiv).
Margins, Borders i Padding svojstva za svaku stranu elementa (Top, Right, Bottom, Left) mogu biti različite vrednosti. Po default vrednostima, ova svojstva su u većini slučajeva 0. Margine mogu imati i negativnu vrednost.
Važno je zapamtiti da Width i Height vrednosti određuju samo širinu, odnosno vidinu sadržaja (content) elementa. Realna visina i širina koje elemenat zauzima na strani je Content + Padding + Border.
Na primer, ukoliko je sadržaj 100 x 100 piskela, padding je 10px (sa svih strana), a border 2px (takođe sa svih strana), mesto koje takav elemenat zauzima je 124 x 124 piksela. To je zato što je širina ukupno: 100px za sadržaj + 10px za padding x2 zbog levog i desnog paddinga + 2px za border x2 jer imamo levu i desnu. (100 + 10x2 + 2x2 = 124px). Isto je i za visinu.
Div elemenat (boks) može sadržati i više drugih elemenata, kreirajući hijerarhiju, što predstavlja ugnježdene elemente stranice. Prozor čitača u ovoj hijerarhiji predstavlja Root (koreni) element.
Postoje dva osnovna tipa elementa: Block i Inline, koje smo ranije pomenuli kod osnovnih tagova. Ipak, tip boksa može biti određen korišćenjem svojstva Display kroz CSS. Ako na primer, svojstvu Display nekog Inline elementa dodelimo vrednost Block, tada će taj element biti tretiran kao i svaki drugi Blok element.
Boks neće biti vidljiv ako svojstvu Display dodelimo vrednost None. U tom slučaju, browser će se ponašati kao da element ne postoji, mada će biti u kodu. Takođe i bilo koji ugnježdeni elementi unutar tog elementa neće biti prikazani iako im je dodeljena neka druga Display vrednost.
Na primer, span tag je inline elemenat. Ukoliko dodelimo display:block vrednost, ponašaće se, praktično, kao div. Ukoliko sa druge strane postavimo display:none, pomenuti span neće biti vidljiv. Ipak, morate zapamtiti da pomoću ove opcije ne uklanjamo kompletno elemenat već samo sakrivamo njegov prikaz, ali korisnik može uvek očitati sirov HTML kod koji sadrži taj deo. Ne bi trebalo sakrivati tako neke osetljive podatke.
Kod pozicioniranja elemenata možemo razlikovati sledeće tipove:
Static i relative pozicioniranje čine normalni tok dokumenta.
Normal Flow je default način rada kod pozicioniranja. U okviru njega se sadrži static 1 i relative pozicioniranje. Primenjuje se na sve elemente koji nemaju specificiranu poziciju putem Absolute ili Fixed i koji nisu Floated. Blok (block) elementi su pozicionirani jedan ispod drugog po vertikali, dok su Inline elementi pozicionirani po horizontali, sleva nadesno.
Vertikalne margine kolapsiraju (preklapaju se) u normalnom toku dokumenta. To znači da se umesto sabiranja vrednosti margina gornjeg i donjeg elementa računa samo margina koja je veća - kao što je ilustrovano na slici ispod. Horizontalne margine nikad ne kolapsiraju.
Float (plutajući elementi)
Floating se ostvaruje preko svojstva Float sa vrednostima left (levo) i right (desno). Kada dodelimo ovu vrednost nekom elementu, on izlazi iz normalnog toka koji smo malopre pomenuli i ponaša se drugačije. Vertikalno je pozicioniran na isti način (kao kod normal flow), dok je po horizontali pozicioniran skroz levo ili desno koliko je moguće unutar svog bloka u kome je sadržan. Okolni Inline sadržaj je tada pozicioniran na suprotnoj strani.
Sledeći kod i slika ilustruju Floated element:
<p> <span style="float:right; width:30%;">content...</span> content content content content content content content... </p>
Za razliku od bokseva u normalnom toku, vertikalne margine floated elemenata nikada ne kolapsiraju sa marginama elemenata iznad ili ispod. Flaoted boks može da preklopi susedne elemente koji su u normalnom toku i uopšte da naruši raspored stranice ukoliko nije adekvatno primenjen.
Sledi primer kôda i slika gde floated element ima mnogo više teksta nego njegov sadržajni blok.
<p> <span style="float:right; width:30%;"> content content content content content content content... </span> content content content content content content </p> <p> content content content content content content content content content content content content </p>
U ovom slučaju možemo primetiti da se floated element preklapa preko svog parent elementa, ali i elementa koji dolazi posle njega. Ovo se može izbeći dodavanjem svojstva clear.
Postavićemo clear:right drugom elementu. Ovo pravilo će ga pomeriti nadole, odmah ispod floated elementa. Time smo postavili da on otpočne tek pošto se završi float.
<p> <span style="float:right; width:30%;"> content content content content content content content... </span> content content content content content content </p> <p> content content content content content content content content content content content content </p>
Floated element se i dalje preklapa sa elementom na vrhu, ali tako je namerno postavljeno u cilju demonstracije. Ovo preklapanje možemo izbeći kada bi floated element postavili izvan p taga. Time bismo dozvolili da oba paragrafa budu pozicionirana oko floated elementa.
<span style="float:right;width:30%;"> content content content content content content content... </span> <p> content content content content content content </p> <p> content content content content content content </p>
Kada je elementu dodeljeno svojstvo position:relative, tada je element inicijalno pozicioniran prema pravilima normalnog toka, ali uz određene razlike u odnosu na static.
Element možemo pomeriti iz njegovog osnovnog položaja, dok će prostor koji on zauzima na osnovnoj poziciji ostati prazan. Pomeramo ga prema Offset svojstvima, koje mogu biti Left, Right, Top i Bottom. Vrednost svakog ovog svojstva predstavlja razdaljinu za koju bi odgovarajuća ivica elementa trebalo da bude pomerena u odnosu na poziciju elementa u static varijanti.
Static i Relative pozicioniranje
Boks 1 koristi relativno pozicioniranje da bi se pomerio udesno za 120px u odnosu na njegovu startnu poziciju. Boks 2 i Boks 3 ostaju u istom mestu, nepromenjene pozicije, (ponašaju se kao da Boks 1 nije ni promenio poziciju, tj. kao da je ostao na istom mestu) jer relativno pozicioniranje ne pomera elemente iz normalnog toka.
Elemenat može biti relativno postavljen u odnosu na stranicu ili relativno u odnosu na roditeljski element. U vezi sa ovim načinom pozicioniranja trebalo bi biti oprezan jer se može desiti da dobijemo "rupe" u sadržaju.
Elementi sa svojstvom position:absolute se uklanjaju, tj. pomeraju iz normalnog toka i ne utiču na ostale elemente. Pozicija elemenata se određuje na osnovu Offset vrednosti koje mogu biti Left, Right, Top i Bottom. Ove vrednosti se ponašaju skoro isto kao i kod relativnog pozicioniranja, sem što se kod apsolutnog pozicioniranja element pomera u odnosu na roditeljski element, koji takođe mora biti pozicioniran, tj. kome je dodeljeno svojstvo position. Najlakše je dodati position:relative roditeljskom elementu ako njega ne želimo da pomeramo.
Apsolutno pozicioniranje nam dozvoljava da definišemo gde bi element trebalo da bude pozicioniran apsolutno u odnosu na stranicu ili u odnosu na roditeljski element.
Absolute pozicioniranje
Boks 1 je apsolutno pozicioniran, Left i Top svojstva ga pomeraju na desno i dole, a Boks 2 i Boks 3 se ponašaju kao da Boks 1 ni ne postoji i zauzimaju njegovu poziciju u normalnom toku. Zbog svoje nove pozicije Boks 1 se preklapa sa Boksom 3 i bilo koja promena u sadržaju Boksa 3 ne utiče na poziciju ostala dva elementa.
Fiksno pozicioniranje je specijalan način apsolutnog pozicioniranja. Kada se skroluje stranica, fiksiran element se ne pomera kao i svi ostali elementi. Ovaj atribut se ne ponaša isto u svim čitačima, a IE6, kao i ranije verzije Internet Explorera ga uopšte ne podržavaju.
#mojElement { position:fixed; left:10%; }
Element je pomeren na desno za 10% od ukupne širine prozora čitača i fiksiran je u tom mestu tako da, kada skrolujemo kroz stranicu, mojElement ostaje na istom mestu.
Ranije verzije Internet Explorera su imale bag vezan za određivanje širine i visine elemenata. Naime, eksplicitno uneta širina/visina u IE je uključivala i border i padding dok kod W3C specifikacije širina/visina određuje samo širinu/visinu sadržaja, a potom se dodaju border i pading, kako smo pomenuli ranije.
Poređenje W3C i IE (pre verzije 6) box modela2
Ovaj detalj je stvarao velike probleme pri kreiranju rasporeda stranica jer nije bilo moguće jednostavno definisati uniformnu širinu/visinu elemenata za sve browsere. Srećom, od IE verzije 6 i nadalje, problem je rešen i IE poštuje W3C standard.
Pomenuti Internet Explorer stvara i dalje velike probleme web dizajnerima i developerima u verziji 6, ali i verzijama 7 i 8. Tek verzija 9 je donela drastičnija poboljšanja, mada i dalje kasni za modernim browserima kao što su Chrome, Firefox i Opera. Očekuje se da će tek najavljeni IE10 biti u skladu sa modernim standardima.
1 Kod nekih autora se ne koristi termin static, već se označava kao normal ili default.
2 Izvor slike http://en.wikipedia.org/wiki/File:W3C_and_Internet_Explorer_box_models.svg