Info Tento blog je v "read-only módu" a nový obsah již nebude přibývat. O vývoji píšu na DevBlog.

Kulaté rohy aneb rounded corners

Update: ASP.NET vývojáři mohou použít komponentu RoundedBox, která vykreslování kulatých rohů zvládá snadno a s velkou elegancí. Viz také Znáte RoundedBox?.

Zaoblené rohy (známé též jako kulaté rohy, oblé rohy nebo anglicky a výstižně rounded corners) jsou jednou z nejčastěji požadovaných CSS technik. Kupodivu je tvorba zaoblených rohů netriviální záležitost, ke které existuje kupa přístupů. Dobrý přehled si člověk může udělat třeba na stránce CSS discuss – Rounded corners.

Obecně lze techniky rozdělit do několika kategorií podle několika možných kriterií:

  • zda se k vykreslení kulatého rohu používá obrázek, nestandardní CSS vlastnost nebo něco úplně jiného (např. JavaScript+CSS)
  • zda jsou obrázky součástí HTML stránky nebo zda jsou definovány externě pomocí CSS
  • zda je v HTML kódu použita tabulka nebo „sémantičtější“ divy
  • jak moc štíhlý je původní HTML kód
  • atd. atd.

Ideálem je HTML kód <div class="rounded">Tohle je obsah</div> ostylovaný třeba pomocí .rounded {border-radius: 10px;} nebo nějak tak. S tím se počítá v CSS3, ale co dnes?

Osobně kladu důraz na co nejjednodušší HTML kód. Nějaké <div class="rounded"><div><div><div>Obsah</div></div></div></div> je přece hrozné! O tabulce ani nemluvě. Proto mě zajímala jen ta řešení, kde šlo napsat <div>Obsah</div>. Nejen že je tento kód dobře čitelný a „semanticky správný“, ale mnohdy je navíc potřeba ostylovat už hotový HTML markup – a provádět v tom případě Find & Replace na každém místě, kde se mají vyskytnout kulaté rohy, by bylo náročné a nesystémové řešení. Požadavek je tedy jasný – maximálně jednoduchý markup.

Principiálním problémem je, že čtyři rohy potřebují čtyři obrázky. (Ano, lze si vystačit se dvěma obrázky pro horní a spodní stranu nebo v extrémním případě i s obrázkem jedním, ale tím se zbytečně zvětšuje datová velikost stránky a ztrácí se tím část flexibility. Předpokládejme tedy potřebu čtyř obrázků.) Pomocí CSS (tak, jak je implementováno v IE) lze však jednomu elementu přiřadit jen jeden obrázek pomocí CSS vlastnosti background. Proto se tak často používá nadbytečný markup. Jsou ale i chytřejší řešení…

Mozilla přímo podporuje nestandardní vlastnosti -moz-border-*, které okamžitě řeší problém a v podstatě představují výše naznačené ideální řešení. Bohužel prohlížeče založené na Gecku používá jen několik málo procent uživatelů internetu. Nezbývá tedy, než se spolehnout na obrázek v pozadí nebo na jinou techniku, o které bude řeč níže. Pojďme tedy dále…

V Gecku a v Opeře funguje řešení, které si se základním a nejjednodušším markupem vystačí. Je prezentováno zde a zakládá se na podpoře pseudoelementů :before a :after. Připomeňme, že potřebujeme uplatnit 4 obrázky, zatím máme ale jen 1 element. Použijeme-li .rounded:before a .rounded:after, máme rázem dva nové elementy. Každému lze nastavit obrázek do pozadí (vlastnost background, resp. background-image) a navíc obsah pomocí vlastnosti content. Tím se nám čistě pomocí CSS podařilo přiřadit jednomu elementu 4 obrázky. Jednoduché a elegantní řešení, bohužel stále nefungující v IE (i když je dobré, že se stránka v IE zobrazí úplně dobře, akorát bez zaoblených rohů).

Arsenál možností CSS je vystřílen a v IE se nám pořád kulaté rohy zobrazit nepodařilo. To je sice smutná zpráva, nicméně za rohem už na svou příležitost čeká natěšený JavaScript.

Moment. JavaScript? Osobně jsem se zarazil, když jsem měl připustit, že se do čistě prezentačních záležitostí bude motat technologie sloužící především k interaktivitě na straně klienta. Chápu, že Centrum.cz mail běží na JavaScriptu, ale používat tuto techniku k prostému vykreslení kulatých rohů? To mě zarazilo. Nicméně zásadním a v podstatě jediným požadavkem na kulaté rohy je jednoduchý markup. Jak bude výsledku dosaženo, jestli pomocí jedné elegantní CSS vlastnosti nebo pomocí desítek řádků JS kódu, je přeci vedlejší a uživatele ani webdesignera to nemusí zajímat. Pojďme se tedy podívat, co JS nabízí.

Hlavní výhodou JavaScriptu a DHTML je v tomto případě skutečnost, že lze jednoduše dynamicky změnit strukturu dokumentu, v našem případě vygenerovat potřebné elementy, které chtě nechtě budeme ke kulatým rohům potřebovat.

Implementaci tohoto přístupu lze najít třeba v SitePoint článku Rounded Corners with CSS and JavaScript. JavaScript jednoduše po načtení dokumentu v prohlížeči dogeneruje příslušné vnořené divy a připravený CSS předpis se postará o dodání obrázků do pozadí. Velmi jednoduché a elegantní řešení. Jaké jsou nevýhody? Prakticky žádné. Ano, při vypnutém JavaScriptu se zobazí pouze normální nezaoblené rohy, ale to je marginální případ, který se dotkne jen malého podílu uživatelů a navíc nepředstavuje žádné dramatické snížení použitelnosti stránky.

Přesto byl vymyšlen ještě jeden přístup, který vůbec nepotřebuje obrázky (!). To má své výhody i nevýhody. Výhodou je, že se neprovádí žádný další požadavek na server a navíc se tím ušetří trocha práce webdesignerům. Nevýhodou naopak je menší flexibilita orámování (obrázek dává prakticky neomezené grafické možnosti) a mně osobně ještě vadí jedna věc, kterou je jakási kostrbatost generovaných rohů. Bohužel zde nejde využít antialiasingu. Každá mince má prostě svůj rub i líc.

Principem tohoto zatím tajemného přístupu je individuální přístup k jednotlivým řádkům pixelů u div-elementu. Když první řádek pixelů vlevo i vpravo zkrátím řekněme o 5 px (třeba nastavením marginu), druhý a třetí řádek o 3 px, čtvrtý řádek o 2 px, pátý o 1 px a analogicky upravím i spodek, dostanu zaoblené rohy. Fikané…

Implementace zmiňovaného přístupu se jmenuje Nifty Corners (původní verze, vylepšená verze). Jedná se o stylový předpis spolu s JS knihovnou.

Zajímavé je, že v českých luzích a hájích se našel člověk, který ideu tohoto přístupu dovedl ještě dál. V článku Kulaté rohy bez obrázků aneb Nifty corners reloaded zveřejňuje Pachollini zajímavou úpravu knihovny, která umožňuje nastavovat určité vlastnosti oblých rohů (jako třeba poloměr), umí kulaté rohy aplikovat na všechny elementy s určitou CSS třídou apod. Nifty Corners se tak stávají snadněji použitelnými a lépe konfigurovatelnými. Dobrá práce.

Zde přehled možných přístupů, na které jsem během krátkého průzkumu narazil, končí. Na závěr však ještě nemůžu nezmínit jednu zajímavost, která s tématem souvisí.

Byl jsem si skoro jistý, že někdo napsal nějaký ASP.NET serverový ovládací prvek, který kulaté rohy zvládá. Nemýlil jsem se a dokonce se jedná o implementaci poměrně zajímavou. Scott Mitchell v článku Introducing the RoundedCorner Web Control ukazuje zajímavou techniku, kterak se ASP.NET vývojář může s kulatými rohy vyrovnat čistě pomocí nastavení určitých vlastností serverovému controlu. Tyto vlastnosti jsou při renderování stránky automaticky převedeny na odpovídající markup spolu s CSS. Nejzajímavější ale je, že veškeré obrázky se generují dynamicky na serveru pomocí GDI+. To je skutečně unikátní přístup.

Jak vidno, „taková blbost a co to muselo dát práce“. Už aby tu bylo CSS3…

Zařazeno do kategorií |
Pachollini (Čt, 2006-03-16 06:12):

Anti-aliasing jde taky, byť je to trošku šílené: http://www.ac­ko.net/…ifty-corners

vývoj (St, 2008-04-09 10:46):

ja si myslim, ze velmi pekny je http://tools.si­tepoint.com/…ky­/index.php

nepouziva JS a temer vyhovuje <div class=„rounded“> obsah</div

jen s omezenim, ze musim obsahovat 2 vnorene elementy (koneckoncu rozumne)

J.N.

Komentáře jsou uzavřeny (blog je v read-only módu). Pokud mě chcete kontaktovat, můžete mailem.