5568 sujets

Sémantique web et HTML

Bonjour à tous,
J'ai une petite question d'ordre technique.

Je souhaite créer une navigation par onglets. Pour celle-ci j'utilise une liste de définitions (DL, DT,DD) qui me semble plus appropriée que celle que je vois sur le net (ul li et div).


<dl [b]role="tablist"[/b]>
    <dt [b]role="tab"[/b]><a href="">Tab 1</a></dt>
    <dd [b]role="tabpanel"[/b]>Content 1</dd>
    <dt [b]role="tab"[/b]><a href="">Tab 2</a></dt>
    <dd [b]role="tabpanel"[/b]>Content 2</dd>
    <dt [b]role="tab"[/b]><a href="">Tab 3</a></dt>
    <dd  [b]role="tabpanel"[/b]>Content 3</dd>
</dl>


Sauf que je me retrouve devant un problème avec les attributs "role". En effet le role tabpanel ne peut pas être un enfant du role tablist Smiley biggol et le role tab à besoin du role tablist en parent.

Ma question est donc la suivante... Existe-t'il une solution à mon case tête?

Merci d'avance de vos réponses
Modifié par semantic (16 Apr 2015 - 14:50)
Et bien puisqu'on parle d'une navigation par onglets... De quel manière ces onglets sont-ils actionnés ? Via PHP ? Via Javascript ? Je demande cela car je me demande si l'on ne prend pas le problème à l'envers.

En effet, si c'est la solution javascript qui est retenue (90% de chance) la question ne devrait même pas se poser en ces termes : un objet dédié au fonctionnement du javascript - en l'occurence ici des onglets - se devrait d'être créé via javascript, point. Donc, sans javascript, le flux devrait avoir un profil du genre itemTitre/itemContenu, avec une sémantique on ne peut plus classique : titre, h2, dt, etc. pour ce qui sera les onglets une fois javascript appliqué, puis div, p, dd ou tout autre élément qui sera approprié au contenu :
<h2>Un onglet</h2>
<p>Un contenu</p>
<h2>Un onglet</h2>
<p>Un contenu</p>
<h2>Un onglet</h2>
<p>Un contenu</p>


Un exemple en ligne une fois le javascript apposé : Tabs
Modifié par Olivier C (16 Apr 2015 - 22:25)
Notons bien qu'une telle approche est aux antipodes de frameworks célèbres, tels que jQueryUI pour ne pas le citer. Celui-ci ne se privera pas d'ajouter tout un tas de divs ou de spans pour faire fonctionner un accordéon ou un menu onglet, quand il n'exige pas purement et simplement l'ajout d'IDs dans le code (Bootstrap aussi)...
Modifié par Olivier C (16 Apr 2015 - 22:25)
Merci pour la réponse.
Le rendu html est généré coté serveur. J'ai un ensemble de classes php qui gèrent la vue.

Dans le cas de ma navigation par onglets j'ai deux grosses classes.
Une qui représente un onglet et une qui récupère les onglets et génère le rendu. Le rendu n'est pas fixe et je peux lui donner la forme que je veux.
Dans mon cas j'utilise une liste de définitions. Un titre (dt), un contenu lié (dd)

Coté navigateur, c'est à javascript de gérer les événements. Il gère les cliques, affiche ou masque le contenu.
Il ajoute rien sauf une classe "active" sur l'onglet actif et une classe "hidden" sur le contenu masqué. Bref du javascript basique et très très simple

Le css lui adapte le rendu en fonction de l'appareil (smartphone, pc, tablette). Là aussi du basique (j'utilise sass pour me simplifier un peu la vie mais rien de plus)

L'ensemble fonctionne bien.
Ma question est plus d'ordre sémantique. La doc w3c dit qu'un role tablist n'a que tab ou presentation comment enfants. Donc comment placer mon role tabpanel en gardant les listes de définitions pour structurer ma navigation par onglets Smiley sweatdrop ...

Au pire je peux revenir à UL LI DIV maix ça me plaît moins Smiley lol
Modifié par semantic (17 Apr 2015 - 03:14)
IL n'y a pas de solution qui soit à la fois conforme à <dl> et aux rôles ARIA dans ton cas. Tu as bien remarqué toi-même que tu es dans une situation contradictoire. ON distingue la liste des onglets de la zone de contenu, et tu es obligé de faire ainsi.

Si plusieurs zones peuvent être ouvertes simultanément, ou même seulement si tu es convaincu que <dl> est la bonne organisation, pour moi ce que tu présentes ici est un menu accordéon et non un système d'onglets (1). . Dans ce cas, il faut plutôt utiliser role=button, aria-expanded et aria-controls. Par ailleurs, dans cette optique, tu as tout intérêt à utiliser des titres de niveau et des <p> (ou des <div>) plutôt que des <dl> à mon avis. Ca a des chances de faciliter la navigation pour les aides techniques qui ne supportent pas complètement ARIA et même pour celles qui le supportent bien.

Exemple typique :

<h3><span role="button" aria-expanded="true" aria-controls="menu1">Afficher/cacher menu 1</span></h3>
<div id="menu1">
...
</div>


Note sur ce code, ne pas tomber dans le piège <h3 role="button"> car ça inhibe le rôle implicite du h3 (role=heading) et du coup on perd le bonus potentiel en facilité de navigation.

de façon générale, il faut faire très attention avec <dl>. Bien souvent, lorsque le contenu des <dd> est important, mieux vaut utiliser des titres de niveau et des <p>. D'après moi, c'est une erreur courante à classer dans la catégorie syndrome de sursémantisation.

(1) Pour moi, le critère qui distingue un système d'onglet d'un menu accordéon, et ce n'est pas un hasard si le W3C a défini les rôles ARIA ainsi, c'est que dans un système d'onglet, on a le contenu dans l'ordre:
Bouton de l'onglet 1 > Bouton de l'onglet 2 > Bouton de l'onglet 3 > ... > Buton de l'onglet N > Contenu de l'onglet 1 > Contenu de l'onglet 2 > ... > Contenu de l'onglet N
Alors que pour un menu accordéon on a:
Bouton du menu 1 > Contenu du menu 1 > Bouton du menu 2 > Contenu du menu 2 > ... > Bouton du menu N > Contenu du menu N

Donc, du coup, ta structure en <dl> présente les choses clairement davantage comme le second plutôt que le premier. LE fait qu'un seul élément ne puisse être ouvert à la fois ou non n'est pas suffisant pour faire la distinction.
Modifié par QuentinC (17 Apr 2015 - 05:53)
Je comprends mieux. Oui tu as raison. Je pense que si la w3c fait la distinction c'est pour une raison précise.
Je ne souhaite pas faire un menu accordéon mais bien une navigation par onglets.

J'ai de nouveau fait la séparation entre la liste et le contenu. J'ai lié les deux avec aria-controls et aria-labelledby.
Le code ressemble maintenant à ça.


<h1>Onglets</h1>
<ul role="tablist">
    <li role="presentation">
        <a href="#tabs-1" aria-controls="tabs-1" role="tab" aria-selected="true" id="tabs-1-tab">Onglet 1</a>
    </li>
    <li role="presentation">
        <a href="#tabs-2" aria-controls="tabs-2" role="tab" aria-selected="false"  id="tabs-2-tab">Onglet 2</a>
    </li>
    <li role="presentation">
        <a href="#tabs-3" aria-controls="tabs-3" role="tab" aria-selected="false"  id="tabs-3-tab">Onglet 3</a>
    </li>
</ul>
<div id="tabs-1" role="tabpanel" aria-hidden="false" aria-expanded="true" aria-labelledby="tabs-1-tab">
    <h2>Onglet 1</h2>
    <p>Contenu 1</p>
</div>
<div id="tabs-2" role="tabpanel" aria-hidden="true" aria-expanded="false" aria-labelledby="tabs-2-tab">
    <h2>Onglet 2</h2>
    <p>Contenu 2</p>
</div>
<div id="tabs-3" role="tabpanel" aria-hidden="true" aria-expanded="false" aria-labelledby="tabs-3-tab">
    <h2>Onglet 3</h2>
    <p>Contenu 3</p>
</div>


Je pense que c'est correct. J'ai bien ma relation entre les deux.
En tout cas merci de ton aide.
Modifié par semantic (17 Apr 2015 - 14:38)