Kulaté rohy bez obrázků aneb Nifty corners reloaded

Pachollini, 3. dubna 2005, 17:07

English version: Rounded corners without images: A Nifty Corners Inspiration

Když jsem na Filově blogu Jana Řezáče poprvé narazil na zmínku o technice Nifty corners, zběžně jsem kouknul na originální popis Nifty corners od Alessandra Fulcinitiho, ale přišlo mi to nějak moc složité, takže jsem zase odešel. Škoda, ale naštěstí mě zachránila Krutá realita, která Nifty corners zmiňuje o něco později. Podíval jsem se tedy pořádně, o co jde, a zjistil jsem, že Nifty corners jsou ve skutečnosti geniální nápad.

O co tedy jde? O techniku, která umožňuje zakulatit rohy bez použití obrázků, jen s pomocí JavaScriptu a trošky CSS. Oblé rohy mám rád, ale nutnost tvořit (a stahovat) pro každé dvě kombinace barev popředí a pozadí a každý rozměr rohů čtyři obrázky mne spolu s potřebou vkládat do kódu další prvky většinou odradí. Nifty corners to řeší jinak: místo obrázků kulatých rohů vloží do zaoblovaného prvku několik pixelů vysoký blok (kontejner), který má stejnou barvu pozadí, jako vnější (nadřazený) prvek. Do něj pak vloží několik 1–2 pixely vysokých prvků (proužků) s barvou pozadí „zaoblovaného“ prvku, kterým se postupně mění velikost okraje (margin), takže vytvoří efekt zakulaceného rohu. Celé to vypadá asi takhle:

schéma uspořádnání prvků

Pointa spočívá v tom, že se prvky, které způsobují optické zaoblení, do stránky přidají pomocí JavaScriptu. Řešení Allesandra Fulcinitiho zavolá pro každý prvek, kterému se mají zakulatit rohy, JavaScriptovou funkci, jíž jako parametry předává barvu pozadí a popředí a identifikátor prvku.

Což je také (alespoň pro mne) největší nevýhoda této metody: jsem člověk velmi líný a nutnost volat tuto funkci pro každý prvek by mne v praxi asi od užívání zaoblených rohů odradila. Ideální by bylo, nastavit prvku, který se má zakulatit nějakou třídu a zbytek přenechat JavaScriptu. Kromě toho by se hodilo mít možnost jednoduše nastavit poloměr zaoblení. Také by bylo pěkné, kdyby nebylo třeba u každého prvku nastavovat barvu popředí a pozadí.

Pustil jsem se tedy do práce a po pár hodinách boje (při němž kupodivu nebyl nejtěžším soupeřem JESPRP, ale goniometrické funkce) vytvořil skriptík, který všechny tyhle požadavky splňuje.

Návod k použití

  1. Ke stránce připojíme soubor s JavaScripty rounded-corners.js.
  2. Všem prvkům, které mají mít zaoblené rohy přiřadíme třídu rounded, případně další třídy, jimiž se nastavují parametry zaoblení.
  3. Na konci stránky zavoláme JavaScriptovou funkci make_corners().

Viz jednoduchá ukázka použití zaoblených rohů.

Nastavení parametrů zaoblení

U každého prvku, který má přiřazenu třídu rounded lze pomocí dalších tříd nastavit parametry zaoblení. Vzhled lze rovněž určit pomocí CSS přes třídy rounded (prvek, kterému zaoblujeme rohy), rc-container-top a rc-container-bottom (kontejnery pro zakulacovací proužky), rc-inner a rc-level-NN (zakulacovací proužky, NN je číslo v rozsahu 0 až poloměr rohu).

Třídy, které se používají k nastavení vlastností prvku mají tvar rc-[název_vlastnosti]-[hodnota_vlastnosti]. Pokud je hodnota typu boolean (tedy ano / ne), používá se 1 / 0, přičemž hodnota 1 se může vynechat ;-). Všem parametrům odpovídá JavaScriptová proměnná $rc_[název_vlastnosti], která se používá ve funkci rounded_corners(). Přehled všech parametrů je uveden v následující tabulce.

CSS třída JS proměnná popis
rc-radius-[integer] $rc_radius Nastaví poloměr zaoblení rohů v pixelech.
rc-top-[0|1] $rc_top Zapíná zakulacování horních rohů.
rc-bottom-[0|1] $rc_bottom Zapíná zakulacování spodních rohů.
rc-right-[0|1] $rc_right Zapíná zakulacování pravých rohů.
rc-left-[0|1] $rc_left Zapíná zakulacování levých rohů.
rc-selfcolor-[RRGGBB] $rc_self_color Nastaví barvu zakulacovaného prvku.
rc-parentcolor-[RRGGBB] $rc_parent_color Nastaví barvu pozadí (rodičovského prvku).
rc-inheritstylecolors-[0|1] Při zapnutí nenastavuje skript žádné barvy, použije se tedy CSS definice.
rc-antialiased-[0|1] $rc_antialiased Proužkům se přidá ještě border, což trošičku vyhladí rohy, ale žádný opravdový antialiasing to není.
Funguje jen s rc-method-margin.
Pozor: nefunguje v MSIE pokud je barva ve stylopisu nastavena jako white nebo #FFF a ne #FFFFFF nebo rgb(255,255,255).
rc-antialiasedcf-[0-1] $rc_antialiased_cf Koeficient přechodu v intervalu 0–1; při vyšších hodnotách se barva přechodu blíží barvě pozadí rodičovského prvku.
rc-compact-[0|1] $rc_compact Nastaví kontejnerům záporné horní či dolní okraje, takže se zakulacovaný prvek nezvětší.
Někdy zlobí v MSIE.
rc-automargin-[0|1] $rc_auto_margin Pokud má zakulacovaný prvek nějaký padding, nastaví kontejneru negativní margin, který jej kompenzuje.
Nefunguje v MSIE.
rc-method-[margin|border] $rc_method Nastaví metodu vykreslování kulatých rohů.
rc-border $rc_border Prvek se vykreslí se zakulaceným borderem. Viz ukázka.

Důležitá je vlastnost rc-method, která nastavuje metodu vykreslování kulatých rohů:

margin
Vykreslí kontejner s barvou pozadí shodnou s barvou pozadí rodičovského prvku a proužky s barvou pozadí zakulacovaného prvku a různě velkým margin, v tomto případě lze border použít pro „antialiasing“.
border
Pozadí kontejneru i proužků zůstane průhledné, proužky dostanou místo marginu border příslušné šířky v barvě pozadí rodičovského prvku. Tento postup je vhodný pokud má zakulacovaný prvek na pozadí obrázek.

Viz ukázka použití zaoblených rohů s nastavením parametrů.

Jak to funguje

Nejprve se pomocí funkce find_class(), kterou jsem si napsal při svém šíleném JavaScriptovém experimentu najdou všechny prvky v dokumentu, které mají přiřazenou třídu rounded. U nich se zjistí, zda mají pomocí tříd nastaveny nějaké další parametry zaoblení. Pokud ne, použijí se výchozí. Poté se do nich vloží zaoblovací prvky, jejichž barvy se ve výchozím nastavení určí z barvy pozadí zaoblovaného a rodičovského prvku pomocí funkce get_current_style(). Nevýhodou je, že určení nefunguje v Safari, Konqueroru a starších verzích Opery (v 7.5 nicméně funguje), nicméně pro ten případ se dá použít manuální nastavení. Detailnější vysvětlení je v této chvíli nad mé síly, masochistické zájemce mahu jedině odkázat na (nekomentovaný) zdrojový kód skriptu, eventuálně na mail. Případné připomínky jsou velmi vítány.

Skript jsem testoval v Geckových prohlížečích (K-Meleon, Mozilla Firefox), Opeře 7.5 a MSIE 5.01 a 6.0 pod Windows, v nichž s uvedenými výhradami fungoval. V MSIE 5.5 nefunguje.

Co vy na to?

[1]

Filosof, 3. dubna 2005, 18:46 http://blog.filosof.biz/

Tož to je drsný upgrade :-) Asi to vyzkouším i někde použít.. :-)

[2] dobre

MARINAKX, 3. dubna 2005, 19:10 http://marinakx.wz.cz/poznamky/

Dobre! i kdyz to neni porad "-moz-border-radius: 10px;" uz se to k tomu blizi vice nez nifty, to jsem zavrh jeste pred otestovanim

PS v opere 8 taky funguje to demo

[3] Luxus

Fred, 18. dubna 2005, 14:21

Nějak jsem tu chvíli nebyl kvůli nepravidelné aktualizaci a málem mi to uniklo. Je tady už docela dost věcí,které si v soukromém žbříčku řadím mezi nejhodnotnější na českém písečku. Takže díky za tuhle pěknou sbírku

1/Ideální šířka stránky

2/Otevírat odkazy v novém okně

3/Skrývání komentářů

4/RSS čtečka

5/Hover efekt tr

6/Kulaté rohy

[4] což takhle nastavená výška

Štěpán Svoboda, 19. dubna 2005, 11:13

Pokud nastavím výšku na nějakou hodnotu rohy se vykreslují tam kde končí obsah prvku. Jinak ovšem geniálně jednoduché na použití. Kdyby ste byl tak hodný a poradil co s tou výškou.

S pozdravem Štěpán Svoboda

[5] Proble s vyskou rodicovskeho prvku

Fedor Tirsel, 19. dubna 2005, 16:43 www.fi0dor.info

Taktiez som dnes narazil na problem s vyskou, co tu spominal Stepan. Snazil som sa to nejak vykumat v zdrojaku, ale ako pises... je to len pre masochistov, dost porno ;). Ak by si si nasiel cas ,tak to skus pozriet, nebude to velka uprava. Moj konkretny pripad je nasledovny:

mam rodicovsky div, ktoremu som nastavil minimalnu vysku (min-height: 450px; height: auto; _height: 450px;). Ak ma obsah tohoto divu mensiu vysku ako zmienenych 450px, tak sa rohy vykreslia hned za obsahom (vacsinou niekde v polovicke divu).

[6] Problémy s výškou

Pachollini, 20. dubna 2005, 15:50

Pokud tomu rozumím dobře, mohlo by pomoci strčit to ještě do jednoho DIVu a zakulatit až ten, ale ztělesněná elegance to není ;-)

Tedy:

<div class="rounded">

<div>(původní div s nastavenou výškou)</div>

</div>

Pokud tomu rozumím špatně, pošlete prosím odkaz na stránku, kde to nefunguje.

[7] Díky

Pachollini, 20. dubna 2005, 15:53

[ 3 ] Děkuji pěkně, z takové chvály budu mít hlavu v oblacích až do večera ;-)

[8] Chyba Paddingu

Olda, 4. srpna 2005, 22:39

Skutečně se rohy vážou na obsah a ne na fyz.výšku. Pokud je padding=0 tak funkce přidá mezeru hrana-text nahoře i dole jakoby byli paddingTop/Bottom=10px, ale né už na boky tj jakoby PaddingLeft/Right=0. Pokud to chci řešit a nastavim padding=1ex, tak rohy zustanou na rozich obsahu. Ta Matrjoška(balení do vnějšího DIVu)nějak nefunguje.

Jinak děkuju, moc mě to potěšilo, udělal jsem první stránku "jako" s "kulatýma" :-), ale zůstanu raději u rohů pro FF a ostatní uživatelé ať počkaj až jim to půjde taky :-).

Přeju zdar.

[9] kulaté rohy s css?

OZZY, 11. ledna 2008, 12:26

Chtěl bych poprosit, jestli by někdo měl nějaký snadný návod na toužebné kulaté rohy.

OZZYk

Aktuální Seky

.