CSS float:left center
“Hogyan lehet float:left block HTML elemeket középre igazítani tisztán CSS-ben?” Bár egy szöveges menüt viszonlyag könnyű középre igazítani, előfordulhat, hogy egymás mellé pakolt (float:left) block HTML elemeket kell ugyanígy elrendezni, amelyeknek ráadásul a méretük (szélességük) is dinamikusan változik a bennük található szöveges vagy képes tartalom méretének függvényében. A Weben ezügyben -bár a kérdés gyakran felmerül- csak szedett-vetett megoldásokkal találkoztam, úgyhogy éppen ideje volt, hogy kicsit beleássam magam a témába.
A feladat
A kitűzött cél az volt, hogy pusztán egyetlen style-deklarációval, semmi vagy nagyon minimális hackeléssel, JavaScript és tábázatok használata nélkül középre igazított float:left block elemeket jelenítsek meg egy menüben, ami minden nagyobb böngészőben (IE6, IE7, FireFox 2, Opera 9, Safari) egyformán fog mutatni.
Block elements, float:left CSS property
Miért van szükség block elemekre? Előfordulhat, hogy egy weboldal menüpontjai nem egyforma méretűek és nem pusztán szöveget tartalmaznak, hanem esetleg (különféle) háttérgrafikákat, képeket, és előfordulhat olyan helyzet, hogy egy nem block element (pl. li, span, a) már nem elég a menü megtervezett megjelenítésére. A nem-block elemek egyik -ilyen esetekben hiányzó- tulajdonsága, hogy nem állítható a magasságuk. A padding és margin állítgatás pedig -a különféle böngészőknek köszönhetően- nem mindig a várt eredményt adja. A HTML szerkesztője ennek kiküszöbölésére block elemek használatára kényszerül, amelyek viszont csak a float property left-re állításával “hajlandóak” egymás mellé kerülni. A float:left elemeket viszont a legtöbb böngésző a befoglaló (parent) HTML elemben -függetlenül annak szövegigazításától- bal szélről kezdi megjeleníteni.
1. példa - float:left block elemek
Az imént említett block elemeket balra igazítva az 1. példában vehetitek szemügyre. A menüpontok ez esetben UL és LI elemek (unordered list), amik a parent elem igazításától függetlenül a float propertyk left-re állítása miatt balról kezdődnek. A példához tartozó CSS kódrészlet:
div#menu{ width:800px; height:32px; text-align:center; background:#369; margin:0 auto; line-height:12px; } div#menu ul{ margin:0 auto; list-style:none; padding:0; } div#menu ul li{ display:block; height:32px; float:left; cursor:default; } div#menu ul li a{ display:block; background:#58b; padding:10px; margin:0 10px 0 10px; text-decoration:none; color:#fff; } div#menu ul li a:hover{ background:#7ae; text-decoration:underline; } div#menu ul li a:active{ background:#58b; text-decoration:none; }
2. példa - a parent elem meghatározása
Második példámból kiderül, hogy -az elején említettel ellentétben- mégis csak táblázatokat kell alkalmazni ahhoz, hogy a menüpontok szépen beálljanak középre. Csakhogy nem inline HTML táblákat használok, hanem CSS által definiált table-öket. A CSS kód:
div#menu{ width:800px; height:32px; text-align:center; background:#369; margin:0 auto; line-height:12px; } div#menu del{ text-decoration:none; display:inline-block; text-align:center; height:32px; } div#menu ul{ margin:0 auto; list-style:none; display:table; white-space:nowrap; padding:0; } div#menu ul li{ display:table-cell; height:32px; float:left; cursor:default; } div#menu ul li a{ display:block; background:#58b; padding:10px; margin:0 10px 0 10px; text-decoration:none; color:#fff; } div#menu ul li a:hover{ background:#7ae; text-decoration:underline; } div#menu ul li a:active{ background:#58b; text-decoration:none; }
A Weben böngészve az egyetlen értelmes megoldás CSS-ébe került bele a <del> HTML tag, amit én is átvettem - ebből kiindulva készítettem el a menüm végleges kódját. A kódból látható, hogy a DEL display:inline-block propertyt, az UL display:table és white-space:nowrap propertyket, a LI pedig display:table-cell propertyt kapott - ezek által jelenítik meg a böngészők az adott elemeket táblázatként. Így már működik a középre igazítás, és be is fejezhetném, boldog is lehetnék akár…
3. példa - Opera és IE7 fix
…ha nem indítanám el az Operát és venném észre, hogy a :hover állapotok nem úgy jelennek meg, ahogy én azt szeretném (a többi böngészővel nem volt ilyen gond). Némi kisérletezés után rájöttem, hogy a DEL HTML tag display propertyjének inline-block értékével nem szimpatizált az említett böngésző, ezért ezt block-ra változtattam. Igen ám, de ekkor az IE mindkét verziója megint csak balra kezdte igazítani a menüpontokat. Némi szenvedés után az alábbi kód hozta el a nirvánát:
div#menu del{ text-decoration:none; display:inherit !important; display:inline-block; text-align:center; height:32px; }
Bekerült a display:inherit és az !important. Előbbinek IE-ben hibát kellene generálnia, ugyanis a DEL parent eleme egy DIV, ami pedig alapból display:block, tehát, mivel az inherit “öröklést” jelent, a DEL-nek is block-ként kéne megjelennie (valamint itt sikerrel jártam ez általam eddig sosem alkalmazott run-in értékkel is), utóbbi pedig biztosítja IE7-ben, Firefoxban, Operában és Safariban, hogy a többi definiált display propertyt már ne vegye figyelembe, viszont az IE6 ezt figyelmen kívül hagyja. Ezzel a megoldással (3. példa) már mind az 5 böngészőben korrektül megjelenik a menüm, jöhet a turbózás.
4. példa - Elemcsere, képek
Először is gondolkodóba estem, hogy talán mégsem a DEL a legjobb megoldás (a DEL tag törölt, áthúzott elemet jelent), hiszen lehet hogy a keresőmotorok (crawlerek, spiderek) figyelmen kívül hagyják a weboldal egyik legfontosabb részét, a menüt, ha “törölt” elemeket találnak benne. Lényeges, hogy ez a parent block elem kivételével bármi lehet - én a SPAN javára döntöttem. További kisérletezés képpen megváltoztattam az UL és LI elemeket DIV-re, csak hogy lássam, az elmélet mennyire “sérül” ezáltal. Optikai tuning gyanánt bekerültek a háttérképek a menühöz és a menüpontokhoz, valamint kiegészítő elemek (SPAN) is kerültek a menügombok elé, közé és mögé (4. példa, a végleges menü). És a hozzá tartozó CSS (senkit ne zavarjon meg, de -pusztán merő lustaságból- a DEL-ből .del classt, az UL-ből .ul classt, a LI-ből pedig .li classt csináltam, amit a HTML kódban hozzárendeltem a DIV-ekhez):
div#menu{ width:800px; height:32px; text-align:center; background:url(images/menubg.gif); margin:0 auto; line-height:12px; color:#fff; } div#menu .del{ display:inherit !important; display:inline-block; text-align:center; height:32px; } div#menu .ul{ margin:0 auto; list-style:none; display:table; white-space:nowrap; } div#menu .ul .li{ display:table-cell; height:32px; float:left; cursor:default; } div#menu .ul .li span.left{ display:table-cell; width:16px; height:32px; float:left; cursor:default; background:url(images/button_left.gif); } div#menu .ul .li span.center{ display:table-cell; width:18px; height:32px; float:left; cursor:default; background:url(images/button_center.gif); } div#menu .ul .li span.right{ display:table-cell; width:16px; height:32px; float:left; cursor:default; background:url(images/button_right.gif); } div#menu .ul .li a{ font-size:14px; font-weight:bold; display:block; background:url(images/button_body.gif); padding:10px; margin:0; text-decoration:none; color:#000; } div#menu .ul .li a:hover{ color:#fff; background:url(images/button_body_over.gif); }
Konklúzió
És el is készült a rugalmas, dinamikus méretű, középre igazított menüpontokból felépült float:left block elemekből álló menü a cikk elején felvázolt kritériumoknak megfelelően. A gyakorlatban elég ritkán kell ilyen megoldást alkalmazni, legtöbbször egy középre igazított tartalmú konténerben nem-block elemekkel is elérhető a kívánt eredmény, ám speciális esetekben mégis szükség lehet erre a megoldásra is.

5 komment - "CSS float:left center"
Szép és átfogó leírás!
Eddig ilyet nem csináltam. Olyat szoktam, hogy a div ul li-nek megadom a float: left property-t, és a fix magassághoz hozzárendelek paddingot a megfelelő irányból (vagy egyszerűen text-align: center, ha középre megy a szöveg) és kész. Vagy ez hülyeség?
Nagyon jól kidolgozott leírás! Köszönöm!
suta
arra a megoldásra gondolsz, ami az első pédában szerepel?
jaegen, csak átsiklottam :$
Nagyon hasznos leírás, köszönöm!
Szólj hozzá