5568 sujets

Sémantique web et HTML

Bonjour,

J'ai récemment été confronté à un problème assez bête mais je n'ai pas trouvé de solution à part de changer mon code HMTL.

Voici le problème :


<form>
 <label>
  <input type="checkbox">
  <span>j'accepte les <a href="monlien">conditions d'utilisation</a> du service</span>
 </label>
</form>


Le problème c'est qu'en cliquant sur le label, ça coche / décoche la checkbox mais le lien vers les conditions d'utilisation ne fonctionne pas. Normal d'un côté, mais comment palier à ce problème ?

Merci
salut,
ça devrait marcher normalement par contre c'est une mauvaise pratique que de procéder ainsi pour un formulaire. La structure devrait être :

<form action="traitement.php">
	<input type="checkbox" id="conditions" />
	<label for="conditions">J'accepte les <a href="mon-lien.php">conditions d'utilisation</a> du service</label>
</form>

Les aides techniques qui ont le plus besoin de label ne reconnaissent effectivement pas du tout, ou très mal, la construction théoriquement valide <label><input /></label>. IL ne faut pas l'utiliser.

Par contre je ne suis pas sûr que la construction classique fonctionne mieux. Le clic sur un lien contenu dans un label est toujours par défaut ambigü: faut-il activer le lien, basculer la case ou les deux ?

Pour être complet, je pense qu'il faut intercepter le clic au niveau du lien, ne pas return false pour que le lien puisse s'ouvrir normalement, mais l'empêcher de rayonner au niveau supérieur pour ne pas que la case bascule en même temps que le lien s'ouvre. A tester. Mais dans tous les cas tu vois que c'est problématique, on a deux zones réagissant au clic qui sont superposées.
Modifié par QuentinC (21 Mar 2014 - 19:10)
Les deux fonctionnent correctement. Ça a été testé (sur PC) sur tous les navigateurs majeurs et le lien marche.
Personnellement je trouve qu'il ne devrait pas y avoir de conflits vu que le lien prime sur la checkbox.
a écrit :
Personnellement je trouve qu'il ne devrait pas y avoir de conflits vu que le lien prime sur la checkbox.

C'est humainement ce qui paraît le plus logique en effet. Mais techniquement, pas forcément.
perso, il y a une incohérence , imbriqué 2 éléments cliquable qui ont deux fonctions différentes,
Si l'on parlait d'imbriqué 2 liens ou 2 labels , les avis serait moins partagés.

A part JavaScript , pour assurément donner la priorité a l'un ou l'autre , au premier puis second clique , pour enfin pouvoir cocher la checkbox, je ne vois pas vraiment.

En théorie, on peut penser que le dernier élément couvre le fond de son parent et intercepte le clique, certains navigateur ne le font pas toujours si le fond est translucide, et paf si le clique tombe entre 2 lettres. On peut donner une couleur de fond pour y remédier et faire en sorte que cet élément couvre 100% de son parent.

Curieux, je me demande aussi comment ça se comporte ou se gère via les touches tab/enter ?
gc-nomade a écrit :
Si l'on parlait d'imbriqué 2 liens ou 2 labels , les avis serait moins partagés.

Je ne sais pas trop si je t'ai bien compris mais en temps normal, c'est impossible (et incorrect) d'imbriquer deux liens ou deux labels. Donc il ne devrait pas y avoir de problèmes à ce niveau.
Cela dit on pourrait comprendre que chacun ait un avis différent sur la question.

gc-nomade a écrit :

A part JavaScript , pour assurément donner la priorité a l'un ou l'autre , au premier puis second clique , pour enfin pouvoir cocher la checkbox, je ne vois pas vraiment.

J'ai peut être raté une version de navigateur qui crée un conflit avec cette structure mais selon mes tests, cela marchait sur tous les navigateurs sur PC et si ça marche, JS ne devrait pas se mêler de tout ça au risque peut être de rendre les choses encore plus compliqués.
Sauf s'il y a un truc qui m'échappe Smiley ohwell
On m'a appris à mettre mon input et ma phrase dans un label pour qu'au clic sur le label la checkbox se coche, c'était l'avantage pour les situations classiques..

Je suis d'accord avec toi Zelalsan sur le fait que ça devrait fonctionner et en fait après un test du html sans js, oui ça fonctionne mais il y a un détail que j'ai omis de préciser.. Smiley langue

En fait j'ai mis en place des checkbox custom. J'ai donc du mettre l'input en display none et avoir recours à du javascript pour détecter le clic sur le label. Lors de cette détection, je me suis rendu compte en faisant un console.log() que toutes les actions étaient répétées 2x, j'ai donc du utiliser .preventDefault() pour palier à ça sauf que du coup ça ne cochait plus ma case.. je la recoche donc en js mais le lien lui ne fonctionne plus :


var conditionsChecked = false;
        $('label').click(function(e){
        	e.preventDefault();
        	conditionsChecked = !conditionsChecked;
			$('label').checked = conditionsChecked;
			console.log(conditionsChecked);
        });


Voila toute l'histoire de mon problème !
@zelasan, peut-être as tu zappé ceci, j'y ai déjà été confronté, et bien sur c'est IE , et ce sont des version qui trainent encore.
gc-nomade a écrit :
et intercepte le clique, certains navigateur ne le font pas toujours si le fond est translucide, et paf si le clique tombe entre 2 lettres.

Pour un site perso on s'en tape , quoique, mais lorsqu'il s'agit de cocher l'acceptation de conditions légales, il y a là une importance a éviter ce risque.

Du coup , ma réflexion sur l’incohérence d'imbriquer 2 éléments qui ont une fonction au clicque. Ceux-ci devrait !? ... tout deux réagir à un seul click, est ce a dire, se prendre un demi clique chacun ?

Pour l'exemple des <a> imbriqué , à l'époque de ie6 et moins avec toute sorte d'effet de rollover voulu et bien sur sans javascript, toute sorte d'imbrication était rencontrés de façon récurrente sur les forums ...
Bonne ou mauvaise pratique d'un <a> dans un <label> , je m'interroge, mais pas trop, il y a un truc qui cloche à mon sens.
Cordialement
a écrit :
Curieux, je me demande aussi comment ça se comporte ou se gère via les touches tab/enter ?

Pour tab, la construction <a> dans <label> ne pose aucun problème, ce n'est pas le label qui prend le focus mais bien le champ associé, puis le lien le tab d'après.

a écrit :
Pour l'exemple des <a> imbriqué , à l'époque de ie6 et moins avec toute sorte d'effet de rollover voulu et bien sur sans javascript, toute sorte d'imbrication était rencontrés de façon récurrente sur les forums ...

Ca n'en reste pas moins invalide et donc peu recommandable à moins de savoir exactement ce qu'on fait.

a écrit :
En fait j'ai mis en place des checkbox custom. J'ai donc du mettre l'input en display none et avoir recours à du javascript pour détecter le clic sur le label.

IL y a à mon avis plusieurs erreurs de conception ici
1 - Intercepter le clic sur le label spécifiquement, normalement ça n'a pas de sens; le clic sur le label devrait déclencher onclick sur la checkbox.
2 - Comment ton truc se comporte avec tab ? mal je suppose, si tu laisses la checbox qui est cachée focusable. Si tu masques ta case avec display:none alors elle ne doit pas être focusable non plus; le focus n'est pas censé pouvoir être donné à un élément invisible. Alors de deux choses l'une, l'utilisateur arrive sur la case avec tab et soit il est perdu parce qu'il ne voit pas où elle est, soit elle devient visible tout pendant qu'elle a le focus mais à un endroit potentiellement totalement imprévisible.
3 - La bonne façon de faire pour un contrôle custom, c'est gérer le focus et le clavier manuellement et convenablement (pour faire court pour une checkbox ça veut dire en gros tabindex=0 et gérer espace/enter), et utiliser ARIA pour que les outils d'assistance comprennent de quoi il s'agit. Étant donné que tu ne peux pas utiliser de label pour un champ custom (il me semble que l'attribut for est obligatoire), il faut avoir recours à aria-label ou aria-labelledby et gérer le clic manuellement.
Si tu veux supporter les navigateurs sans js, alors le plus simple est sûrement de cacher l'input et remplacer le label initial au chargement de la page.
Bref, beaucoup de choses à penser pour une simple checkbox custom qui fonctionne correctement dans tous les contextes; tu ferais mieux de ne pas en utiliser, tout simplement !
Merci pour ces précisions,

1. Le clic sur le label ne génère aucun action autres que celles de ma fonction à cause du preventDefault(), c'est pour ça que j'ai besoin de cocher la checkbox manuellement (et c'est aussi pour ça que mon lien ne fonctionne pas ...)

2. Oui il est impossible de sélectionner la checkbox avec tab vu qu'elle est en display none. Je suis d'accord que ce n'est pas opti mais il est actuellement impossible de styliser à volonté les input de type radio ou checkbox, donc je dois bidouiller..

a écrit :
tu ferais mieux de ne pas en utiliser, tout simplement !


Je suis d'accord mais va dire ça à la cliente et aux créa qui ont fait les maquettes. Pour eux c'est normal de styliser ce genre d'éléments, ils s'en foutent qu'on ne puisse pas sélectionner le champs avec tab ou que cela pose des problèmes d'accessibilité, tant que globalement ça fonctionne.

C'est moche je sais, vive le monde de l'agence. Smiley smile
a écrit :
1. Le clic sur le label ne génère aucun action autres que celles de ma fonction à cause du preventDefault(), c'est pour ça que j'ai besoin de cocher la checkbox manuellement (et c'est aussi pour ça que mon lien ne fonctionne pas ...)

A tout hasard, est-ce que tu as déjà essayé de jouer avec les z-index ? La solution est peut-être là. Parce que si je comprends bien la situation, il y a une chance pour que le lien ne fonctionne pas parce que le clic est absorbé par ta fonction + preventDefault sur le label qui le recouvre.

a écrit :
2. Oui il est impossible de sélectionner la checkbox avec tab vu qu'elle est en display none. Je suis d'accord que ce n'est pas opti mais il est actuellement impossible de styliser à volonté les input de type radio ou checkbox, donc je dois bidouiller..

Pas optimum ? C'est pire que ça, tu viens peut-être de perdre des clients potentiels à ton service vu qu'ils ne peuvent pas terminer l'inscription. Et pour un truc bête et super frustrant en plus, ne pas pouvoir cocher la case "j'accepte les CGU".

Laissons les navigateurs sans js pour le moment (je pense qu'il y en a de toute façon plus beaucoup en 2014), mais si tu veux des checkbox custom qui fonctionnent bien chez tout le monde, tu devrais aller jusqu'au bout en gérant correctement tous les périphériques d'entrée potentiels et ARIA.
a écrit :
A tout hasard, est-ce que tu as déjà essayé de jouer avec les z-index ?

Oui c'est le premier truc que j'ai testé (sait on jamais) mais non ça ne fonctionne pas et c'est logique d'un côté.

a écrit :
Pas optimum ? C'est pire que ça, tu viens peut-être de perdre des clients potentiels à ton service vu qu'ils ne peuvent pas terminer l'inscription.

La je ne te suis pas. d'IE8 à chrome il est possible de cocher la case d'un simple clic sur le label donc les clients potentiels perdu seraient :
- Ceux qui ont désactivé / n'ont pas javascript
- Ceux qui utilisent Internet Explorer < 8
- A voir pour les mobiles, mais dans mon cas la page n'est pas accessible depuis mobile car il s'agit d'une application Facebook.

a écrit :
tu devrais aller jusqu'au bout en gérant correctement tous les périphériques d'entrée potentiels et ARIA.

Je suis d'accord et je vais faire un code propre et réutilisable pour mes input custom. Cela me reservira par la suite de toute façon.

Merci pour vos réponses et commentaires en tout cas. Smiley smile
En deplaçant le label sous les CGU , est ce que ce comportement , scenario, ressemble a ce que tu cherches à faire ?
http://codepen.io/gc-nomade/pen/qFdkD/ -> pas la soluce ni forcement une bonne idée , mais la place qu'occupe le label dans la structure n'est pas forcement d'etre a toucher son input Smiley smile

inside , popup modale et radio custom :
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>CodePen - A Pen Test by gc-nomade</title>
    <style media="screen" type="text/css">
      #cgu, :checked ~ #cgu{
      display:none;
      text-align:center;
      position:absolute;
      left:50%;
      margin-left:-200px;
      width:360px;
      border:solid;
      background:gray;
      padding:20px;
      box-shadow:0 0  500px 100px;
      border-radius:10px; 
      }
      #cgu:target {
      display:block;
      }
      .cgu {
      width:300px;
      height:200px;
      overflow:auto;
      text-align:left;
      margin:auto;
      background:white;
      border:inset;
      margin-bottom:20px;
      }
      #cgu label {
      display:inline-block;
      line-height:1.5em;
      border:solid 1px;
      padding:0 1em;
      margin:0 0.5em;
      border-radius:5px;
      }
      #cgu label ,
      input + span:before  {
      box-shadow:
      -1px -1px 3px white,
      1px 1px 3px black,
      inset 0 0 15px white; 
      transition:0.5s;
      }
      #cgu label:hover, 
      #cgu label:active, 
      input:hover + span:before {
      cursor:pointer;
      box-shadow:
      -1px -1px 3px black,
      1px 1px 3px white,
      inset 0 0 15px white;
      }
      :checked ~ #cgu{
      display:none;
      }
      .noclick  {
      pointer-events:none;/* pas de click possible */
      }
      input[type="radio"] {
      position:absolute;
      opacity:0;/* on le cache */
      transform:scale(2);/* on augmente la zone reactive */
      }
      input[type="radio"] + span:before {/* span a styler pour afficher au lieu des input */
      content:'';
      display:inline-block;
      height:1em;
      width:1em;
      line-height:1em;
      vertical-align:middle;
      }
      input:checked + span:before {
      content:'\2714';.* heavy check mark */
      }
    </style>
  </head>
  <body>
    <form action="#" method="post">
      <a href="#cgu">lire et accepter les conditions</a>
      Accepter<input type="radio" id="ckb" name="ckb" value="ok" class="noclick"/> <span></span> ou 
      Refuser <input type="radio" id="nop" name="ckb" value="nop"/> <span></span>
      <br/><input type="reset" value="revoir mon choix" /><input type="submit" />
      <div id="cgu">
        <div class="cgu">
          <p>tout plein de blabla important </p>
        </div>
        <label for="ckb">j'accept</label>
        <label for="nop">je décline</label>
      </div>
    </body>

  </html>

Modifié par gc-nomade (23 Mar 2014 - 20:55)
@gc-nomade> Je crois que je vois à peu près ce que tu veux dire. Perso et pour l'exemple en cours, je dirais qu'il serait logique que le lien soit actif, même imbriqué dans un <label>. En suivant la propagation de l'évènement, celui-ci s'applique d'abord au nœud le plus profond avant d'être transmis au parent (sans entrer dans les détails et les exceptions complexes). Comme dans la majore partie des cas, un lien fait changer de page, on n'aura pas le temps de voir l'action sur le <label> et par enchaînement des choses, sur la checkbox.
Donc je dirais qu'il serait logique qu'en cliquant sur le lien, on soit emmené vers la cible du lien.

@ganondorf150> Je n'ai pas trop pris le temps de lire toutes les réponses après ton message mais en effet tu as omis un détail assez important. Créer un custum checkbox devrait se faire d'une manière propre. Le principe serait le même que de créer un custum file input, on devrait juste jouer sur l'opacité de l'élément et les positions absolues sans passer par "display:none". L'évènement JS serait un simple "onchange" qui se déclenchera donc au clic du label ou de la checkbox. Un exemple vite fait par ici (tout pourri je sais Smiley langue ) pour expliquer le principe.
a écrit :
En deplaçant le label sous les CGU , est ce que ce comportement , scenario, ressemble a ce que tu cherches à faire ?
http://codepen.io/gc-nomade/pen/qFdkD/


Non pas du tout lol. Déjà au niveau de du "confort du hover" on va dire, ta souris se transforme en curseur sur ton exemple car on survole du texte. Ca ne donne pas très envie de cliquer, c'est pour ça qu'il faut le label. Et pour l'ouverture des CGU en popin, je suis sur une application Facebook donc ce n'est pas l'idéal dans ce cas car je n'ai que 810px et placer une page comme les CGU en popin dans 810px, t'as pas fini de scroller.. Et surtout l'ouverture d'une mini popin comme la.. Je trouve ça old en fait. ^^'
Full screen à la rigueur, mais la c'est un autre débat. En tout cas merci pour cette proposition Smiley langue

a écrit :
tu as omis un détail assez important. Créer un custum checkbox devrait se faire d'une manière propre. Le principe serait le même que de créer un custum file input, on devrait juste jouer sur l'opacité de l'élément et les positions absolues sans passer par "display:none".


Alors, ce n'est pas la première fois que j'ai a faire ce genre d'input et je recode à chaque fois car je n'ai toujours pas trouvé la technique parfaite pour ça. L'opacité déjà d'IE6 à 8 tu es obligé d'utiliser un hack et si jamais l'utilisateur clic sur l'emplacement de la case, le clic est absorbé et la vrai checkbox
ne se coche pas, te faisant croire que tu as validé le formulaire alors qu'en réalité quand tu vas appuyer sur valider tu vas revenir sur la page et le champs sera rouge. Smiley smile C'est pour ça que je me suis permet de tester carrément le display:none, après tout elle n'a pas besoin d'être affiché cette sale checkbox, je la coche en js. Par contre il faudrait prévoir un élément de substitution de la taille de la nouvelle checkbox et qui puisse être target pour respecter les normes.

C'est la qu'on voit qu'HTML ne s'adapte pas assez vite à la crosisance du web. Il devrait être normal en 2014 de pouvoir styliser via css ces éléments de formulaire dont le style appartient aux navigateurs..

L'évènement JS serait un simple "onchange" qui se déclenchera donc au clic du label ou de la checkbox. Un exemple vite fait par ici (tout pourri je sais Smiley langue ) pour expliquer le principe.
Wow j'avoue pas mal ! Smiley smile Par contre, et je pense que c'est lié à jsfiddle mais ton lien vers google ne s'ouvre pas (un peu comme le problème original de ce topic ^^).
Je n'ai pas très bien compris le problème qui se pose sur IE. Cela dit IE 6,7 ne sont plus à considérer (à mon sens) car totalement morts.
Le lien dans mon exemple ne s'ouvrira forcément pas et c'est bien parce que c'est sous JSField (il utilise des iframe donc...)
a écrit :
La je ne te suis pas. d'IE8 à chrome il est possible de cocher la case d'un simple clic sur le label donc les clients potentiels perdu seraient :
- Ceux qui ont désactivé / n'ont pas javascript
- Ceux qui utilisent Internet Explorer < 8
- A voir pour les mobiles, mais dans mon cas la page n'est pas accessible depuis mobile car il s'agit d'une application Facebook.

Tel que tu le présente, ton truc n'est pas accessible. Donc ça concerne aussi les non-voyants, ceux qui naviguent en mode texte, ceux qui naviguent au clavier, ... A noter que non-voyant ou clavier ou mode texte ne veut pas dire javascript désactivé, c'est une idée reçue qui est la plupart du temps fausse.

a écrit :
C'est la qu'on voit qu'HTML ne s'adapte pas assez vite à la crosisance du web. Il devrait être normal en 2014 de pouvoir styliser via css ces éléments de formulaire dont le style appartient aux navigateurs..

Tu mets malheureusement le doigt où ça fait mal.

Il devrait aussi être normal en 2014 que tous les sites web soient accessibles par défaut sans que les développeurs n'aient à réfléchir. Ca devrait être implicite et transparent.

Mais pour cela, ça impliquerait de remettre à plat certaines parties des standards complètement....

ARIA est très bien fait, mais ça ne devrait pas être la procédure standard pour faire des contrôles de formulaire au look custom. Je n'ai encore jamais vu un site sérieux utiliser des formulaires avec ARIA correctement jusqu'au bout en-dehors des démos, j'en conclus alors que soit c'est trop compliqué, soit ce n'est pas suffisament connu; et je penche plutôt pour le premier.

Pourquoi je dis que c'est trop compliqué, c'est simple: tu veux juste un contrôle qui a un look un peu différent de la normale, et pour faire bien tu te retrouves à devoir gérer le focus, le clavier, les autres périphériques d'entrée et les états internes manuellement. Alors qu'au fond, c'est toujours un contrôle standard qui doit se comporter de manière normale, il a juste un visuel personnalisé.

C'est très bien qu'ARIA existe, mais il devrait être réservé à ceux qui veulent vraiment faire des contrôles spéciaux, dont le comportement dévie de la normale. Pas ceux qui aimeraient juste que leur contrôle standard aient un aspect graphique différent.

Ca m'étonne d'ailleurs que les concepteurs au W3C n'ont pas pensé, tout simplement, de proposer des propriétés permettant de spécifier une image pour chaque état, ou allant dans le sens de contrôles owner-drawn. Ils l'ont bien fait avec <canevas> qui est une zone de dessin dédié; alors pourquoi pas un mode owner-drawn utilisable pour n'importe quel élément de formulaire, avec une fonction paint en javascript ? T'est content avec ce que te propose CSS alors t'en as pas besoin, et sinon, tu te démerdes en javascript pour dessiner ce que tu veux.
Modifié par QuentinC (24 Mar 2014 - 09:11)
Je viens de tomber sur une idée très intéressante:
http://blog.temesis.com/post/2014/03/18/cases-a-cocher-personnalisees-accessibles

Rangez donc les plans compliqués et foireux à base de span et d'ARIA; Leur concept est simple, ils affichent des images par-dessus la case normale. Résultat, ça marche avec jaws, ça marche au clavier, le focus est visible, et ça marche sans js ou sans CSS (j'ai testé la démo avec IE9).

Seul bémol, je crois me rappeler qu'afficher quelque chose au-dessus des contrôles de formulaire ne fonctionne pas dans certaines versions lointaines d'IE (le contrôle reste toujours affiché au-dessus de tout). Mais apparament c'est quand même compatible jusqu'à IE8, donc suffisament raisonnable niveau compatibilité il me semble.
Modifié par QuentinC (24 Mar 2014 - 14:18)
a écrit :
Je n'ai pas très bien compris le problème qui se pose sur IE.

Jusqu'à maintenant je mettais mon input et mon texte dans le label et je désactivais le label via la fonction preventDefault(). Le problème que je rencontrais est sur IE8 : si l'input à une opacity à 0, il est quand même la, bien qu'invisible. Et si tu clic exactement sur lui, le faux input se coche mais pas le vrai, et comme généralement c'est un champs obligatoire, quand tu valides le formulaire, la page est réaffiché avec le champs en rouge. Pourtant visuellement la case était cochée.
Cela vient probablement de ma mauvaise utilisation de mettre l'input dans le label, ça expliquerai que toi tu n'ai pas rencontré ce problème (ou alors tu ne l'as pas vu Smiley langue ) je testerai la prochaine fois que je rencontre ce cas.

@QuentinC je suis d'accord mais on part peut être un peu loin la. ^^ Et après tout, si les langages web étaient aussi simple ce serait à la porté de tous et nous n'aurions ne servirions plus à grand chose Smiley langue