Com estructurar un formulari web

Ara que ja coneixem els conceptes bàsics, veurem amb més detall els elements que s’utilitzen per a proporcionar estructura i significat a les diferents parts d’un formulari.

Requisits previs: Coneixements bàsics d'informàtica i una fonaments bàsics de l’HTML.
Objectiu: Aprendre a estructurar els formularis HTML i donar-los semàntica perquè compleixin criteris d’usabilitat i accessibilitat.

La flexibilitat dels formularis els converteix en una de les estructures més complexes pel que fa al codi HTML; pots crear qualsevol tipus de formulari bàsic amb elements i atributs específics de formulari. Fer servir una estructura correcta en crear un formulari HTML et garantirà la usabilitat i l’accessibilitat del formulari.

L'element <form>

L’element <form> defineix formalment un formulari i els atributs que determinen el comportament del formulari. Cada vegada que vols crear un formulari HTML, has de començar per aquest element i imbricar-hi tot el contingut a dins. Moltes tecnologies d'assistència i complements de navegador poden descobrir elements <form> i implementar codis de suport (hooks) especials per a facilitar-ne l’ús.

Ja ho hem vist en l’article anterior.

Atenció: Està totalment prohibit imbricar un formulari dins d’un altre formulari. És una mala idea perquè la imbricació de formularis pot introduir comportaments del tot imprevisibles.

Sempre és possible utilitzar un control de formulari fora d'un element <form>. Si ho fas, per defecte aquest control no tindrà res a veure amb cap formulari, tret que l’associïs a algun formulari amb l'atribut form. Això es va introduir per a permetre unir explícitament un control amb un formulari encara que no hi estigui imbricat.

Avancem una mica i observem els elements estructurals que trobaràs en un formulari.

Els elements <fieldset> i <legend>

L’element <fieldset> és una manera convenient de crear grups de controls que comparteixen el mateix propòsit, amb les mateixes finalitats d’estil i semàntiques. Pots etiquetar un element <fieldset> incloent un element <legend> just a sota de l'etiqueta d'obertura <fieldset>. El text contingut en l'element <legend> descriu formalment el propòsit de l'element <fieldset> que hi ha inclòs.

Moltes tecnologies d'assistència utilitzaran l'element <legend> com si fos una part de l'etiqueta de cada control de formulari que hi ha dins de l'element <fieldset> corresponent. Per exemple, alguns lectors de pantalla com Jaws i NVDA llegiran el contingut de la llegenda abans de llegir el text de l’etiqueta de cada control.

Aquí hi ha un petit exemple:

<form>
  <fieldset>
    <legend>Mida del suc de fruita</legend>
    <p>
      <input type="radio" name="size" id="size_1" value="small">
      <label for="size_1">Petit</label>
    </p>
    <p>
      <input type="radio" name="size" id="size_2" value="medium">
      <label for="size_2">Mitjà</label>
    </p>
    <p>
      <input type="radio" name="size" id="size_3" value="large">
      <label for="size_3">Gran</label>
    </p>
  </fieldset>
</form>

Nota: Pots trobar aquest exemple en el fitxer fieldset-legend.html (o consultar-ne l’exemple en viu).

En llegir el formulari anterior, un lector de pantalla dirà «Mida del suc de fruita: petit» per al primer giny, «Mida del suc de fruita: mitjà» per al segon i «Mida del suc de fruita: gran» per al tercer.

El cas d’ús que mostra aquest exemple és un dels més importants. Cada vegada que tinguis un conjunt de botons d'opció, els hauries d’imbricar dins d’un element <fieldset>. Hi ha altres casos d'ús i, en general, l'element <fieldset> també es pot utilitzar per a introduir seccions en un formulari. L’ideal seria que els formularis llargs ocupin diverses pàgines, però si un formulari s’allarga i només ha d’ocupar una sola pàgina, posar les diferents seccions relacionades dins de diferents elements <fieldset> millora la usabilitat.

L’element <fieldset> és un dels elements clau per crear formularis accessibles per l’efecte que té sobre la tecnologia d’assistència; tanmateix, és la teva responsabilitat no abusar-ne. Si és possible, cada cop que creïs un formulari, intenta escoltar com l’interpreta un lector de pantalla. Si sona estrany, prova de millorar l'estructura del formulari.

L'element <label>

Com hem vist en l’article anterior, l’element <label> és la manera formal de definir una etiqueta per a un control de formulari en HTML. Aquest és l’element més important si vols crear formularis accessibles: quan s’implementen correctament, els lectors de pantalla llegeixen l’etiqueta d’un element de formulari juntament amb qualsevol instrucció relacionada, i també resulta útil per als usuaris sense discapacitats. Considerem aquest exemple, que hem vist en l’article anterior:

<label for="name">Nom:</label> <input type="text" id="name" name="user_name">

Amb l'etiqueta <label> associada correctament amb l’element <input> per l’atribut for (que conté l'atribut id de l'element <input>), un lector de pantalla llegirà una cosa així com «Nom, editar text».

Hi ha una altra manera d’associar un control de formulari amb una etiqueta: introduir el control de formulari dins de <label> i associar-l’hi implícitament.

<label for="name">
  Nom: <input type="text" id="name" name="user_name">
</label>

Fins i tot en aquests casos, però, es considera una bona pràctica establir-hi l’atribut for per garantir que totes les tecnologies d’assistència entenen la relació entre l'etiqueta i el control.

Si no hi ha cap etiqueta o si el control de formulari no està associat implícitament ni explícitament amb una etiqueta, un lector de pantalla llegirà alguna cosa com ara «Editar text en blanc», la qual cosa no és gaire útil.

També pots clicar les etiquetes!

Un altre avantatge de configurar correctament les etiquetes és que pots fer-hi clic o tocar-les per a activar-ne el control corresponent. Això és útil per a controls com les entrades de text, en què pots fer clic a l’etiqueta i també a l’entrada per a donar-hi el focus, però és útil, sobretot, per als botons d'opció i les caselles de verificació; l’àrea d’aquest control pot ser molt petita, de manera que és útil per a facilitar-ne l’activació.

Per exemple, si fas clic al text de l'etiqueta «M'agraden les cireres» de l'exemple següent, canviarà l'estat seleccionat de la casella taste_cherry:

<form>
  <p>
    <input type="checkbox" id="taste_1" name="taste_cherry" value="cherry">
    <label for="taste_1">M'agraden les cireres</label>
  </p>
  <p>
    <input type="checkbox" id="taste_2" name="taste_banana" value="banana">
    <label for="taste_2">M'agraden els plàtans</label>
  </p>
</form>

Nota: Pots trobar aquest exemple en el fitxer checkbox-label.html (o consultar l’exemple en viu).

Etiquetes múltiples

Estrictament parlant, pots posar diverses etiquetes en un sol control, però no és una bona idea perquè algunes tecnologies d'assistència poden tenir problemes a l'hora de manejar-los. En el cas de tenir etiquetes múltiples, hauràs d’incloure el control i les seves múltiples etiquetes dins d’un únic element <label>.

Considerem l'exemple següent:

<p>Els camps obligatoris van seguits de <abbr title="required">*</abbr>.</p>

<!-- Doncs, això: --->
<div>
  <label for="username">Nom:</label>
  <input type="text" name="username">
  <label for="username"><abbr title="obligatori" aria-label="required">*</abbr></label>
</div>

<!-- seria millor fer-ho d'aquesta manera: -->
<div>
  <label for="username">
    <span>Nom:</span>
    <input id="username" type="text" name="username">
    <abbr title="obligatori" aria-label="required">*</abbr>
  </label>
</div>

<!-- Però això és probablement el millor: -->
<div>
  <label for="username">Nom: <abbr title="obligatori" aria-label="required">*</abbr></label>
  <input id="username" type="text" name="username">
</div>

El paràgraf de la part superior estableix una regla per als elements obligatoris. La regla s'ha d'incloure abans que s’hagi d'utilitzar perquè els usuaris generals i els usuaris amb tecnologies d’assistència, com ara lectors de pantalla, puguin saber què vol dir abans de trobar un element obligatori. Tot i que això ajuda a informar els usuaris què significa un asterisc, no ens en podem refiar. Un lector de pantalla llegirà un asterisc així: «estrella». Si s'hi passa el ratolí per sobre, hauria d'aparèixer «obligatori», que s'aconsegueix amb l'atribut title. Els títols que es llegeixen en veu alta depenen de la configuració del lector de pantalla, de manera que és més fiable incloure també l’atribut aria-label, que els lectors de pantalla llegeixen sempre.

Les variants anteriors augmenten l’efectivitat a mesura que hi avances:

  • En el primer exemple, l’etiqueta no es llegeix del tot amb l’entrada: només es llegeix «editar text en blanc»; a més, les etiquetes es llegeixen en realitat per separat. Els múltiples elements <label> confonen el lector de pantalla.
  • En el segon exemple, les coses són una mica més clares: l’etiqueta, llegida juntament amb l’entrada, és «Editar text nom estrella nom obligatori» i les etiquetes encara es llegeixen per separat. Tot és encara una mica confús, però aquesta vegada està una mica més bé, perquè <input> té una etiqueta associada.
  • El tercer exemple és el millor: l’etiqueta es llegeix realment en conjunt i l’etiqueta que es llegeix amb l’entrada és «Editar text nom requerit».

Nota: Pots obtenir resultats una mica diferents, segons quin sigui el teu lector de pantalla. Aquest ha estat provat amb VoiceOver (i NVDA es comporta de manera similar). Ens agradaria conèixer també les teves experiències.

Nota: Pots trobar aquest exemple a GitHub en el fitxer required-labels.html (o consulta l’exemple en viu). No provis l'exemple amb les dues o tres versions sense comentaris: els lectors de pantalla definitivament es confondran si tens diverses etiquetes i múltiples entrades amb el mateix ID.

Estructures HTML habituals que es fan servir als formularis

Més enllà de les estructures específiques dels formularis web, és bo recordar que l'etiquetatge del formulari només és HTML. Això significa que pots utilitzar tot el poder de l'HTML per a estructurar un formulari web.

Com es pot veure en els exemples, és una pràctica habitual delimitar una etiqueta i el control associat amb un element <li> dins d'un element de llista <ul> o <ol>. Els elements <p> i <div> també s'utilitzen de forma habitual. Per a estructurar diverses caselles de verificació o botons d'opció es recomana crear una llista.

A més de l’element <fieldset>, també és una pràctica habitual utilitzar títols HTML (per exemple, <h1>, <h2>) i seccionar (per exemple, <section>), per a estructurar formularis complexos.

Per sobre de tot, et correspon a tu trobar un estil de codificació còmode que doni lloc a formularis que compleixin criteris d’accessibilitat i usabilitat. Les seccions independents amb funcions diferents haurien d’estar contingudes en un element <section> separat, amb elements <fieldset> per a contenir botons d'opció.

Aprenentatge actiu: construir l’estructura d’un formulari

Posem en pràctica aquestes idees i construïm un formulari una mica més complicat: un formulari de pagament. Aquest formulari contindrà diversos tipus de controls que encara no coneixes. No et preocupis; en veuràs el funcionament en l’article següent (Els controls de formulari bàsics originals). Per ara, llegeix amb detall les descripcions mentre segueixes les instruccions següents i comences a entendre quins elements utilitzem per a estructurar un formulari, i per què.

  1. Per començar, fes una còpia local del fitxer de plantilla en blanc i del CSS del nostre formulari de pagament en un directori nou del teu ordinador.
  2. Aplica el CSS a l’HTML afegint la línia següent a l’element <head> de l’HTML:
    <link href="payment-form.css" rel="stylesheet">
  3. A continuació, afegeix l’element extern <form> per a crear el teu formulari:
    <form>
    
    </form>
  4. Afegeix un títol d’encapçalament encapçalament i un paràgraf a les etiquetes <form> per a informar els usuaris com es marquen els camps obligatoris:
    <h1>Forma de pagament</h1>
    <p>Els camps obligatoris van seguits de <strong><abbr title = "obligatori">*</abbr></strong>.</p>
  5. A continuació, afegirem una secció més gran de codi al formulari, a sota de l’entrada anterior. Aquí veuràs que delimitem amb un element <section> independent els camps amb la informació de contacte. A més, hi ha un conjunt de dos botons d'opció, cadascun dels quals col·loquem dins d’un element de llista (<li>) propi. També hi ha dos textos estàndard <input> i els seus elements <label> associats, cadascun imbricat dins d'un element <p> i un camp per a introduir una contrasenya. Afegeix aquest codi al teu formulari:
    <section>
        <h2>Informació de contacte</h2>
        <fieldset>
          <legend>Títol </legend>
          <ul>
              <li>
                <label for="title_1">
                  <input type="radio" id="title_1" name="title" value="K" >
                  Rei
                </label>
              </li>
              <li>
                <label for="title_2">
                  <input type="radio" id="title_2" name="title" value="Q">
                  Reina
                </label>
              </li>
              <li> 
                <label for="title_3"> 
                  <input type="radio" id="title_3" name="title" value="J">
                  Bufó 
                </label> 
              </li>
          </ul>
        </fieldset>
        <p>
          <label for="name">
            <span>Nom: </span>
            <strong><abbr title="required">*</abbr></strong>
          </label>
          <input type="text" id="name" name="username">
        </p>
        <p>
          <label for="mail">
            <span>Correu electrònic: </span>
            <strong><abbr title="required">*</abbr></strong>
          </label>
          <input type="email" id="mail" name="usermail">
        </p>
        <p>
          <label for="pwd">
            <span>Contrasenya:</span>
            <strong><abbr title="required">*</abbr></strong>
          </label>
          <input type="password" id="pwd" name="password">
        </p>
    </section>
  6. La segona secció (<section>) del nostre formulari és la informació de pagament. Hi ha tres controls diferents, juntament amb les seves etiquetes, cadascun inclòs en un element <p>. El primer és un menú desplegable (<select>) que selecciona el tipus de targeta de crèdit. El segon és un element <input> del tipus tel, que introdueix un número de targeta de crèdit; tot i que podríem haver utilitzat el tipus number, no volem la interfície d'usuari que s'hi aplica per defecte. L'últim és un element <input> del tipus date, per a introduir la data de caducitat de la targeta; aquest apareixerà amb un control de selecció de dates en els navegadors compatibles, i es converteix en una entrada de text normal en els navegadors no compatibles. Aquests tipus d’entrada més nous es reintrodueixen en l’article tipus d’entrades en HTML5.

    Introdueix el següent en la secció anterior:
    <section>
        <h2>Informació de pagament</h2>
        <p>
          <label for="card">
            <span>Tipus de targeta: </span>
          </label>
          <select id="card" name="usercard">
            <option value="visa">Visa</option>
            <option value="mc">Mastercard</option>
            <option value="amex">American Express</option>
          </select>
        </p>
        <p>
          <label for="number">
            <span>Número de targeta:</span>
            <strong><abbr title="required">*</abbr></strong>
          </label>
          <input type="tel" id="number" name="cardnumber">
        </p>
        <p>
          <label for="date">
            <span> Data de caducitat: </span>
            <strong><abbr title="required">*</abbr></strong>
            <em>en format mm/aa</em>
          </label>
          <input type="date" id="date" name="expiration">
        </p>
    </section>
  7. L’última secció que afegim és molt més senzilla, perquè només conté un element <button> de tipus submit, que envia les dades del formulari. Afegeix això al final del formulari:
    <p> <button type="submit">Validar el pagament</button> </p>

A sota pots veure en acció el formulari acabat (també el pots trobar a GitHub; consulta el codi d’origen a payment-form.html i executa’l en viu):

Resum

Ara tens tot el coneixement que necessites per a estructurar adequadament els teus formularis web. En els pròxims articles tractarem moltes de les funcions que s’introdueixen aquí; l’article següent explica amb més detall l’ús de tots els diferents tipus de controls de formulari que voldràs utilitzar per a recopilar informació dels teus usuaris.

Consulta també

En aquest mòdul

Temes avançats