Dostal se ke mně zajímavý webdesignérský trik, o který se musím podělit. Jak se zachází s plovoucími („floatovanými“) prvky pomocí kaskádových stylů jistě víte. Ovšem víte i jak nejlépe jejich obtékání ukončit?
Pokud ihned vyhrknete, že přidáte značku s clear:left; clear:right nebo clear:both, tak sice máte pravdu, ale já se ptal jak nejlépe plovoucí sekci ukončit.
Pavel Kout z WEBface mi totiž zaslal řešení, jak obtékání ukončit i bez přidané značky navíc. Já o něčem takovém slyšel poprvé. Nevěřil jsem. Zkoumal. Testoval. A nakonec pochopil. Skutečně, Pavlova řešení (ano, hned dvě různá řešení) tento malý zázrak umožní a fungují ve všech běžných prohlížečích.
Výsledek naší ukázky bude vypadat takto:
Nadpisy panelů na obrázku jsou ve skutečnosti neuspořádaný seznam, který je tvořen plovoucími položkami. Vlastní obsah panelů je ale nesmí obtékat, nýbrž má být umístěn až pod nadpisy (na obrázku vlastně žádný obsah nemáme, jen bílý prázdný obdélník).
Napřed si připravme základní kód společný pro obě řešení.
XHTML:
<ul> <li><a href="#">first</a></li> <li class="selected"><a href="#">second</a></li> <li><a href="#">third</a></li> </ul>
CSS:
ul { list-style: none; margin: .8em 0 0 0; padding: 0; border-bottom: 1px solid #DDDDDD; } ul li { position: relative; /* IE6 only */ float: left; background-color: #EEEEEE; border: 1px solid #DDDDDD; padding: 5px 15px; margin: 0 5px -1px 0; list-style: none; display: block; } html>body ul li { position: static; } ul li:hover { background-color: white; } ul li.selected { background-color: white; border-bottom-color: white; }
V prvním řešení k ukončení obtékání použijeme pseudoelement :after, kterému nastavíme clear:both. Obejdeme tím nutnost přidávat další značku – jednoduše využijeme pseudoelement (pseudoznačku). Jednoduché a elegantní.
ul { height: 1%; /* IE workaround */ overflow: visible; /* IE workaround */ }
ul:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
Důležitá jsou pravidla pro ul:after, první pravidla pro ul jsou pomůckou jen pro IE.
Omezení: pseudoelement :after může být u každé značky jen jeden. Proto pokud byste :after již využívali pro svojí potřebu, zmíněné řešení nemůžete použít.
V druhém řešení použijeme selektor pro následujícího sourozence a ať jím je kterýkoliv prvek, nastavíme mu clear:both. Když o té myšlence přemýšlím, připadá mi strašně triviální, nicméně samotného mě nikdy nenapadla.
ul { height: 1%; /* IE6 only */ margin-bottom: -4px; /* IE6 only */ overflow: visible; float: left; width: 100%; }
html>body ul { height: auto; margin-bottom: 0; }
*+html>body ul { margin-bottom: -4px; /* IE7 only */ }
ul + * { clear: both; }
Nejdůležitější je označené univerzální pravidlo se selektorem ul + *, kterým opět obejdeme nutnost přidávat další značku pro ukončení obtékání. My totiž využijeme první značku za naším seznamem, ať je to jakákoliv značka (pokud by žádná následující sourozenecká značka neexistovala, museli bychom selektor upravit).
Obě řešení spolu s dalšími pokusy najdete na adrese http://client.webface.cz/temp/clear-float-tabs.html
Zmíněná řešení jsou k nezaplacení zejména pokud:
Věřím, že předvedená řešení řada z vás někdy využije. Já za ně Pavlu Koutovi děkuji. Pavel potvrzuje, že stále patří mezi přední osoby českého webdesignu.
A co obyčejné overflow nadřazenému prvku (zde ul)?
Pozor na hasLayout u IE6 (width:100% nebo zoom:1)
Viz http://www.quirksmode.org/css/clearing.html
Takové vychytávky bych také rád uvedl na WebExpo.
Načo riešiť veci jednoducho keď to ide zložito :)
Moje riešenie bez floatovania
ul li {
/* mozilla haven't inline-block */
display: -moz-inline-block;
display: -moz-inline-box;
display: inline-block;
a inline-block podporuju všetky prehliadače len mozilla nie, no na to tam je specialny atribut ;)
Tak som hladal, ja som podobne riesenie vyuzil pri odkaze v riadku, aby som mal z neho blok.
Na blogu quirksmode je napisane:
"IE 6/7 accepts the value only on elements with a natural display: inline."
Takze jedine oddelenym CSS alebo pomocou javascriptu IE7/8. Kazdopadne je to podla mojeho nazoru cistejsie riesenie ako tu spominane. Podobne riesenia na "dve strany" pre obycajnu prkotinu mi obcas vedia len privodit nazor, ze musi to ist aj lepsie :)
[2] Ano, Martine. Ono tohle je tohle vyčištění vlastně známé už déle (z pravěku, kdy jsme si říkávali "tohle bych chtěl jednou používat"), ale problém je IE. Tak mě napadlo zkombinovat to s validními filtry pro IE, které znám, aby to bylo skutečně použitelné už aspoň dnes.
Teď mě zrovna čeká kódování layoutu s hromadou záložek (cestovka) a potřeboval jsem najít elegantnější řešení než klasika: zapouzdřující blok, a v něm seznam (nejlépe obtékaný kvůli pozadí) a ještě "čistič" navíc. Pokud se navíc podíváš pozorněji, všimneš si ještě další odlišnosti oproti stávajícím řešením: není tam použit *žádný* obrázek (obvykle jako background-image toho nečíslovaného seznamu) — to je další goal.
A ještě pro zajímavost: testoval jsem to i v v betě IE8 a tady je screenshot chybného zobrazení řešení 1 a 2 — http://client.webface.cz/temp/clear-float-tabs-ie8b1.png — z čehož vyplývá, že výhledově nejsou použitelná.
Jejda, dúfam, že tento komentár už nebude braný ako spam, no urobím zhrnutie a vysvetlenie a deklarujem si autorske pravo na napad :-D (ironia)
Takže zmena oproti stávajúcemu riešeniu a iným dostupných na weboch je rozdielna v tom, že nepoužíva žiadne všeobecné a krkolomné hacky, ale len jemne upravuje nekompatibilitu CSS v IE6/7 a prehliadačoch na jadre Gecko 1.8 (Firefox 2)
ul
{
list-style: none;
border-bottom: 1px solid #DDDDDD;
}
ul li
{
display: inline;
}
ul li a
{
/* mozilla haven't inline-block */
display: -moz-inline-block;
display: -moz-inline-box;
display: inline-block;
background-color: #EEEEEE;
border: 1px solid #DDDDDD;
padding: 5px 15px;
margin: 0 5px -1px 0;
list-style: none;
}
ul li a:hover
{
background-color: white;
}
ul li.selected a
{
background-color: white;
border-bottom-color: white;
}
Princíp je v tom, že využijeme atribút z CSS 2.1 "display: inline-block" kedy objekt sa sprava ako blok, ale je zarovnaný ako riadkový element. Jediný použitie "hacku" je to, že prinútime Firefox nižši ako verzia 3 využit svoje riešenie tohoto atribútu, pre ostatné prehliadače (tým aj nový Firefox 3) sa využije štadardný zápis.
Malá zmena sa týkala aj IE6/7, kedy "inline-block" je možné použiť len pre značky s prirodzeným atribútom display: inline, čo práve LI nebolo. Tým teda stačí definovať odkaz ako "inline-block" a položku zoznamu zmenit na "inline"
[9] Když já se zoufale bráním používat proprietární elementy, atributy, vlastnosti a hodnoty. Používám pouze obecně platné a podporované (z důvodu dopředné kompatibility) a jsem ochoten pouze ošetřit staré "shity" (aktuálně IE6/7) za podmínky, že to nebude dělat paseku v budoucnosti (= budou ignorovány). Já vím, že jsem příliš konzervativní, ale tento přístup se mi za ta léta vyplatil.
[9][10] - mno, ona je otázka, co je dopředně kompatibilnější - inline-block nebo :after? Podle mě to vyjde nastejno. Jinak tyhle metody jsou známy už delší dobu, ale každá má své "ale". Já se po různých experimentech vrátil k normálnímu clearovacímu elementu, zas tolik mi tam nevadí. Mimochodem mě ale celkem zarazilo používání old-school hacků typu html>body ul. Ale proti gustu...
[10] Pavel:
Ja to chápem, ale príde mi (osobne) veľmi zvláštne používať "škaredé" techniky na úkor použiteľnosti, prehlľadnosti a hlavne pokrokovosti. Ja som taký liberálnejši typ a mám rad pokrok.
A tieto rozšírenia sú plne s definíciou CSS, ktorá práve na to odkazuje
[11] Karf, no ono to je dost na uvážnie, ale keď si zoberieš, že CSS 2.1 tu je dosť dlho na to, aby väčšina vecí bola implementovaná (a ked nie je tak aspoň niečo), tak ju treba využiť.
http://www.quirksmode.org/css/display.html
Jediné problémy boli s týmito dvoma "hekmi". No že nie sú validné (iba v prípade Firefoxu 2 a nižšie) ? To mi nijako nevadí keď priamo norma o týchto vychytávkach spomína.
[14] Rixio, nič proti gustu, ale aspoň u mňa skončila éra hnusných hackov, ak niečo nejde už nijak jednoducho, tak použijem Dean Edvardsov javascript IE7/8.
Získam:
- pokojnejší spánok
- viac voľného času
- zdokonalím sa v novších technikách
- posuniem web trochu dopredu
Ja som osoba "lenivá" a po relatívne dlhom čase v oblasti web developerstva osoba pokroková.
Vždy si treba zvážiť pre koho to robím a čo použijem. Je mi jasné, že keď budem používať hojne jQuery a Ajax prkotinky, tak vyladovať niečo pre staršie prehliadače je:
1. strata času
2. javascript musí byť povolený.
No po tom druhom bode ma dúfam nebudete haniť, ale 98% ľudí ho má zapnutý a zbytok sú vačšinou ludia, čo sa boja nebezpečenstva čo nie je a milovníci príkazovej riadky
[11] "zarazilo používání old-school hacků typu html>body ul" — tady bych si dovolil upozornit, že se nejedná o hack (tj. potenciální pandořinu skříňku), nýbrž o workaround pro elegantní odliftrování té nejhloupější současné potvory (IE6) a relativně normálního zbytku (relativně kvůli IE7, což je jen o něco lepší IE6; v praxi je ovšem důsledek kolikrát spíš horší).
[14] Ano, to je ono profláknuté řešení, které bylo zdokumentováno ještě přes původním release toho příspěvku na PositionEverything. Zaklínadlo však opět zní "IE".
Ale dovolím si ještě jednou zopakovat to, o co mi primárně šlo — abych mohl vytvořit záložky ze kteréhokoliv nečíslovaného seznamu bez toho, abych ho uzavíral do zapouzdřujícího prvku, ošetřoval obtékání mimo tento seznam (když kód implementuje někdo další, může na to zapomenout) a abych se vyhnul použití obrázku. To samé platí třeba i pro fotogalerie (resp. thumbnaily) — opět jen UL/LIs. Proto jsem si říkal, že by to mohlo pár lidem pomoci a ukázal jsem to Martinovi.
Nezapomeňte prosím, že si povídáme o stylování v době, kdy stále cca třetina používá IE6, který nezvládne ani např. H1 + P ( margin-top: 0; }. Lze vymyslet soustu parádních formátování, ovšem IE6 záhy obvykle srazí vaši radost z nich do záporných hodnot (ani IE7 na tom není zase o tolik lépe).
[19] :-D :-D
Ja nehovorím o vtieravom javascripte, ale o tom čo uľahčuje veci. Len neviem či máš predstavu o tvorbe portálov, nie len obyčajných web stránok. Ak máš, tak sám vieš, ze bez pokročilejších techník sa nezaobídeš, pokiaľ nechceš tvoriť web ala 90te roky.
Pokročilejšie vyhľadávanie (bez nutnosti reloadovat stránku), komplexnejšie formuláre (neviem si predstaviť 5 select boxov a pri každej zmene znova robiť reload). Bez niečoho podobného sa nezaobídeš, a keď už je javascript nuntosť, tak prečo si robiť nervy s problémami prehliadačov a riešiť veci komplikovano keď máme dostupné riešenia ?
Dokonca v Youtube si bez javascriptiu môzeš akurát tak čítať texty, aj to len na prvej stránke, lebo ďalej neprekliknes :-D
Javascript nie je hrozba. A preto sa k nej aj tak chovám.
BTW: ešte teraz sa smejem :-D
Jezz: A tak je to také řečeno ve specifikaci http://www.w3.org/TR/CSS2/visuren.html#floats Ono u plovoucích prvků používaných pro ten účel, pro který byl float skutečně vytvořen, to platilo (např. když někdo nechal plovat obrázek / tabulku s popiskem, bylo nutné explicitně říct, jak se má ten popisek zalomit).
Ale dnes, když je float používán (chtěl bych říct i zneužíván, ovšem to už lze těžko říct, když ho tak používáme de facto každý) k tvorbě vlastního designu, to není tak jednoduché a pro řešení zmiňované v článku nepraktické až nepoužitelné - s každou změnou obsahu (popisky) by bylo nutné nastavoval i šířky a měnit design (to je ve sporu i s oddělením vzhledu a obsahu).
Dalo by se říct, že CSS2 specifikace je nekompatibilní z praktickým používáním floatu. A do příchodu CSS3, který přinese nové designovací možnosti, se to nezmění.
Martin Hassman ex-biochemik, umělecký programátor a publicista. Spoluzakladatel CZilly, zakladatel Zdrojáku, správce HTML5.cz, organizátor hackathonů, čekovacích muzejních nocí aj. akcí.
Přečteno 24 507×
Přečteno 24 033×
Přečteno 20 755×
Přečteno 19 839×
Přečteno 19 810×