Box Model probléma és megoldás IE alatt

Aki foglalkozik táblázatok nélküli lapszerkezetek építésével, az már biztos belefutott (ha nem, akkor bele fog) abba a problémába, hogy a szépen beállított dobozszélességek másképp jelennek meg a böngészők alatt. “Meglepő” módon megint az IE-vel van a baj.
A problémát a neten “box model hack” néven lehet megtalálni és már elég sok helyen leírták. Ha már utánanéztél, valószínűleg itt sem fogsz egetverő újdonságokat találni, a cikk célja inkább csak annyi, hogy egyszer már rendesen összeszedjem erről az anyagot és ne kelljen ismerősöknek a linkeket keresgélnem, ha szóba kerül a téma.

A probléma leírása

A IE 5.x és 6 bizonyos esetekben másképp értelmezi a box model-t, mint a többi böngésző. A szabvány szerint a szélességhez (width) nem tartozik hozzá a padding, a border és a margin. Az IE ezzel igen, mert a szélességbe beleszámolja a padding-t és a border-t is.

Emiatt pl. Firefox alatt ha egy elemnek az alábbi tulajdonságai vannak:
width: 200px; padding: 20px; border: 20px;
A valós szélessége az elemnek 200px + 2x20px + 2x20px = 280px

IE alatt:
width: 200px; padding: 20px; border: 20px;
A valós szélessége az elemnek 200px marad és összenyomja a tartalmat.
Ahhoz, hogy a szabványkövetőknek megfelelő megjelenést kapd meg, az IE-nek úgy kell tudnia, hogy a szélesség 280px (width: 280px)

Az alábbi kép ábrázolja a fent leírtakat

A megoldások

Szerencsére többféle megoldás is van az IE ilyen jellegű butáságára, melyek közül a számomra szimpatikusabbakkal fogom kezdeni.

1.) használj megfelelő doctype-t

Ha nem szükséges, hogy az IE6 előtti IE verziók és helyesen jelenítsék meg box model-t, akkor elég ha annyit teszel, hogy a dokumentumnak megfelelő doctype-t adsz, mellyel szabványos módba kapcsolod. (IE 5.x tesz a doctype-ra, rosszul jeleníti meg.)

XHTML 1.0 – Transitional

1
2
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

2.) Box-in-a-box

Megoldást jelent a problémára, ha a problémás DIV-nek nem adunk meg width-t, padding-t és border-t. Helyette 2db DIV-et kell felvenni, egyiknek beállítani a width-t, a másiknak pedig padding-t és border-t adni.

1
2
div.valami1 { width: 300px; }
div.valami2 { padding: 10px; }
1
2
3
<div class="valami1">
  <div class="valami2">Text</div>
</div>

Fontos!
IE-ben egy 100%-os szélességű táblázat szintén problémát okoz, tehát ez a megoldás csak akkor jó, ha nem ‘width=”100%”‘-os táblázatot akarunk a DIV-ben elhelyezni.

3.) Böngészőfüggő CSS használata

Conditional comment-ekkel meg lehet mondani, hogy az IE egyes verziói honnan töltsék be a CSS-t. Így a kód tiszta és átlátható marad, viszont hátrányként meg kell említenem, hogy több CSS fájlt kell karbantartani.

1
2
3
<!--[if IE 6]>
  <link rel="stylesheet" href="ie6.css" type="text/css" media="all" />
<![endif]-->

Bővebb információkért olvasd el “Böngészőfüggő CSS – feltételek segítségével” című leírásomat.

4.) box model hack-ek

a.) The Simplified Box model Hack (SBMH)

1
2
3
4
5
6
7
8
/* Alap szélesség, normális böngészőknek */
div { 
  width: 150px;
  }
div {            /* előző felülírása */
  \width: 200px; /* IE 5.x ezt tudja értelmezni */
  w\idth: 150px; /* csak a modernebb böngészők tudják értelmezni */
  }

b.) A Modified SBMH (Tan hack)

1
2
3
4
5
6
7
div {
  width: 150px;
  }
* html div {     /* csak az IE tudja értelmezni */
  width: 200px;
  w\idth: 150px; /* az IE 5.x nem tudja értelmezni */
  }

c.) Komment hack

1
2
3
4
5
div {
  width: 200px;
  width/* */:/**/150px;
  width: /**/150px;
  }

d.) Important + komment hack 1.

1
2
3
4
5
div {
  width: 150px !important;
  width: 200px;
  width/**/:/**/150px;
  }

e.) Important + komment hack 2.

1
2
3
4
div {
  width: 150px !important;
  width /**/:200px;
  }

f.) Cycloid’s Tiny Box Model Hack (ezzel nem lesz W3C valid a CSS kód)

1
2
3
4
div {
  width:   150px;
  width:   "200px";
  }

felhasznált irodalom

The IE box model and Doctype modes – http://css.maxdesign.com.au/listamatic/about-boxmodel.htm
Quirks mode and strict mode – http://www.quirksmode.org/css/quirksmode.html
CSS box model hack – http://hac.kers.hu/CSS-box-model-hack_a12.html
Tantek – box model hack – http://www.tantek.com/CSS/Examples/boxmodelhack.html
Why does the CSS box model need a hack? – http://css-discuss.incutio.com/?page=BoxModelHack
Recommended DTDs to use in your Web document – http://www.w3.org/QA/2002/04/valid-dtd-list.html

Quirks mode

9 HOZZÁSZÓLÁS

  1. A doboz model formázásainál érdemes arra is figyelni, hogy IE esetén nem beállított formázások (margin, padding) elvárt 0 értékkel jelennek meg (IE7 alatt tapasztaltam), a többi böngészö (Netscape 9, Firefox 2, Opera 9) pedig esetleg egy felsőbb elem értékét örökli (még ha specializált osztály is).

    Tipikusan ilyen formázási különbség még az “ul – li” listaelemek formázása (aki esetleg menüelemekhez használja), ahol IE eltérő margin/padding értéket használ a többi böngészőhöz képest. (az eredmény: listával formázott menü elcsúszik, ha nem IE a böngésző, és nincs maximálisan beszabályozva a margin/padding érték).

    Végkövetkeztetés: Ki kell próbálni több böngészőn is az eredményt, és jobb a mindenre kiterjedő beállítás, pl.: ul { margin: 0 0 10 0} li { margin 0 0 0 0}

  2. a példáknál hívnám fel a figyelmet egy apró hibára: osztály nevét sose kezdjük számmal! tehát a class=”1″ nagyon nem szerencsés megoldás, lehet hogy valamelyik doctype-nál észreveszik a böngészők, én azt szoktam tapasztalni hogy figyelmen kívül hagyják ezeket… class=”layer-1″ vagy valami ilyesmi jobb lesz :)

    de nem ezért írok…

    —-

    mutatni akarok egy saját fejlesztésű megoldást. hasonló a box-in-a-box-hoz, de kevesebb formázással jár… hozzá is látok a mutatáshoz! előszöris vegyünk egy alap div formázást:

    div
    {
    background-color: transparent;
    background-image: none;
    border-style: none;
    display: block;
    margin: 0px;
    padding: 0px;
    height: auto;
    width: auto;
    text-align: center;
    }

    ezek többnyire default értékek, de mivel általában (most meg biztosan) “többrétegű” a lapunk, az öröklődés miatt meg kell határozni őket. konkrétan a “display”-re fektetném a hangsúlyt, alapból is “block”-ként jelennek meg, de ha valamelyik szülő divnek mást írunk be, akkor az öröklődik a következő egy darab szintre, és ez mindent felborít… a példához, pontosabban a “technikámhoz” fontos hogy ez alapból block-ként legyen kezelve!

    meghatározunk még egy div-et, ez az egész kulcsa, sokszor fogjuk használni, erre értettem az elején, hogy kevesebb formázással jár. ugyanis írhatjuk a régi megszokott rendszerünk szerint a kódot, csak ennek az egynek a (sokszori) beillesztésére lesz szükség. az ilyen általánosan használt osztályokat szoktam 0 sorszámmal ellátni, ezért ez lesz a layer-0…

    div.layer-0
    {
    display: table;
    width: 100%;
    }

    mi a haszna ennek? ha csak egy szövegünk van és egy div-ünk, és azt szeretnénk, ha a szövegnek margója legyen, akkor ezt csináljuk:

    blabla
    blabla
    blabla

    mit látunk? hogy a szöveg alatt és fölött a margónak nincs háttérszine. ezért betesszük a 0-s layert! és rögtön azt kapjuk, amit akartunk…

    blabla
    blabla
    blabla

    persze ilyen egyszerű esetekben ezer másik megoldás is célravezető… de ha két-három divet ágyaznánk egymásba, amiknél nem használunk keretet, margót viszont adunk nekik, az egész szétesik vagy rosszul jelenik meg. írok egy kicsit bonyolultabb példát (először “layer-0” nélkül, majd vele), ami jobban prezentálja a módszer hatékonyságát:

    blabla

    blabla

    ez nem az, amit látni akartunk… akkor próbáljuk ki máshogy:

    blabla

    blabla

    na ez már az! :) még változtathatunk rajta annyit, hogy a “cellák” közötti és az egész “tábla” melletti tér egyforma széles legyen…

    blabla
    blabla
    blabla
    blabla

    blabla
    blabla

    csak betettem a “pink” hátterű dobozt… egyszerűen ügyes, precíz dolgokat el lehet így érni! (ja, és tessék kipróbálni a legutóbbi példát layer-0 nélkül… nem egy szép látvány…)… az egész “találmányom” egyébként arra vezethető vissza, hogy pontosan valami ilyesmi kinézetet szerettem volna elérni egy lapon… azóta mindig ezt használom, és minden esetben jó szolgálatot tesz, nem keveredik bele az ember, hogy az adott doboznak éppen milyen a megjelenése (block vagy table) vagy hogy éppen van e körülötte margó vagy border… (ja, és a padding-ok nálam mindig 0-n vannak… arra törekszek mindig hogy csak kevés tulajdonságot kelljen egy-egy elemnek adni…) szerintem ez a legegyszerűbb és legjobb megoldás a dobozproblémákra. ie, firefox, opera alatt hiba nélkül jelenik meg minden esetben!

    írhatok róla esetleg tutorialt, látványosabb megjelenésekkel. bár aki eféle problémával idetéved, az olvashatjaa kommentet, remélem segítettem valamit! :)

  3. hát, ezt nem sikerült beírni… a legutolsó html forrást azért mégegyszer ideteszem, “kacsacsőrök” helyett szögletes zárójelek közé zárva…

    [body style=”margin: 0px; padding: 0px;”]
    [div style=”background-color: red; width: 512px;”]
    [div class=”layer-0″]
    [div style=”background-color: pink; margin: 8px;”]
    [div class=”layer-0″]
    [div style=”background-color: green; width: 50%; float: left;”]
    [div class=”layer-0″]
    [div style=”background-color: blue; margin: 8px;”]
    [div class=”layer-0″]
    [p style=”margin: 16px;”]blabla[/p]
    [p style=”margin: 16px;”]blabla[/p]
    [p style=”margin: 16px;”]blabla[/p]
    [p style=”margin: 16px;”]blabla[/p]
    [/div]
    [/div]
    [/div]
    [/div]
    [div style=”background-color: green; width: 50%; float: left;”]
    [div class=”layer-0″]
    [div style=”background-color: blue; margin: 8px;”]
    [div class=”layer-0″]
    [p style=”margin: 16px;”]blabla[/p]
    [p style=”margin: 16px;”]blabla[/p]
    [/div]
    [/div]
    [/div]
    [/div]
    [/div]
    [/div]
    [/div]
    [/div]
    [/body]

  4. Igazad van, a példánál nem figyeltem erre a számmal kezdődő dologra, de igaz amit írtál úgyhogy kijavítottam ott a cikket.
    Sajnos ahogy látom kiszedte az összes formázást már az első bejegyzésedből is, úgyhogy mi lenne ha a szöveget átdobnád nekem mailban egy txt-be rakva, és én kitenném a lapra mit leírást? Ebben a cikkben meg megjelenne egy leírás ami a te megoldásodra mutat, hogy van más megoldása is e problémának.
    Ha így neked megfelelne, akkor küldd el légyszíves a harder kukac tutorial pont hu címre a txt-t azzal a névvel amit szeretnél ha megjelenne a cikkben mint szerző és ha van honlapod, akkor a linkjét is küldheted, kiteszem mint a szerző honlapját.

  5. No, ezzel kapcsolatban kérnék egy kis segítséget. A MySpace-ről nevű oldalról lenne szó. Néhány dolgot már tudtam szépíteni a profilomon, de az explorer és a firefox is széthányja a dobozokat, csak egy kicsit másképp. Mivel nem az én üzemeltetem az oldalt, vannak olyan dolgok amibe nem nyúlhatok bele. Viszont egy-két dolog mindegyik böngészőbe rosszul mutat. A dobozok közül néhány rugalmas, néhány pedig fix. A fix dobozok kinézetén nem tudok változtatni; a tag képet hozzáilleszti a doboz széléhez a kapcsolatfelvételi táblát meg nem illeszti be kódként, csak GIF-ként, úgy viszont a képre írt szövegek kattinthatóak! Erre végső kétségbeesésemben jöttem rá véletlenül…

    Mellesleg azt sem tudom, hogy a meghajtón melyik fájlba lehetne betenni ezeket a margóbeállításokat. DOCTYPE-hoz hasonlót nem találtam. Talán nekem kell létrehozni?…

    Kábé ennyi lenne. Ha látni szeretnétek, akkor a fórumra kiteszek egy pár srcshotot, mindkét böngészőből, ha az segíthetne.

    Még egy apróság. Kellene egy kód, amivel a szöveg színét változtathatom. Gondolom a színt azt hexában kell megadni #dd248a, de a hozzávezető pár karakterre még nem tudtam rájönni.

  6. a myspace dobozainak sajnos nem sok köze van a hagyományos dobozmodelles dobozokhoz. ha jól emlékszek table-ös megoldást is kevernek bele, paff… nem azért mert szükség lenne rá… nem tudom miért, szeretik ha összevissza jelenik meg az oldaluk… amúgy a myspace talán a második legrosszabbul megszerkesztett lap, amit valaha láttam. az első helyen a hotdog.hu szerepel. á, rettenetesen zavaros és hibás mindkettő. (utóbbi, ha nem figyeli az ember, néha képes egy két perc alatt egy gigányi memóriát lefoglalni… mert vagy 15665165 javascript ciklus fut végtelen alkalommal…)

    egyébként a szöveg színe css-ben: p{ color: #c00000; } (vagy pl.: .osztalyneve{ color: #c00000; } )

  7. Köszi a kódot, és a választ! Ez a kód olyan egyszerű, hogy eszembe sem juthatott volna :) A MySpace-be meg majd belenyugszom valahogy. Én megformáltam a saját profilomat, amennyire csak engedte, a továbbiak nem rajtam múlnak tehát. Tehetem is ezt annál inkább, mivel a belső munkafelületem, amit látok, az szép web 2.0, kívülről meg úgysem nekem kell nézegetni azt a ronda profilt. De nem ismerem a mai divatot. Lehet, hogy manapság úgy trendi, ha lemászik a doboz a képernyőről; én még régi iskolában tanultam, olyan könyvekből, amiben margók is voltak a szöveg körül ;)

  8. Köszi a sok hasznos infot! Életmentő volt! Csak így tovább! Nagyon hasznos oldal!

HOZZÁSZÓLOK A CIKKHEZ

Kérjük, írja be véleményét!
írja be ide nevét