english * engels

Flexibele ronde hoeken

Liquid round corners

een veelzijdig dynamisch css-model met transparantie
voor het maken van zich aanpassende 'vloeibare' afgeronde randen

EERST EEN PAAR TOEPASSINGEN BEKIJKEN?

Er is een Flexibele Hoeken Speeltuin met voorbeelden. Tot straks!

Inleiding

Stap voor stap

  1. linksboven
  2. rechtsboven
  3. midden boven
  4. zijkanten links en rechts
  5. onderkant
  6. vereenvoudiging

De complete css

Haast? (download home kit)

Evaluatie

Variaties

Speeltuin

Inleiding

Er zijn verschillende wensen mogelijk voor een vakje met ronde (of andere niet rechthoekige) hoeken aan de rand. Mijn wensen zijn:

Een blik op internet leerde dat er tal van oplossingen de wereld rondgaan. Wat ik o.a. tegenkwam: veel tabelconstructies, css maar niet geschikt voor transparantie, wel doorzichtig maar niet flexibel, wel flexibel maar javascript, flexibel èn transparant maar met beeldscherm vullende images, css èn flexibel èn transparant maar met buitengewoon complexe <div>-nesten, enz. enz.
Alle denkbare varianten, maar geen eenvoudige universele oplossing waar je alle kanten mee op kunt.
Niet in de stemming om verder te gaan Google'en en bij een heel groot aantal webpagina's met "maak zelf ronde hoeken voor je site", "nifty corners" of "smooth curved edges" te gaan kijken of die dan wel aan mijn wensen voldeden, maakte ik het model dat je hierboven en hieronder ziet. De randen en hoeken van deze etiketvakjes worden automatisch en vloeiend aangepast als je de resolutie of de vensterbreedte verandert.
 

Voorbeeld: probeer dit door een zijbalk (bv. de geschiedenis-zijkant) van je browser aan te zetten, en dan daarvan de breedte te variëren.
Of door het venster te "ont-maximaliseren", en dan eveneens de breedte te variëren: dit etiket blijkt uiterst flexibel!


Alles vloeibaar!
Hoewel de titel van deze pagina lijkt te zeggen dat er alleen aanpasbare ronde hoeken gemaakt kunnen worden, is de gevonden methode ook geschikt voor andere toepassingen. In feite:

Er zitten een paar voorbeelden daarvan in de speeltuin. Ik hoop dat dit de creativiteit stimuleert, want ik denk dat er veel meer mogelijk is!

Stap voor stap

Stap 1: linksboven

Eerst de linker bovenhoek. Dit kan een gif-plaatje zijn dat aan de buitenkant doorzichtig is gemaakt (voor wanneer je de pagina met het vakje over een vaste achtergrond scrollt). Ik gebruikte dit image van 9x9px:

show topleft corner

Nu het bekende css-voordeel: één keer de eigenschappen omschrijven, en toepassen zo vaak als je wilt. - Dus met een css-class roepen we dit plaatje aan als achtergrondfiguur in een <div>, zodat we niet voor elk vak dezelfde html met <img src="..." ...> hoeven te herhalen:

stylesheet

.top-left {

background-image: url('images/corner-topleft9x9.gif');
height: 9px;
width: 9px;
}

html

<div class="top-left"></div>


Dit geeft:

FF-result

Maar ... Internet Explorer is (weer eens) ongehoorzaam en denkt dat het een normale regel is met normale eigenschappen qua regelhoogte. Resultaat in IE is de vertoning van 2 hoekjes bovenop elkaar:

IE-result

Om hier van af te komen, voegen we een letterformaat toe dat kleiner is dan de hoogte van ons plaatje: om voor IE een kleinere regelhoogte te forceren. We nemen: 

stylesheet

.top-left {

...
font-size: 2px;
}


Op deze manier doet IE wat hij hoorde te doen, en zo is de eerste stap klaar.

Zie stap 1 in werking

Stap 2: rechtsboven

De rechter bovenhoek is natuurlijk het gespiegelde linker hoekje: topright-corner. We kunnen nu niet dit plaatje in dezelfde <div> zetten als de linkerkant: er past maar 1 background-image tegelijk in! Dus maken we nog een <div>, en deze keer plaatsen we het image aan de rechterkant, met "float: right;". 
Het resultaat is (met toevoeging van een beetje achtergrondkleur om de positie beter te zien):

not in line

Dat is niet goed: we moeten iets regelen! De reden is dat de twee <div>'s elementen op "block"-niveau zijn, en die kunnen niet zonder meer in één stoel zitten. Maar door een negatieve "margin-top" in te voeren kunnen we de rechterhoek omhoog tillen met de 9px hoogte van de linkerhoek:

stylesheet

.top-right {

float: right;
margin-top: -9px;
background-image: url('images/corner-topright9x9.gif');
height: 9px;
width: 9px;
font-size: 2px;
}

html

<div class="top-left"></div>
<div class="top-right"></div>


Nu staat ook de rechterbovenhoek op de goede plaats, en zal deze links-rechts meebewegen als de breedte van het venster toeneemt of vermindert. Zonder tabel: met losse handen!

Zie stap 2 in werking

Stap 3: Midden boven

Als we alléén hoekmarkeringen rond een tekstblok willen, is er helemaal geen bovenrand en linker- en rechterrand nodig. Rechtstreeks door naar Stap 5!

Als we wel van lijntjes houden, kunnen we nog een <div> toevoegen met een border bovenaan en de backgroundkleur van het blok voor de rest (of met een zich herhalend background-image van de bovenlijn tussen de twee bovenhoekjes, zoals: topline).

Maar om een extra <div> uit te sparen, kunnen we makkelijk de linkerhoek uitbreiden. Het trucje is, dat de linkerhoek een background-image is: en die kan niet groter zijn dan het doorkijkje van de <div>-box waarin het plaatje de achtergrond vormt.

Dus tekenen we een lekker lange lijn aan de rechterkant van ons css-background-image van de linkerhoek:

left corner with topline

Om onze ronde hoeken resolutie-bestendig te laten werken voor een scherm tot 1280x1024px, maken we dit plaatje 1280x9px. In geval van nood kan dan het ronde hoeken-vak de breedte van het hele scherm opvullen, terwijl het ook voor elke lagere resolutie bruikbaar is.
Nu moeten we het stylesheet voor dit plaatje aanpassen: geen vaste breedte van 9px meer, maar de breedte van de box waarin het ronde hoekenvak is opgenomen (dwz. de box waarin ook de normale alinea's staan, vaak de content-box).
Dat kunnen we bereiken door het nieuwe background-image voor te schrijven zijn hele <div> op te vullen: door gewoon de breedte weg te laten (de "no-repeat" eigenschap hebben we niet nodig: hij is lang genoeg gemaakt om niet opnieuw met het linkerhoekje te beginnen!).

stylesheet

.top-left {

background-image: url('images/corner-topleft1280x9.gif');
height: 9px;
font-size: 2px;
}


Resultaat:

overlapping < detail overlapping

We zien nu een overlapping aan de rechterkant (wegens de transparantie van de rechterhoek), die we weg moeten zien te vogelen. Daartoe korten we het (denkbeeldige) rechter uiteinde van het "linkerhoek plus bovenrandje" image in, door een vrij te houden margin-right op te geven die net zo breed is als de breedte van het rechter hoekje.

stylesheet

.top-left {

...
margin-right: 9px;

}


Hiermee is de bovenkant kompleet.

Zie stap 3 in werking

Stap 4: Zijkanten links en rechts

Dit is een makkelijke: we hoeven alleen maar een class met zijlijnen (borders) te maken voor de paragrafen en andere inhoud van ons etiket, met in de html een <div> die dit alles insluit.
De border-color is de randkleur van onze hoekjes, de background-color is de kleur binnen de hoekjes.

We geven nog een padding van 10px voor wat afstand tussen de zijlijnen en de tekstregels van de inhoud:

stylesheet

.inside {

border-left: 1px solid #C00000;
border-right: 1px solid #C00000;
background: #EFEFEF;
padding-left: 10px;
padding-right: 10px;
}

html

<div class="inside">

<!-- wat je in het etiketvak wilt hebben -->

<p>Paragraph: lorem ipsum: consectetuer!</p>

<!-- enz. -->

</div>


Het enige is: we hebben nu een gat gekregen tussen de strook met de bovenkant en de box met de inhoud.

gap

Het eerste element van de inhoud moet een margin-top van 0px krijgen om dit te vermijden (en parallel hieraan: hetzelfde voor de margin-bottom van het laatste element van de inhoud).

Dan hiervoor maar vlug twee nieuwe classes aangemaakt.

stylesheet

.notopgap {

margin-top: 0;
}

.nobottomgap {

margin-bottom: 0;
}

html

<div class="inside">

<p class="notopgap">Eerste element</p>
<p>Andere elementen...</p>
<p class="notbottomgap">Laatste element</p>

</div>


Het meeste werk is nu gedaan.

Zie stap 4 in werking

Stap 5: Onderkant

Hier begint het spiegelbeeld van de eerste stappen. We hebben alleen van de figuren de op-z'n-kop versies nodig.

stylesheet

.bottom-left {

background-image: url('images/corner-botleft1280x9.gif');
height: 9px;
font-size: 2px;
margin-right: 9px;
}

.bottom-right {

background-image: url('images/corner-botright9x9.gif');
background-position: 100% 0;
background-repeat: no-repeat;
height: 9px;
font-size: 2px;
margin-top: -9px;
}

html

<div class="bottom-left"></div>
<div class="bottom-right"></div>


Opgelet: in het geval we alleen hoeken zonder randlijnen willen, moeten we in de bottom-left stijl de "width: 9px;" van de linker onderhoek meegeven, of anders zal deze zich op de achtergrond naar rechts blijven herhalen.

Maar in elk geval: onze methode werkt!

Zie stap 5 in werking

Stap 6: Vereenvoudiging

Tot dusverre hebben we 4 images voor dit model gebruikt. Maar met in gedachten het artikel over snelle css-rollovers van Petr ('Pixy') Stanicek lijkt het wel zo mooi om de zaak op te schonen en maar één figuur voor alles te gebruiken.
We beginnen de 4 images aan elkaar te plakken:

a long sigar

Dan gebruiken we het kijkvenster voor background-images om alle onderdelen naar hun goede positie te manoeuvreren, net als we in stap 3 deden met de linker hoeken. Op een kladblaadje zien we hoe we dit moeten aanpakken.

corners divided

De eigenschappen voor de linker bovenhoek hoeven niet te veranderen. De rechter bovenhoek, als spiegelbeeld van de linkerkant, hoeft nu niet meer rechts te drijven (dat kan via de background-position geregeld worden), maar moet wel een margin-left van 9px krijgen om te verhinderen dat de bovenlijn het transparante deel van de linkerbovenhoek doorkruist. De opgegeven breedte voor de rechterhoek (nu met bovenlijn) kan in rook opgaan: overbodig.

Hetzelfde geldt voor de onderkant. Hier moeten we alleen de onderste helft van de totaalfiguur omhoog halen (met de 9px hoogte van de bovenste helft), zodat de onderste delen van de figuur getoond worden in plaats van de bovenste hoeken en lijnen. De stijlcode verandert in:

stylesheet

.top-left {

margin-right: 9px; /* hou rechter hoekje vrij */
background-image: url('images/corners1280x18.gif');
height: 9px; /* toon alleen bovenste helft van de figuur */
font-size: 2px; /* corrigeer hoogte voor IE */
}

.top-right {

margin-top: -9px; /* naar niveau van linker hoekje */
margin-left: 9px; /* hou linker hoekje vrij */
background-image: url('images/corners1280x18.gif'); 
background-position: 100% 0; /* laat achtergrond vanaf rechts beginnen */
height: 9px; 
font-size: 2px;
}

.bottom-left {

margin-right: 9px; /* hou rechter hoekje vrij */

background-image: url('images/corners1280x18.gif');
background-position: 0 -9px; /* toon onderste helft figuur */
height: 9px;
font-size: 2px;
}

.bottom-right {

margin-top: -9px; /* naar niveau van linker hoekje */
margin-left: 9px; /* hou linker hoekje vrij */
background-image: url('images/corners1280x18.gif'); 
background-position: 100% -9px; /* onderste helft, rechts beginnen */
height: 9px; 
font-size: 2px; 
}

.inside {

border-left: 1px solid #C00000;
border-right: 1px solid #C00000;
background: #EFEFEF;
color: #000000;
padding-left: 10px;
padding-right: 10px;
}

.notopgap {

margin-top: 0;
}

.nobottomgap {

margin-bottom: 0;
}

 

Nu we op deze manier alle vier de hoeken hebben bijgeschaafd voor de ene background-figuur, is het ruwe materiaal klaar.

Zie stap 6 in werking

De complete css

Nu we alle style-elementen werkend hebben, kunnen we nog wat gaan verfijnen en bezuinigen. We kunnen elementen met dezelfde stijl combineren, en we kunnen de code comprimeren door de korte notatie te gebruiken.
En natuurlijk halen we het style-blok uit de <head> van onze bouwpagina, en maken er een net extern stylesheet van.

Hoewel de proefnemingen hierboven nogal wat code vroegen en er wel wat gecompliceerd uitzagen, is wat er op het laatst overblijft een lekker klein en eenvoudig stylesheet.
Zonder de commentaren bestaat het stylesheet uit zo'n 10 regeltjes code, en is het maar zo'n 0,5kB groot. Dat is snel!

Zie het complete basis stylesheet: liquidcorners.css

Wat er in je html-pagina's overblijft, is alleen de link naar het stylesheet en een paar regeltjes om het spul in werking te zetten op de plaatsen waar je de hoekjes wilt laten verschijnen.

html (head)

<link rel="stylesheet" type="text/css" href="liquidcorners.css">

html (body)

<div class="top-left"></div>
<div class="top-right"></div>

<div class="inside">

<p class="notopgap">...</p>
...
<p class="nobottomgap">...</p>

</div>
<div class="bottom-left"></div>
<div class="bottom-right"></div>


En ingeval het eerste element van de inhoud tegelijkertijd het laatste element is, kunnen we de twee no-gap classes combineren:

html (body)

<p class="notopgap nobottomgap">...</p>


Voor het snellere kopie-/plakwerk kan je nog de 3 startregels in één regel zetten, en de 3 eindregels ook. Dus voor instant-plakken:

Zie tekstbestand: paste-liquidcorners.txt

Wat je eigenlijk als enige handmatig moet doen, is het toevoegen van de classes "notopgap" en "nobottomgap" aan het eerste/laatste element van de inhoud van de box. Maar geen zorg: als je een spleet ziet, weet je wat er mist! smiley
 

Haast?

Alle gebruiksaanwijzingen voor het stylesheet (en de varianten in de Speeltuin) zijn als commentaar opgenomen in de broncodes ervan: dus dat is alles wat je nodig hebt om te downloaden.
De stylesheets, wat images en een leesmij zitten samen in:

francky's liquidcorners-homekit.zip
(100kB)

Flexibele ronde hoeken: makkelijk te maken!

overal te
plaatsen

 

overal te
plaatsen

overal te
plaatsen

Evaluatie

De html- en css-validator van het w3c feliciteren hiermee, dus deze flexibele hoeken zouden zich in alle moderne browsers goed moeten laten zien. Zelfs Internet Explorer kan ermee omgaan zonder noemenswaardige extra hacks of workarounds (dat mag wel in de krant). De prestaties zijn door mij getest onder Windows 98SE: IE6, Firefox-1.0.6, Mozilla-1.7, Netscape-6.2 en Opera-7.54 en Opera-8 (met als resultaat: alles in orde wink).

Update 11 febr. 2006:
Door Thomas -Balu- Walter werd ik gewezen op een foutje in de tekst van stap 3; gecorrigeerd! (geen gevolgen voor de rest)

Variaties

Met dezelfde principes kan je een hoop meer doen. In de speeltuin staan een paar varianten van dit stylesheet: een kalere versie voor alleen hoek-figuren zonder rand, en een iets uitgebreide versie voor zelf gemaakte randjes links en rechts van de box.
Misschien krijg ik nog eens nieuwe inspiratie en genoeg ideeën om een "deel II" te schrijven met wat meer voorbeelden en nog het een en ander ... en een linken-pagina is er nog niet, en ... dus .. wanhopig op zoek naar tijd.

Speeltuin

In de tussentijd ben je welkom in m'n mini Flexibele Hoeken Speeltuin ("Liquid Corners Playgarden"), waarin ik wat voorbeelden / experimenten gestald heb. Misschien kan ik er later ook bijdragen van anderen in opnemen.
 

Geniet van de schoonheid van css!

francky kleyneman 12 oct. 2005

 

De aanleiding voor dit artikel was een vraag in het NL forum "www.designhulp.nl":

http://designhulp.nl/forum/basistechnieken/css-layout/8900/1#frmMsg56326

 

Valid HTML 4.01 Transitional

Valid CSS

mail francky?
mail francky!