MDN’s new design is in Beta! A sneak peek: https://blog.mozilla.org/opendesign/mdns-new-design-beta/

Geavanceerde styling van HTML-formulieren

Deze vertaling is niet volledig. Help dit artikel te vertalen vanuit het Engels.

In dit artikel wordt ingegaan op het gebruik van CSS in HTML-formulieren om moeilijk te stijlen widgetsaan te passen. Zoals in vorig artikel werd aangegeven vormen tekstvelden en knoppen geen enkel probleem in CSS. Hier wordt dieper ingegaan  op de donkere kant van het stijlen van HTML-formulieren.

Even ter herinnering:

The bad
Elementen die moeilijk aan te passen zijn en die ingewikkelde trucs nodig hebben en soms ook geavanceerde kennis van CSS3.
The ugly
Elementen die praktisch niet kunnen aangepast worden. In het beste geval kunnen enkele zaken gedaan worden maar die werken dan weer niet in andere browsers. Volledige controle over de stijl van dergelijke elementen is onmogelijk.

CSS uiterlijk

Het probleem met formulierwidgets andere dan tekstvelden en knoppen, is dat in veel gevallen CSS niet expressief genoeg is.

Recent is daar wel verbetering in gekomen:

Dit alles is een goed begin maar er zijn twee problemen: ten eerste een aantal browsers implementeert niet verder dan CSS 2.1. En ten tweede zijn deze nauwelijks voldoende om ingewikkelde formulieren te stylen. Zoals bijvoorbeeld datepicker dat toelaat een  datum te kiezen uit een lijst van datums.

Er zijn bij sommige browsers experimenten gaande betreffende de presentatie van formulieren en soms is het nuttig te weten wat er bestaat.

Waarschuwing: ondanks dat die experimenten aantrekkelijk lijken,  zijn zij niet standaard, hetgeen betekent dat zij niet betrouwbaar zijn. Gebruik ervan is op eigen risico en misschien is het beter van ze niet te gebruiken want men zou iets kunnen doen dat slecht is voor het Web door niet-standaard eigenschappen te gebruiken.

De presentatie van formulierelementen instellen

Browsers gebaseerd op WebKit (Chrome, Safari) en Gecko (Firefox) kunnen het best overweg met aanpassing van HTML-elementen. Zij zijn ook over platformen heen inzetbaar omdat zij een mechanisme hebben om over te schakelen tussen natuurlijk uitzicht en aanvoelen en elementen die door de gebruiker kunen aangepast worden.

Hiertoe gebruiken zij de eigenschap: -webkit-appearance of -moz-appearance. Deze eigenschappen zijn niet standaard en worden best niet gebruikt. Zij gedragen zich zelfs verschillend in WebKit en in Gecko. Eén waarde is wel goed te gebruiken: none. Met deze waarde heeft men (praktisch volledige) controle over de stijl van bepaalde widgets.

Hieronder enkele voorbeelden. Het gebruik is het best aan te tonen bij zoekvelden met WebKit browsers:

<form>
    <input type="search">
</form>
<style>
input[type=search] {
    border: 1px dotted #999;
    border-radius: 0;
    
    -webkit-appearance: none;
}
</style>

Nota: het is altijd moeilijk de toekomst te voorspellen betreffende webtechnologieën, maar CSS-uitbreidingen zijn niet eenvoudig en er gebeurt ook onderzoek naar andere specificaties zoals Shadow DOM  dat enig perspectief biedt. De zoektocht naar het volledig aanpasbaar formulier is nog lang niet over.

Voorbeelden

Keuzevakjes en keuzerondjes

Het voorkomen van keuzevakjes en -rondjes is nogal rommelig. Zo is het bijvoorbeeld niet de bedoeling om de afmetingen van keuzevakjes en -rondjes te wijzigen en sommige browsers kunnen nogal verschillend reageren  wanneer men dit tracht te doen.

Een eenvoudige test

<span><input type="checkbox"></span>
span {
    display: inline-block;
    background: red;
}

input[type=checkbox] {
    width : 100px;
    height: 100px;
}

Zo wordt dit in de verschillende browsers weergegeven:

Browser Rendering
Firefox 16 (Mac OSX) Rendering of a sized check box on Firefox
Chrome 22 (Mac OSX) Rendering of a sized check box on Chrome
Opera 12.01 (Mac OSX) Rendering of a sized check box on Opera
Internet Explorer 9 (Windows 7) Rendering of a sized check box on IE9
Internet Explorer 7 (Windows XP) Rendering of a sized check box on IE7

Een ingewikkelder voorbeeld

Omdat Opera en Internet Explorer geen eigenschappen hebben als -webkit-appearance of -moz-appearance, is het niet mogelijk deze te gebruiken. CSS is gelukkig wel in staat om dit te omzeilen. Neem het volgend klassiek voorbeeld:

<form>
  <fieldset>
    <p>
      <input type="checkbox" id="first" name="fruit-1" value="cherry">
      <label for="first">I like cherry</label>
    </p>
    <p>
      <input type="checkbox" id="second" name="fruit-2" value="banana" disabled>
      <label for="second">I can't like banana</label>
    </p>
    <p>
      <input type="checkbox" id="third" name="fruit-3" value="strawberry">
      <label for="third">I like strawberry</label>
    </p>
  </fieldset>
</form>

met als basisstijl:

body {
  font: 1em sans-serif;
}

form {
  display: inline-block;

  padding: 0;
  margin : 0;
}

fieldset {
  border : 1px solid #CCC;
  border-radius: 5px;
  margin : 0;
  padding: 1em;
}

label {
  cursor : pointer;
}

p {
  margin : 0;
}

p+p {
  margin : .5em 0 0;
}

Aanpassing van het keuzevakje:

De bedoeling is het basis keuzevakje te vervangen door een eigen keuze. Onze keuze moet dezelfde toestanden kennen als het originele keuzevak. Deze toestanden zijn: aangevinkt, niet-aangevinkt, niet-aktief aangevinkt en niet-actief niet-aangevinkt. Dit ziet er als volgt uit:

Check box CSS Sprite

Vooreerst moeten de originele keuzevakjes verborgen worden. Daartoe worden ze buiten het gezichtsveld geplaatst. Hierbij moeten twee zaken in acht genomen worden:

  • Om de keuzevakjes te verbergen mag display:none  niet gebruikt worden omdat de gebruiker ze nog moet kunnen bedienen. Hij moet ze immers kunnen aan- of uitvinken. Met display:none is het keuzevak niet meer toegankelijk voor de gebruiker.
  • De vormgeving gebeurt door CSS3. Om compatibel te blijven met oudere browsers wordt de :root  pseudoklasse gebruikt. Oudere browsers, als Internet Explorer, tonen dan een gewoon keuzevak, terwijl de moderne browsers het aangepaste keuzevak zullen tonen.
:root input[type=checkbox] {
  /* original check box are push outside the viexport */
  position: absolute;
  left: -1000em;
}

Dan moet het eigen keuzevak toegevoegd worden. Daarvoor wordt gebruik gemaakt van het :before pseudo-element dat behoort bij het <label> element van het oorspronkelijk keuzevak. Dan wordt het keuzevak geselecteerd en door middel van de adjacent sibling selector wordt het bijbehorende label geselecteerd. Tenslotte wordt het :before pseudo-element ingevoegd en wordt bepaald hoe het keuzevakje er moet uitzien.

:root input[type=checkbox] + label:before {
  content: "";
  display: inline-block;
  width  : 16px;
  height : 16px;
  margin : 0 .5em 0 0;
  background: url("https://developer.mozilla.org/files/4173/checkbox-sprite.png") no-repeat 0 0;

/* The following is used to adjust the position of 
   the check boxes on the text baseline */

  vertical-align: bottom;
  position: relative;
  bottom: 2px;
}

De toestand van ket keuzevakje wordt vastgelegd met de :checked en :disabled pseudoklassen. Omdat er met CSS sprite wordt gewerkt moet alleen de positie van de achtergrond aangepast worden.

:root input[type=checkbox]:checked + label:before {
  background-position: 0 -16px;
}

:root input[type=checkbox]:disabled + label:before {
  background-position: 0 -32px;
}

:root input[type=checkbox]:checked:disabled + label:before {
  background-position: 0 -48px;
}

Er moet nog een (zeer) belangrijk punt afgewerkt worden. Als de gebruiker het toetsenbord gebruikt om tussen de widgets te navigeren, moet er visueel aangegeven worden welke widget de focus heeft. Omdat de originele keuzevakjes verborgen zijn, moet dat op een of andere manier opgevangen worden. Dit wordt op de volgende manier gedaan:

:root input[type=checkbox]:focus + label:before {
  outline: 1px dotted black;
}

Hier een voorbeeld:

Het probleem met select

Het <select> element is een 'lelijk' element omdat het onmogelijk consistent kan gestyled worden over platformen heen. Er zijn nochtans enkele mogelijkheden. Een voorbeeld:

<select>
  <option>Cherry</option>
  <option>Banana</option>
  <option>Strawberry</option>
</select>
select {
  width   : 80px;
  padding : 10px;
}

option {
  padding : 5px;
  color   : red;
}

De volgende tabel toont hoe de verschillende browsers er mee omgaan. De twee eerste  kolommen zijn het gewone voorbeeld. De twee volgende kolommen geven aan wat er gebeurt met de widgets bij gebruik van aangepaste CSS:

select, option {
  -webkit-appearance : none; /* To gain control over the appearance on WebKit */
  -moz-appearance : none; /* To gain control over the appearance on Gecko */

  /* Om de weergave bij Presto (Opera) en Trident (IE) aan te passen.
     Noteer dat dit ook werkt bij Gecko en deels bij WebKit */  
  background : none;
}
Browser Normale weergave Aangepaste weergave
gesloten open gesloten open
Firefox 16 (Mac OSX) Select closed on Firefox on Mac OSX (No tweak) Select open on Firefox on Mac OSX (No tweak) Select closed on Firefox on Mac OSX Select open on Firefox on Mac OSX
Firefox 16 (Windows 7) Select closed on Firefox on Windows 7 (No tweak) Select open on Firefox on Windows 7 (No tweak) Select closed on Firefox on Windows 7 Select open on Firefox on Windows 7
Chrome 22 (Mac OSX) Select closed on Chrome on Mac OSX (No tweak) Select open on Chrome on Mac OSX (No tweak) Select closed on Chrome on Mac OSX Select open on Chrome on Mac OSX
Chrome 22 (Windows 7) Select closed on Chrome on Windows 7 (No tweak) Select open on Chrome on Windows 7 (No tweak) Select closed on Chrome on Windows 7 Select open on Chrome on Windows 7
Opera 12.01 (Mac OSX) Select closed on Opera on Mac OSX (No tweak) Select open on Opera on Mac OSX (No tweak) Select closed on Opera on Mac OSX Select open on Opera on Mac OSX
Internet Explorer 9 (Windows 7) Select closed on IE9 on Windows 7 Select open on IE9 on Windows 7 n.v.t. n.v.t.
Internet Explorer 7 (Windows XP) Select closed on IE7 on Windows XP Select open on IE7 on Windows XP n.v.t. n.v.t.

Ondanks het gebruik van de -*-appearance eigenschap zijn er nog enkele problemen:

  • De padding eigenschap wordt nog steeds niet gelijk behandeld in alle browsers.
  • De oude Internet Explorer laat geen soepele styling toe.
  • Firefox laat niet toe de pijl van het afrolmenu te stylen.
  • Bij het stylen van de <option> elementen binnen de afrollijst verschillen het gedrag van Chrome en Opera van systeem tot systeem.

En dit voorbeeld gaat slechts over drie CSS-eigenschappen. Wat als er nog meer eigenschappen zijn? Zoals het voorbeeld aantoont kan met CSS de voorstelling en het aanvoelen van deze widgets niet consequent toegepast worden. Maar een en ander kan wel aangepast worden als men aanvaardt dat er kleine verschillen zullen zijn tussen de ene browser en de andere en tussen het ene besturingssysteem en het andere.

In het volgend artikel wordt nagegaan welke eigenschappen in aanmerking komen: Tabel van compatibele formulierelementen.

De weg naar mooiere formulieren: nuttige bibliotheken en polyfills

Terwijl CSS zeer bruikbaar is voor keuzevakjes en keuzerondjes, is dat niet zo voor geavanceerde elementen. Ondanks dat enkele zaken mogelijk zijn met het  <select> element, kan de bestandsdialoog helemaal niet aangepast worden. Hetzelfde geldt voor datumpicker, enz.

Als volledige controle over formulierelementen gewenst is, zit er niets anders op dan JavaScript te gebruiken. In het artikel Het maken van aangepaste widgets wordt getoond hoe men zelf widgets kan aanpassen, maar er zijn ook enkele bibliotheken die van nut kunnen zijn:

  • Uni-form is  een kader dat formulieropmaak standaardiseert met CSS. Er is ook een optie voor extra mogelijkheden samen met jQuery.
  • Formalize is een uitbreiding van JavaScript (zoals jQuery, Dojo, YUI, enz.) die formulieren aanpast en normaliseert.
  • Niceforms is een standalone JavaScript methode die volledige websites kan aanpassen.

De volgende bibliotheken zijn niet uitsluitend voor formulieren, maar zijn zeer interessant:

  • jQuery UI biedt zeer interessante geavanceerde en aanpasbare widgets zoals datumpickers (met speciale aandacht voor toegankelijkheid).
  • Twitter Bootstrap is zeer nuttig bij het normaliseren van formulieren.
  • WebShim is een uitgebreid gereedschap dat HTML5 ondersteunt. Het gedeelte over webformulieren kan zeer nuttig zijn.

Houd er echter rekening mee dat de combinatie van CSS en JavaScript ook neveneffecten kan hebben. Bij gebruik van deze bibliotheken dient men steeds te beschikken over stylesheets waarop men kan terugvallen als het script niet werkt. Er zijn vele redenen waarom een script niet werkt, vooral in de mobiele wereld. En een website of een app moet er op voorzien zijn om deze gevallen op te vangen.

Besluit

Ondanks dat er hiaten zijn bij het gebruik van CSS in HTML-formulieren, is er dikwijls toch wel een manier om deze te omzeilen. Er is geen algemene oplossing, maar de moderne browsers bieden altijd nieuwe mogelijkheden. Voor 't ogenblik is de beste oplossing te leren hoe de verschillende browsers CSS ondersteunen bij het maken van HTML-formulieren.

In het volgend artikel wordt ingegaan op hoe de diverse HTML-formulierelementen de meest belangrijke CSS eigenschappen ondersteunen: Tabel van compatibele formulierelementen.

Zie ook

Documentlabels en -medewerkers

 Aan deze pagina hebben bijgedragen: coenegrachts
 Laatst bijgewerkt door: coenegrachts,