CSS triky - jak obtékat i bez "clearování"

9. 7. 2008 19:54 (aktualizováno) Martin Hassman

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 KoutWEBface 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:

Obtekani - vysledka ukazka

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;
}

První řešení – použití after

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.

Druhé řešení – nastavíme obecnou následující značku

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:

  • chcete mít (X)HTML kód co nejjednodušší (nechceme ho mít plný značek jen pro clearování)
  • nemůžeme do stávajícího (X)HTML kódu zasahovat (např. když tvoříme uživatelské styly)

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.

Sdílet