From 39f2114f9797eb51994966c6bb8ff1814c9a4da8 Mon Sep 17 00:00:00 2001 From: Florian Merz Date: Thu, 11 Feb 2021 12:36:08 +0100 Subject: unslug fr: move --- .../index.html" | 118 -- .../html/cat\303\251gories_de_contenu/index.html" | 175 -- .../web/guide/html/content_categories/index.html | 175 ++ .../fr/web/guide/html/editable_content/index.html | 36 + .../advanced_styling_for_html_forms/index.html | 469 ----- .../apparence_des_formulaires_html/index.html | 391 ---- .../example_3/index.html" | 247 --- .../example_4/index.html" | 297 --- .../example_5/index.html" | 290 --- .../exemple_1/index.html" | 420 ----- .../exemple_2/index.html" | 215 --- .../index.html" | 837 -------- .../exemple/index.html | 166 -- .../index.html | 310 --- .../index.html" | 371 ---- .../html_forms_in_legacy_browsers/index.html | 220 --- files/fr/web/guide/html/formulaires/index.html | 81 - .../les_blocs_de_formulaires_natifs/index.html | 683 ------- .../mon_premier_formulaire_html/exemple/index.html | 104 - .../mon_premier_formulaire_html/index.html | 281 --- .../index.html | 1991 -------------------- .../sending_forms_through_javascript/index.html | 440 ----- .../validation_donnees_formulaire/index.html | 874 --------- .../html/html5/introduction_to_html5/index.html | 40 + .../index.html" | 580 ------ files/fr/web/guide/html/liens_email/index.html | 64 - .../using_html_sections_and_outlines/index.html | 375 ++++ 27 files changed, 626 insertions(+), 9624 deletions(-) delete mode 100644 "files/fr/web/guide/html/astuces_de_cr\303\251ation_de_pages_html_\303\240_affichage_rapide/index.html" delete mode 100644 "files/fr/web/guide/html/cat\303\251gories_de_contenu/index.html" create mode 100644 files/fr/web/guide/html/content_categories/index.html create mode 100644 files/fr/web/guide/html/editable_content/index.html delete mode 100644 files/fr/web/guide/html/formulaires/advanced_styling_for_html_forms/index.html delete mode 100644 files/fr/web/guide/html/formulaires/apparence_des_formulaires_html/index.html delete mode 100644 "files/fr/web/guide/html/formulaires/comment_construire_des_widgets_de_formulaires_personnalis\303\251s/example_3/index.html" delete mode 100644 "files/fr/web/guide/html/formulaires/comment_construire_des_widgets_de_formulaires_personnalis\303\251s/example_4/index.html" delete mode 100644 "files/fr/web/guide/html/formulaires/comment_construire_des_widgets_de_formulaires_personnalis\303\251s/example_5/index.html" delete mode 100644 "files/fr/web/guide/html/formulaires/comment_construire_des_widgets_de_formulaires_personnalis\303\251s/exemple_1/index.html" delete mode 100644 "files/fr/web/guide/html/formulaires/comment_construire_des_widgets_de_formulaires_personnalis\303\251s/exemple_2/index.html" delete mode 100644 "files/fr/web/guide/html/formulaires/comment_construire_des_widgets_de_formulaires_personnalis\303\251s/index.html" delete mode 100644 files/fr/web/guide/html/formulaires/comment_structurer_un_formulaire_html/exemple/index.html delete mode 100644 files/fr/web/guide/html/formulaires/comment_structurer_un_formulaire_html/index.html delete mode 100644 "files/fr/web/guide/html/formulaires/envoyer_et_extraire_les_donn\303\251es_des_formulaires/index.html" delete mode 100644 files/fr/web/guide/html/formulaires/html_forms_in_legacy_browsers/index.html delete mode 100644 files/fr/web/guide/html/formulaires/index.html delete mode 100644 files/fr/web/guide/html/formulaires/les_blocs_de_formulaires_natifs/index.html delete mode 100644 files/fr/web/guide/html/formulaires/mon_premier_formulaire_html/exemple/index.html delete mode 100644 files/fr/web/guide/html/formulaires/mon_premier_formulaire_html/index.html delete mode 100644 files/fr/web/guide/html/formulaires/property_compatibility_table_for_form_widgets/index.html delete mode 100644 files/fr/web/guide/html/formulaires/sending_forms_through_javascript/index.html delete mode 100644 files/fr/web/guide/html/formulaires/validation_donnees_formulaire/index.html create mode 100644 files/fr/web/guide/html/html5/introduction_to_html5/index.html delete mode 100644 "files/fr/web/guide/html/html5/liste_des_\303\251l\303\251ments_html5/index.html" delete mode 100644 files/fr/web/guide/html/liens_email/index.html create mode 100644 files/fr/web/guide/html/using_html_sections_and_outlines/index.html (limited to 'files/fr/web/guide/html') diff --git "a/files/fr/web/guide/html/astuces_de_cr\303\251ation_de_pages_html_\303\240_affichage_rapide/index.html" "b/files/fr/web/guide/html/astuces_de_cr\303\251ation_de_pages_html_\303\240_affichage_rapide/index.html" deleted file mode 100644 index 58e21b4603..0000000000 --- "a/files/fr/web/guide/html/astuces_de_cr\303\251ation_de_pages_html_\303\240_affichage_rapide/index.html" +++ /dev/null @@ -1,118 +0,0 @@ ---- -title: Astuces de création de pages HTML à affichage rapide -slug: Web/Guide/HTML/Astuces_de_création_de_pages_HTML_à_affichage_rapide -tags: - - HTML - - Performance -translation_of: Learn/HTML/Howto/Author_fast-loading_HTML_pages ---- -

C'est connu, les internautes sont de grands impatients, ils veulent des résultats immédiats, avec des gros titres et des réponses courtes et efficaces. 
- Une page web optimisé prévoit non seulement un site plus réactif, mais aussi de réduire la charge sur vos serveurs Web et votre connexion Internet. Cela peut être crucial pour les gros sites ou des sites qui ont un pic de trafic dans des circonstances exceptionnelles (telles que les Unes des journaux fracassantes). De plus, Google en tient compte pour son classement.

- -

Réduire le poids de la page

- -

Le poids de la page est de loin le facteur le plus important dans les performances de chargement de votre page. Pour les améliorer, on peut procéder de diverses manières:

- - - -

Téléchargez le html d'abords, puis le CSS et le JavaScript nécessaires à son affichage, de sorte que l'utilisateur obtienne rapidement une réponse apparente au cours du chargement de la paget. Ce contenu est généralement du texte, et peuvent donc bénéficier de la compression de texte dans le modem, fournissant ainsi une réponse encore plus rapide à l'utilisateur.

- -

Réduisez le nombre de fichiers

- -

Réduire le nombre de fichiers référencés dans une page web diminue le nombre de connexions HTTP nécessaire pour télécharger une page.

- - - -

Les videos sont diffusées progressivement depuis le serveur, elles ne ralentisseent donc pas le chargement de votre page.

- -

Réduire les domaines des recherches

- -

Étant donné que chaque requete DNS demande du temps, le temps de chargement de la page va augmenter avec l'augmentation du nombre de domaines séparés figurant dans le lien CSS, JavaScript et image (src). Vous devez toujours prendre soin de n'utiliser que le nombre minimum nécessaire de différents domaines dans vos pages.

- -

Réutiliser le contenu du cache

- -

Assurez-vous que tout contenu qui peut être mis en cache, est mis en cache, et avec un temps d'expiration appropriée.
- En particulier, attention à l'en-tête "Last-Modified". Elle permet la mise en cache de la page; grâce à cette en-tête, l'information est transmise au navigateur (ou "user agent") sur le fichier qu'il veut charger, comme lors de sa dernière modification. La plupart des serveurs web ajoute automatiquement l'en-tête "Last-Modified" aux pages statiques (par exemple. html,. css), basé sur la date de la dernière modification stockées dans le système de fichiers. Avec des pages dynamiques (p. ex. Php,. Aspx), ceci, bien sûr, ne peut pas être fait, et l'en-tête n'est pas envoyé.
- En particulier pour les pages qui sont générées dynamiquement, une petite recherche sur ce sujet est bénéfique. Il peut être quelque peu complexe, mais il permettra d'économiser beaucoup de demandes de page sur des pages qui ne devraient normalement pas être mis en cache.
-
- Plus d'informations:
-
-    1. HTTP Conditional Get for RSS Hackers
-    2. HTTP 304: Not Modified
-    3. On HTTP Last-Modified and ETag

- -

Réduire le nombre de scripts en ligne

- -

Les scripts intégrés peut être coûteux pour le chargement de la page, puisque l'analyseur (ou parser) doit supposer qu'un script intégré pourrait modifier la structure de la page quand le "parsing" est en cours. Il est donc préférable, en général, de réduire l'utilisation des scripts intégrés et l'utilisation de document.write(), en particulier au contenu de sortie. Ces manipulations peuvent améliorer chargement globale de la page. Utilisez des méthodes modernes de W3C-DOM pour manipuler le contenu de la page pour les navigateurs modernes, plutôt que des approches plus fondées sur document.write ().

- -

Utilisez le CSS moderne et des balises valides

- -

L'utilisation de CSS modernes réduit la quantité de balisage, et peut réduire la nécessité de "spacer" les images, en termes de disposition, et peut très souvent remplacer des images de texte stylisé - qui "coutent" beaucoup plus que l'équivalent texte-et-CSS.
- Utiliser des balises valides a d'autres avantages. Tout d'abord, les navigateurs n'ont pas besoin d'effectuer de corrections d'erreurs lors de l'analyse du code HTML.
- En outre, la validité du balisage permet la libre utilisation d'autres outils qui peuvent pré-traiter vos pages web. Par exemple, HTML Tidy  peut supprimer des espaces blancs et des balises facultatives, mais il refusera de s'exécuter sur une page avec des erreurs de balisage graves.

- -

Segmentez votre contenu

- -

Remplacer la mise en page basé sur des <table> par des blocs <div>, plutôt que des <table> très imbriquée comme dans l'exemple suivant:

- -
<TABLE>
-  <TABLE>
-    <TABLE>
-          ...
-    </TABLE>
-  </TABLE>
-</TABLE>
-
-
- -

Préferez des <table> non-imbriquées ou <div> comme dans l'exemple suivant:

- -
> TABLE <TABLE> ...</
-> TABLE <TABLE> ...</
-> TABLE <TABLE> ...</
- -

Préciser la taille des images et des tableaux

- -

Si le navigateur peut immédiatement déterminer la hauteur et/ou la largeur de vos images et tableaux, il sera capable d'afficher une page web sans avoir à refondre le contenu. Cela n'augmente pas seulement la vitesse d'affichage de la page, mais aussi à empêcher les changements gênants dans la disposition d'une page lors du chargement. Pour cette raison, la hauteur et la largeur doit être spécifié pour les images, chaque fois que possible.
- Les tableaux doivent utiliser le sélecteur CSS selector:property combination:

- -
  table-layout: fixed;
-
-
- -

et doit spécifier la largeur des colonnes en utilisant le COL et les balises html COLGROUP.

- -

Choisissez les versions des navigateur ciblés

- -


- Pour atteindre les plus grandes améliorations dans la conception de la page, assurez-vous que des exigences raisonnables de l'agent utilisateur (user-agent) soit définies pour les projets. Cela ne nécessite pas que votre contenu apparaisse parfaitement sur tous les navigateurs, et surtout pas dans les navigateurs d'une version anterieure.
-
- Idéalement, vous devriez vous concentrez sur l'examen des navigateurs modernes qui prennent en charge des normes pertinentes. Il peut s'agir de: Firefox 5, Internet Explorer 9 sur Windows, Opera 11 sous Windows et Safari 5 sur Mac OS X.
-
- Notez, cependant, que beaucoup de conseils énumérés dans cette page sont des techniques de bon sens qui s'applique à tous, et peuvent être appliquées à n'importe quelle page web, indépendamment des exigences relatives des navigateurs.

- -

Liens connexes

- -


-     * Optimisez vos pages avec Yslow
-     * Livre: "Speed Up Your Site" par Andy King
-     * Site Optimization Tutorial (WebMonkey) (en anglais) 
-     * Best Practices for Speeding Up Your Web Site (en anglais) 

- -

 

- -

Document d'information d'origine
-
-     * https://developer.mozilla.org/en/Tips_for_Authoring_Fast-loading_HTML_Pages

diff --git "a/files/fr/web/guide/html/cat\303\251gories_de_contenu/index.html" "b/files/fr/web/guide/html/cat\303\251gories_de_contenu/index.html" deleted file mode 100644 index 35a8ed9779..0000000000 --- "a/files/fr/web/guide/html/cat\303\251gories_de_contenu/index.html" +++ /dev/null @@ -1,175 +0,0 @@ ---- -title: Catégories de contenu -slug: Web/Guide/HTML/Catégories_de_contenu -tags: - - Avancé - - Contenus - - Guide - - HTML -translation_of: Web/Guide/HTML/Content_categories ---- -

Chaque élément HTML est membre d'un certain nombre de catégories de contenu qui regroupent des éléments partageant un ensemble de caractéristiques. Ceci est un regroupement lâche, en ce sens qu'il ne crée pas réellement de relation entre les éléments de ces types, mais il aide à définir et à décrire leur comportement et les règles associées qu'ils doivent respecter, en particulier lorsque l'on entre dans leurs détails complexes. Il est également possible que les éléments ne soient membres d'aucune de ces catégories.

- -

Il y a trois types différents de catégories de contenu :

- - - -
-

Note : un discours plus détaillé sur ces catégories de contenu et de leurs fonctionnalités comparatives dépasse le cadre de cet article ; pour en savoir plus, vous pouvez lire les parties correspondantes de la spécification HTML (en).

-
- -
Content_categories_venn.png
- -

Principales catégories de contenu

- -

Contenu de méta-données

- -

Les éléments appartenant à cette catégorie modifient la présentation ou le comportement du reste du document, insèrent des liens vers d'autres documents ou comportent des informations sur la structure même des données.

- -

Les éléments appartenant à cette catégories sont : {{HTMLElement("base")}}, {{HTMLElement("command")}}{{ Obsolete_inline()}} , {{HTMLElement("link")}}, {{HTMLElement("meta")}}, {{HTMLElement("noscript")}}, {{HTMLElement("script")}}, {{HTMLElement("style")}} et {{HTMLElement("title")}}.

- -

Contenu de flux

- -

Les éléments appartenant à la catégorie de contenu de flux contiennent généralement du texte ou du contenu intégré. Ces éléments sont : {{HTMLElement("a")}}, {{HTMLElement("abbr")}}, {{HTMLElement("address")}}, {{HTMLElement("article")}}, {{HTMLElement("aside")}}, {{HTMLElement("audio")}}, {{HTMLElement("b")}},{{HTMLElement("bdo")}}, {{HTMLElement("bdi")}}, {{HTMLElement("blockquote")}}, {{HTMLElement("br")}}, {{HTMLElement("button")}}, {{HTMLElement("canvas")}}, {{HTMLElement("cite")}}, {{HTMLElement("code")}}, {{ Obsolete_inline() }}{{HTMLElement("command")}}, {{HTMLElement("data")}}, {{HTMLElement("datalist")}}, {{HTMLElement("del")}}, {{HTMLElement("details")}}, {{HTMLElement("dfn")}}, {{HTMLElement("div")}}, {{HTMLElement("dl")}}, {{HTMLElement("em")}}, {{HTMLElement("embed")}}, {{HTMLElement("fieldset")}}, {{HTMLElement("figure")}}, {{HTMLElement("footer")}}, {{HTMLElement("form")}}, {{HTMLElement("h1")}}, {{HTMLElement("h2")}}, {{HTMLElement("h3")}}, {{HTMLElement("h4")}}, {{HTMLElement("h5")}}, {{HTMLElement("h6")}}, {{HTMLElement("header")}}, {{HTMLElement("hgroup")}}, {{HTMLElement("hr")}}, {{HTMLElement("i")}}, {{HTMLElement("iframe")}}, {{HTMLElement("img")}}, {{HTMLElement("input")}}, {{HTMLElement("ins")}}, {{HTMLElement("kbd")}}, {{HTMLElement("keygen")}}{{deprecated_inline()}}, {{HTMLElement("label")}}, {{HTMLElement("main")}}, {{HTMLElement("map")}}, {{HTMLElement("mark")}}, {{MathMLElement("math")}}, {{HTMLElement("menu")}}, {{HTMLElement("meter")}}, {{HTMLElement("nav")}}, {{HTMLElement("noscript")}}, {{HTMLElement("object")}}, {{HTMLElement("ol")}}, {{HTMLElement("output")}}, {{HTMLElement("p")}}, {{HTMLElement("picture")}}, {{HTMLElement("pre")}}, {{HTMLElement("progress")}}, {{HTMLElement("q")}}, {{HTMLElement("ruby")}}, {{HTMLElement("s")}}, {{HTMLElement("samp")}}, {{HTMLElement("script")}}, {{HTMLElement("section")}}, {{HTMLElement("select")}}, {{HTMLElement("small")}}, {{HTMLElement("span")}}, {{HTMLElement("strong")}}, {{HTMLElement("sub")}}, {{HTMLElement("sup")}}, {{SVGElement("svg")}}, {{HTMLElement("table")}}, {{HTMLElement("template")}}, {{HTMLElement("textarea")}}, {{HTMLElement("time")}}, {{HTMLElement("ul")}}, {{HTMLElement("var")}}, {{HTMLElement("video")}}, {{HTMLElement("wbr")}} et le texte.

- -

Quelques autres éléments appartiennent à cette catégorie mais seulement sous certaines conditions :

- - - -

Contenu sectionnant

- -

Les éléments appartenant à cette catégorie sont ceux créant une nouvelle section dans le plan du document qui définit la portée des éléments {{HTMLElement("header")}}, des éléments {{HTMLElement("footer")}} et du contenu de titre.

- -

Les éléments appartenant à cette catégorie sont les éléments {{HTMLElement("article")}}, {{HTMLElement("aside")}}, {{HTMLElement("nav")}} et {{HTMLElement("section")}}. 

- -
-

Note : Il ne faut pas confondre ce modèle de contenu avec la catégorie de racine de sectionnement qui isole un contenu par rapport à la structure (ou plan) principale.

-
- -

Contenu de titre

- -

Le contenu de titre définit le titre d'une section, qu'elle soit marquée par un contenu sectionnant de manière explicite ou qu'elle soit définie de manière implicite par le contenu de titre lui-même.

- -

Les éléments appartenant à cette catégorie sont {{HTMLElement("h1")}}, {{HTMLElement("h2")}}, {{HTMLElement("h3")}}, {{HTMLElement("h4")}}, {{HTMLElement("h5")}}, {{HTMLElement("h6")}} et {{HTMLElement("hgroup")}}.

- -
-

Note : Bien qu'il soit probable qu'un élément {{HTMLElement("header")}} comporte du contenu de titre, il n'est pas lui-même un contenu de titre.

-
- -
-

Note : {{HTMLElement("hgroup")}} est supprimé du document recommandé par W3C.

-
- -

Contenu phrasé

- -

Le contenu phrasé définit le texte et le balisage qu'il contient. Des séquences de contenu phrasé constituent des paragraphes.

- -

Les éléments appartenant à cette catégorie sont  {{HTMLElement("abbr")}}, {{HTMLElement("audio")}}, {{HTMLElement("b")}}, {{HTMLElement("bdo")}}, {{HTMLElement("br")}}, {{HTMLElement("button")}}, {{HTMLElement("canvas")}}, {{HTMLElement("cite")}}, {{HTMLElement("code")}}, {{ Obsolete_inline() }}{{HTMLElement("command")}}, {{HTMLElement("data")}}, {{HTMLElement("datalist")}}, {{HTMLElement("dfn")}}, {{HTMLElement("em")}}, {{HTMLElement("embed")}}, {{HTMLElement("i")}}, {{HTMLElement("iframe")}}, {{HTMLElement("img")}}, {{HTMLElement("input")}}, {{HTMLElement("kbd")}}, {{HTMLElement("keygen")}}{{deprecated_inline()}}, {{HTMLElement("label")}}, {{HTMLElement("mark")}}, {{MathMLElement("math")}}, {{HTMLElement("meter")}}, {{HTMLElement("noscript")}}, {{HTMLElement("object")}}, {{HTMLElement("output")}}, {{HTMLElement("picture")}}, {{HTMLElement("progress")}}, {{HTMLElement("q")}}, {{HTMLElement("ruby")}}, {{HTMLElement("samp")}}, {{HTMLElement("script")}}, {{HTMLElement("select")}}, {{HTMLElement("small")}}, {{HTMLElement("span")}}, {{HTMLElement("strong")}}, {{HTMLElement("sub")}}, {{HTMLElement("sup")}}, {{SVGElement("svg")}}, {{HTMLElement("textarea")}}, {{HTMLElement("time")}}, {{HTMLElement("var")}}, {{HTMLElement("video")}}, {{HTMLElement("wbr")}} et du texte brut (n'étant pas une simple suite de blancs).

- -

Quelques autres éléments appartiennent à cette catégorie mais seulement selon certaines conditions :

- - - -

Contenu intégré

- -

Le contenu intégré importe une autre ressource ou intègre du contenu provenant d'un autre langage de balisage ou d'un autre espace de noms dans le document. Les éléments appartenant à cette catégorie sont : {{HTMLElement("audio")}}, {{HTMLElement("canvas")}}, {{HTMLElement("embed")}}, {{HTMLElement("iframe")}}, {{HTMLElement("img")}}, {{MathMLElement("math")}}, {{HTMLElement("object")}}, {{HTMLElement("svg")}}, {{HTMLElement("video")}}.

- -

Contenu interactif

- -

Le contenu interactif regroupe des éléments spécialement conçus pour une interaction avec l'utilisateur. Les éléments appartenant à cette catégories sont : {{HTMLElement("a")}}, {{HTMLElement("button")}}, {{HTMLElement("details")}}, {{HTMLElement("embed")}}, {{HTMLElement("iframe")}}, {{HTMLElement("keygen")}}{{deprecated_inline()}} , {{HTMLElement("label")}}, {{HTMLElement("select")}}, et {{HTMLElement("textarea")}}.

- -

Quelques éléments appartiennent à cette catégorie seulement sous certaines conditions :

- - - -

Contenu tangible

- -

Un contenu peut être dit tangible lorsqu'il n'est ni vide ni caché. Les éléments dont le modèle de contenu est de flux ou phrasé devraient toujours avoir au moins un noeud dont le contenu est tangible.

- -

Contenu associé aux formulaires

- -

Le contenu associé aux formulaires contient les éléments possédés par un formulaire, exposé avec un attribut form. Être possédé par un formulaire signifie être descendant d'un élément  {{HTMLElement("form")}} ou de l'élément dont l'identifiant est référencé par la valeur de l'attribut form.

- -

Cette catégorie contient les éléments :

- - - -

 Cette catégorie peut être subdivisée en plusieurs sous-catégories.

- -
-
listed (éléments listés)
-
Les éléments étant listés sont les ensembles IDL form.elements et fieldset.elements. Ce sont : {{HTMLElement("button")}}, {{HTMLElement("fieldset")}}, {{HTMLElement("input")}}, {{HTMLElement("keygen")}}{{deprecated_inline()}} , {{HTMLElement("object")}}, {{HTMLElement("output")}}, {{HTMLElement("select")}}, et {{HTMLElement("textarea")}}.
-
labelable (éléments étiquetables)
-
Les éléments pouvant être associés avec des éléments  {{HTMLElement("label")}}. Ce sont : {{HTMLElement("button")}}, {{HTMLElement("input")}}, {{HTMLElement("keygen")}}{{deprecated_inline()}} , {{HTMLElement("meter")}}, {{HTMLElement("output")}}, {{HTMLElement("progress")}}, {{HTMLElement("select")}} et {{HTMLElement("textarea")}}.
-
submittable (éléments participants à l'envoi du formulaire)
-
Les éléments pouvant être utilisés pour construire les données du formulaires quand celui-ci est envoyé. Ce sont : {{HTMLElement("button")}}, {{HTMLElement("input")}}, {{HTMLElement("keygen")}}{{deprecated_inline()}} , {{HTMLElement("object")}}, {{HTMLElement("select")}} et {{HTMLElement("textarea")}}.
-
resettable (éléments de ré-initialisation)
-
Éléments pouvant être impactés lorsqu'un formulaire est ré-initialisé. Ce sont : {{HTMLElement("input")}}, {{HTMLElement("keygen")}}{{deprecated_inline()}}, {{HTMLElement("output")}},{{HTMLElement("select")}} et {{HTMLElement("textarea")}}.
-
- -

Catégories secondaires

- -

Il existe des classifications secondaires d'éléments qu'il peut être utile de connaître également.

- -

Éléments supports de script

- -

Les éléments supports de script sont des éléments qui ne contribuent pas directement à la sortie rendue d'un document. Au lieu de cela, ils servent à prendre en charge les scripts, soit en contenant ou en spécifiant le code de script directement, soit en spécifiant les données qui seront utilisées par les scripts. Ce sont :

- - - -

Modèle de contenu transparent

- -

Si l'élément possède un modèle de contenu transparent, son contenu doit alors être structuré comme du HTML5 valide, et ce, même si l'élément transparent a été enlevé et remplacé par ses éléments fils.

- -

Les éléments {{HTMLElement("del")}} et {{HTMLELement("ins")}} sont des exemples d'éléments transparents.

- -
<p>Bonjour <del><em>tout</em></del> <ins>le monde</ins>.</p>
-
- -

Si ces éléments étaient retirés, ce fragment de code HTML serait toujours du HTML valide.

- -
<p>Bonjour <em>tout</em> le monde.</p>
-
- -

Autres modèles de contenu

- -

Racine de sectionnement.

diff --git a/files/fr/web/guide/html/content_categories/index.html b/files/fr/web/guide/html/content_categories/index.html new file mode 100644 index 0000000000..35a8ed9779 --- /dev/null +++ b/files/fr/web/guide/html/content_categories/index.html @@ -0,0 +1,175 @@ +--- +title: Catégories de contenu +slug: Web/Guide/HTML/Catégories_de_contenu +tags: + - Avancé + - Contenus + - Guide + - HTML +translation_of: Web/Guide/HTML/Content_categories +--- +

Chaque élément HTML est membre d'un certain nombre de catégories de contenu qui regroupent des éléments partageant un ensemble de caractéristiques. Ceci est un regroupement lâche, en ce sens qu'il ne crée pas réellement de relation entre les éléments de ces types, mais il aide à définir et à décrire leur comportement et les règles associées qu'ils doivent respecter, en particulier lorsque l'on entre dans leurs détails complexes. Il est également possible que les éléments ne soient membres d'aucune de ces catégories.

+ +

Il y a trois types différents de catégories de contenu :

+ + + +
+

Note : un discours plus détaillé sur ces catégories de contenu et de leurs fonctionnalités comparatives dépasse le cadre de cet article ; pour en savoir plus, vous pouvez lire les parties correspondantes de la spécification HTML (en).

+
+ +
Content_categories_venn.png
+ +

Principales catégories de contenu

+ +

Contenu de méta-données

+ +

Les éléments appartenant à cette catégorie modifient la présentation ou le comportement du reste du document, insèrent des liens vers d'autres documents ou comportent des informations sur la structure même des données.

+ +

Les éléments appartenant à cette catégories sont : {{HTMLElement("base")}}, {{HTMLElement("command")}}{{ Obsolete_inline()}} , {{HTMLElement("link")}}, {{HTMLElement("meta")}}, {{HTMLElement("noscript")}}, {{HTMLElement("script")}}, {{HTMLElement("style")}} et {{HTMLElement("title")}}.

+ +

Contenu de flux

+ +

Les éléments appartenant à la catégorie de contenu de flux contiennent généralement du texte ou du contenu intégré. Ces éléments sont : {{HTMLElement("a")}}, {{HTMLElement("abbr")}}, {{HTMLElement("address")}}, {{HTMLElement("article")}}, {{HTMLElement("aside")}}, {{HTMLElement("audio")}}, {{HTMLElement("b")}},{{HTMLElement("bdo")}}, {{HTMLElement("bdi")}}, {{HTMLElement("blockquote")}}, {{HTMLElement("br")}}, {{HTMLElement("button")}}, {{HTMLElement("canvas")}}, {{HTMLElement("cite")}}, {{HTMLElement("code")}}, {{ Obsolete_inline() }}{{HTMLElement("command")}}, {{HTMLElement("data")}}, {{HTMLElement("datalist")}}, {{HTMLElement("del")}}, {{HTMLElement("details")}}, {{HTMLElement("dfn")}}, {{HTMLElement("div")}}, {{HTMLElement("dl")}}, {{HTMLElement("em")}}, {{HTMLElement("embed")}}, {{HTMLElement("fieldset")}}, {{HTMLElement("figure")}}, {{HTMLElement("footer")}}, {{HTMLElement("form")}}, {{HTMLElement("h1")}}, {{HTMLElement("h2")}}, {{HTMLElement("h3")}}, {{HTMLElement("h4")}}, {{HTMLElement("h5")}}, {{HTMLElement("h6")}}, {{HTMLElement("header")}}, {{HTMLElement("hgroup")}}, {{HTMLElement("hr")}}, {{HTMLElement("i")}}, {{HTMLElement("iframe")}}, {{HTMLElement("img")}}, {{HTMLElement("input")}}, {{HTMLElement("ins")}}, {{HTMLElement("kbd")}}, {{HTMLElement("keygen")}}{{deprecated_inline()}}, {{HTMLElement("label")}}, {{HTMLElement("main")}}, {{HTMLElement("map")}}, {{HTMLElement("mark")}}, {{MathMLElement("math")}}, {{HTMLElement("menu")}}, {{HTMLElement("meter")}}, {{HTMLElement("nav")}}, {{HTMLElement("noscript")}}, {{HTMLElement("object")}}, {{HTMLElement("ol")}}, {{HTMLElement("output")}}, {{HTMLElement("p")}}, {{HTMLElement("picture")}}, {{HTMLElement("pre")}}, {{HTMLElement("progress")}}, {{HTMLElement("q")}}, {{HTMLElement("ruby")}}, {{HTMLElement("s")}}, {{HTMLElement("samp")}}, {{HTMLElement("script")}}, {{HTMLElement("section")}}, {{HTMLElement("select")}}, {{HTMLElement("small")}}, {{HTMLElement("span")}}, {{HTMLElement("strong")}}, {{HTMLElement("sub")}}, {{HTMLElement("sup")}}, {{SVGElement("svg")}}, {{HTMLElement("table")}}, {{HTMLElement("template")}}, {{HTMLElement("textarea")}}, {{HTMLElement("time")}}, {{HTMLElement("ul")}}, {{HTMLElement("var")}}, {{HTMLElement("video")}}, {{HTMLElement("wbr")}} et le texte.

+ +

Quelques autres éléments appartiennent à cette catégorie mais seulement sous certaines conditions :

+ + + +

Contenu sectionnant

+ +

Les éléments appartenant à cette catégorie sont ceux créant une nouvelle section dans le plan du document qui définit la portée des éléments {{HTMLElement("header")}}, des éléments {{HTMLElement("footer")}} et du contenu de titre.

+ +

Les éléments appartenant à cette catégorie sont les éléments {{HTMLElement("article")}}, {{HTMLElement("aside")}}, {{HTMLElement("nav")}} et {{HTMLElement("section")}}. 

+ +
+

Note : Il ne faut pas confondre ce modèle de contenu avec la catégorie de racine de sectionnement qui isole un contenu par rapport à la structure (ou plan) principale.

+
+ +

Contenu de titre

+ +

Le contenu de titre définit le titre d'une section, qu'elle soit marquée par un contenu sectionnant de manière explicite ou qu'elle soit définie de manière implicite par le contenu de titre lui-même.

+ +

Les éléments appartenant à cette catégorie sont {{HTMLElement("h1")}}, {{HTMLElement("h2")}}, {{HTMLElement("h3")}}, {{HTMLElement("h4")}}, {{HTMLElement("h5")}}, {{HTMLElement("h6")}} et {{HTMLElement("hgroup")}}.

+ +
+

Note : Bien qu'il soit probable qu'un élément {{HTMLElement("header")}} comporte du contenu de titre, il n'est pas lui-même un contenu de titre.

+
+ +
+

Note : {{HTMLElement("hgroup")}} est supprimé du document recommandé par W3C.

+
+ +

Contenu phrasé

+ +

Le contenu phrasé définit le texte et le balisage qu'il contient. Des séquences de contenu phrasé constituent des paragraphes.

+ +

Les éléments appartenant à cette catégorie sont  {{HTMLElement("abbr")}}, {{HTMLElement("audio")}}, {{HTMLElement("b")}}, {{HTMLElement("bdo")}}, {{HTMLElement("br")}}, {{HTMLElement("button")}}, {{HTMLElement("canvas")}}, {{HTMLElement("cite")}}, {{HTMLElement("code")}}, {{ Obsolete_inline() }}{{HTMLElement("command")}}, {{HTMLElement("data")}}, {{HTMLElement("datalist")}}, {{HTMLElement("dfn")}}, {{HTMLElement("em")}}, {{HTMLElement("embed")}}, {{HTMLElement("i")}}, {{HTMLElement("iframe")}}, {{HTMLElement("img")}}, {{HTMLElement("input")}}, {{HTMLElement("kbd")}}, {{HTMLElement("keygen")}}{{deprecated_inline()}}, {{HTMLElement("label")}}, {{HTMLElement("mark")}}, {{MathMLElement("math")}}, {{HTMLElement("meter")}}, {{HTMLElement("noscript")}}, {{HTMLElement("object")}}, {{HTMLElement("output")}}, {{HTMLElement("picture")}}, {{HTMLElement("progress")}}, {{HTMLElement("q")}}, {{HTMLElement("ruby")}}, {{HTMLElement("samp")}}, {{HTMLElement("script")}}, {{HTMLElement("select")}}, {{HTMLElement("small")}}, {{HTMLElement("span")}}, {{HTMLElement("strong")}}, {{HTMLElement("sub")}}, {{HTMLElement("sup")}}, {{SVGElement("svg")}}, {{HTMLElement("textarea")}}, {{HTMLElement("time")}}, {{HTMLElement("var")}}, {{HTMLElement("video")}}, {{HTMLElement("wbr")}} et du texte brut (n'étant pas une simple suite de blancs).

+ +

Quelques autres éléments appartiennent à cette catégorie mais seulement selon certaines conditions :

+ + + +

Contenu intégré

+ +

Le contenu intégré importe une autre ressource ou intègre du contenu provenant d'un autre langage de balisage ou d'un autre espace de noms dans le document. Les éléments appartenant à cette catégorie sont : {{HTMLElement("audio")}}, {{HTMLElement("canvas")}}, {{HTMLElement("embed")}}, {{HTMLElement("iframe")}}, {{HTMLElement("img")}}, {{MathMLElement("math")}}, {{HTMLElement("object")}}, {{HTMLElement("svg")}}, {{HTMLElement("video")}}.

+ +

Contenu interactif

+ +

Le contenu interactif regroupe des éléments spécialement conçus pour une interaction avec l'utilisateur. Les éléments appartenant à cette catégories sont : {{HTMLElement("a")}}, {{HTMLElement("button")}}, {{HTMLElement("details")}}, {{HTMLElement("embed")}}, {{HTMLElement("iframe")}}, {{HTMLElement("keygen")}}{{deprecated_inline()}} , {{HTMLElement("label")}}, {{HTMLElement("select")}}, et {{HTMLElement("textarea")}}.

+ +

Quelques éléments appartiennent à cette catégorie seulement sous certaines conditions :

+ + + +

Contenu tangible

+ +

Un contenu peut être dit tangible lorsqu'il n'est ni vide ni caché. Les éléments dont le modèle de contenu est de flux ou phrasé devraient toujours avoir au moins un noeud dont le contenu est tangible.

+ +

Contenu associé aux formulaires

+ +

Le contenu associé aux formulaires contient les éléments possédés par un formulaire, exposé avec un attribut form. Être possédé par un formulaire signifie être descendant d'un élément  {{HTMLElement("form")}} ou de l'élément dont l'identifiant est référencé par la valeur de l'attribut form.

+ +

Cette catégorie contient les éléments :

+ + + +

 Cette catégorie peut être subdivisée en plusieurs sous-catégories.

+ +
+
listed (éléments listés)
+
Les éléments étant listés sont les ensembles IDL form.elements et fieldset.elements. Ce sont : {{HTMLElement("button")}}, {{HTMLElement("fieldset")}}, {{HTMLElement("input")}}, {{HTMLElement("keygen")}}{{deprecated_inline()}} , {{HTMLElement("object")}}, {{HTMLElement("output")}}, {{HTMLElement("select")}}, et {{HTMLElement("textarea")}}.
+
labelable (éléments étiquetables)
+
Les éléments pouvant être associés avec des éléments  {{HTMLElement("label")}}. Ce sont : {{HTMLElement("button")}}, {{HTMLElement("input")}}, {{HTMLElement("keygen")}}{{deprecated_inline()}} , {{HTMLElement("meter")}}, {{HTMLElement("output")}}, {{HTMLElement("progress")}}, {{HTMLElement("select")}} et {{HTMLElement("textarea")}}.
+
submittable (éléments participants à l'envoi du formulaire)
+
Les éléments pouvant être utilisés pour construire les données du formulaires quand celui-ci est envoyé. Ce sont : {{HTMLElement("button")}}, {{HTMLElement("input")}}, {{HTMLElement("keygen")}}{{deprecated_inline()}} , {{HTMLElement("object")}}, {{HTMLElement("select")}} et {{HTMLElement("textarea")}}.
+
resettable (éléments de ré-initialisation)
+
Éléments pouvant être impactés lorsqu'un formulaire est ré-initialisé. Ce sont : {{HTMLElement("input")}}, {{HTMLElement("keygen")}}{{deprecated_inline()}}, {{HTMLElement("output")}},{{HTMLElement("select")}} et {{HTMLElement("textarea")}}.
+
+ +

Catégories secondaires

+ +

Il existe des classifications secondaires d'éléments qu'il peut être utile de connaître également.

+ +

Éléments supports de script

+ +

Les éléments supports de script sont des éléments qui ne contribuent pas directement à la sortie rendue d'un document. Au lieu de cela, ils servent à prendre en charge les scripts, soit en contenant ou en spécifiant le code de script directement, soit en spécifiant les données qui seront utilisées par les scripts. Ce sont :

+ + + +

Modèle de contenu transparent

+ +

Si l'élément possède un modèle de contenu transparent, son contenu doit alors être structuré comme du HTML5 valide, et ce, même si l'élément transparent a été enlevé et remplacé par ses éléments fils.

+ +

Les éléments {{HTMLElement("del")}} et {{HTMLELement("ins")}} sont des exemples d'éléments transparents.

+ +
<p>Bonjour <del><em>tout</em></del> <ins>le monde</ins>.</p>
+
+ +

Si ces éléments étaient retirés, ce fragment de code HTML serait toujours du HTML valide.

+ +
<p>Bonjour <em>tout</em> le monde.</p>
+
+ +

Autres modèles de contenu

+ +

Racine de sectionnement.

diff --git a/files/fr/web/guide/html/editable_content/index.html b/files/fr/web/guide/html/editable_content/index.html new file mode 100644 index 0000000000..01e1691ed1 --- /dev/null +++ b/files/fr/web/guide/html/editable_content/index.html @@ -0,0 +1,36 @@ +--- +title: Contenu éditable +slug: Web/HTML/Contenu_editable +translation_of: Web/Guide/HTML/Editable_content +--- +

Introduction

+

Chaque élément du HTML5 peut être éditable. Cette fonctionnalité a été introduite longtemps auparavant mais a maintenant été standarisée avec WHATWG (voir la spécification HTML actuelle). Avec des gestionnaires d'événements JavaScript, vous pouvez transformer votre page Web en un éditeur de texte, complet et rapide.

+

Compatibilité

+

Le contenu éditable est entièrement compatible avec les navigateurs actuels :

+ +

Ce n'est pas encore supporté par Opera Mini et Opera Mobile.

+

Comment ça marche ?

+

Fixez l'attribut contenteditable à true dans votre élément HTML. Ça peut être fait dans quasiment tous les éléments HTML.

+

Exemples

+

Un exemple simple :

+
<!DOCTYPE html>
+<html>
+  <body>
+    <div contenteditable="true">
+      Ce texte peut être édité par l'utilisateur.
+    </div>
+  </body>
+</html> 
+

Vous pouvez observer un exemple concret intégrant JavaScript utilisant LocalStorage ici. Le code source est disponible ici.

+

Voir aussi

+

Comment interagir avec le contenu (style proche de l'ancienne API Internet Explorer) ou encore ici.

+
+ {{ languages({ "ja": "ja/HTML/Content_Editable", "zh-cn": "zh-cn/HTML/Content_Editable" }) }}
diff --git a/files/fr/web/guide/html/formulaires/advanced_styling_for_html_forms/index.html b/files/fr/web/guide/html/formulaires/advanced_styling_for_html_forms/index.html deleted file mode 100644 index 6d6a68bd4c..0000000000 --- a/files/fr/web/guide/html/formulaires/advanced_styling_for_html_forms/index.html +++ /dev/null @@ -1,469 +0,0 @@ ---- -title: Composition avancée des formulaires HTML -slug: Web/Guide/HTML/Formulaires/Advanced_styling_for_HTML_forms -tags: - - Avancé - - CSS - - Exemple - - Formulaires - - Guide - - HTML - - Web -translation_of: Learn/Forms/Advanced_form_styling ---- -
{{LearnSidebar}}{{PreviousMenuNext("Web/Guide/HTML/Formulaires/Apparence_des_formulaires_HTML", "Web/Guide/HTML/Formulaires/Property_compatibility_table_for_form_widgets", "Web/Guide/HTML/Formulaires")}}
- -

Dans cet article, nous verrons comment utiliser les CSS avec les formulaires HTML pour modifier le style de certains widgets difficiles à personnaliser. Comme nous l'avons vu dans l'article précédent, les champs texte et les boutons sont parfaitement compatibles avec les CSS. Maintenant, nous allons approfondir la part sombre de la composition stylistique des formulaires HTML.

- -

Avant d'aller plus loin, faisons un rappel pour deux types de widgets de formulaires :

- -
-
la brute
-
Éléments, dont le style n'est que difficilement modifiable, demandant des astuces complexes, nécessitant parfois de faire appel à une connaissance avancée des CSS3.
-
le truand
-
Oubliez l'emploi des CSS pour modifier le style de ces éléments. Au mieux, vous pourrez faire des petites choses, mais elle ne seront pas reproductibles sur d'autres navigateurs ; il ne sera jamais possible de prendre un contrôle total de leur apparence.
-
- -

Possibilités d'expression avec les CSS

- -

Le problème fondamental avec les widgets de formulaire, autres que champs de texte et boutons, est que dans de nombreux cas, le CSS ne possède pas assez d'expressions pour styliser correctement les widgets complexes.

- -

L'évolution récente du HTML et des CSS a étendu l'expressivité des CSS :

- - - -

Voilà un bon début, mais il y a deux problèmes. Primo, certains navigateurs ne mettent pas en œuvre des fonctionnalités au-delà de CSS 2.1. Secundo, ils ne sont tout simplement pas assez perfectionnés pour styliser des widgets complexes, comme les sélecteurs de date.

- -

Il y a quelques expérimentations par les fournisseurs de navigateurs pour étendre l'expressivité des CSS sur les formulaires ; dans certains cas, il est bon de savoir ce qui est disponible..

- -
-

Avertissement : Même si ces expérimentations sont intéressantes, elles ne sont pas normées, ce qui signifie qu'elles ne sont pas fiables. Si vous les utilisez (et vous ne devriez probablement pas le faire souvent), vous le faites à vos propres risques et périls ; vous faites quelque chose qui peut être mauvais pour le Web en utilisant des propriétés non standard.

-
- - - -

Contrôle de l'apparence des éléments de formulaire

- -

Les navigateurs fondés sur WebKit- (Chrome, Safari) et Gecko- (Firefox) offrent les meilleures possibilités de personnalisation des widgets HTML. Ils sont aussi disponibles sur plateforme croisées, et donc ils nécessitent un mécanisme de bascule entre les widgets de « look and feel » natif  et widget stylistiquement composables par l'utilisateur.

- -

À cette fin, ils utilisent une propriété propriétaire : {{cssxref("-webkit-appearance")}} ou {{cssxref("-moz-appearance")}}. Ces propriétés ne sont pas normées et ne doivent pas être utilisées. En fait, elles se comportent même différemment entre WebKit et Gecko. Cependant, il y a une valeur qu'il est bon de connaître : none. Avec cette valeur, vous êtes en mesure d'obtenir un contrôle (presque total) sur le style des widgets donnés.

- -

Donc, si vous avez du mal à appliquer un style à un élément, essayez d'utiliser ces propriétés propriétaires. Nous verrons quelques exemples ci-dessous, mais le cas d'utilisation le plus connu de cette propriété est relatif au style des champs de recherche sur les navigateurs WebKit :

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

{{EmbedLiveSample("Contrôle_de_l'apparence_des_éléments_de_formulaire", 250, 40)}}

- -
-

Note : Il est toujours difficile de prédire l'avenir, quand on parle de techniques Web. L'extension des possibilités d'expression des CSS est difficile ; il y a un travail exploratoire avec d'autres spécifications, telles que Shadow DOM qui offrent certaines perspectives. La quête du formulaire de style totalement composable est loin d'être terminée.

-
- -

Exemples

- -

Cases à cocher et boutons radio

- -

Composer le style d'une case à cocher ou d'un bouton radio conduit à un certain désordre en soi. Par exemple, la taille des cases à cocher et des boutons radio n'est pas vraiment destinée à être modifiée et les navigateurs peuvent réagir très différemment, si vous essayez de le faire.

- -

Une simple case à cocher

- -

Considérons la case à cocher suivante :

- -
<span><input type="checkbox"></span>
- -
span {
-    display: inline-block;
-    background: red;
-}
-
-input[type=checkbox] {
-    width : 100px;
-    height: 100px;
-}
- -

Voici les différentes façons dont divers navigateurs gèrent cela :

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NavigateurRendu
Firefox 57 (Mac OSX)
Firefox 57 (Windows 10)
Chrome 63 (Mac OSX)
Chrome 63 (Windows 10)
Opera 49 (Mac OSX)
Internet Explorer 11 (Windows 10)
Edge 16 (Windows 10)
- -

Un exemple un peu plus compliqué

- -

Comme Opera et Internet Explorer n'ont pas de fonctionnalités telles que {{cssxref("-webkit-appearance")}} ou {{cssxref("-moz-appearance")}}, leur utilisation n'est pas appropriée. Heureusement, nous sommes dans un cas où les CSS disposent d'assez d'expressions pour trouver des solutions. Prenons un exemple courant :

- -
<form>
-  <fieldset>
-    <p>
-      <input type="checkbox" id="first" name="fruit-1" value="cerise">
-      <label for="first">J'aime les cerises</label>
-    </p>
-    <p>
-      <input type="checkbox" id="second" name="fruit-2" value="banane" disabled>
-      <label for="second">Je ne peux pas aimer la banane</label>
-    </p>
-    <p>
-      <input type="checkbox" id="third" name="fruit-3" value="fraise">
-      <label for="third">J'aime les fraises</label>
-    </p>
-  </fieldset>
-</form>
- -

avec une composition stylistique élémentaire :

- -
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;
-}
- -

Maintenant composons pour avoir une case à cocher personnalisée.

- -

Le plan consiste à remplacer la case à cocher native par une image de notre choix. Tout d'abord, nous devons préparer une image avec tous les états requis pour une case à cocher. Ces états sont : non coché, coché, non coché désactivé et coché désactivé. Cette image sera utilisée comme fantôme des CSS :

- -

Check box CSS Sprite

- -

Commençons par masquer les cases à cocher d'origine. Nous les déplacerons simplement à l'extérieur de la fenêtre de visualisation de la page. Il y a deux choses importantes à considérer ici :

- - - -
:root input[type=checkbox] {
-  /* les cases à cocher d'origine sont placées en dehors de la vue */
-  position: absolute;
-  left: -1000em;
-}
- -

Maintenant que nous sommes débarrassés des cases à cocher natives, ajoutons la nôtre. Pour cela, nous utiliserons le pseudo élément {{cssxref(":before")}} de l'élément {{HTMLElement("label")}} qui suit la case à cocher originale. Ainsi, dans le sélecteur suivant, nous utilisons le sélecteur d'attributs pour cibler la case à cocher, puis nous utilisons le sélecteur de parents adjacent pour cibler le label suivant la case à cocher originale. Enfin, nous accédons au pseudo-élément {{cssxref(":before")}} et le styliser pour qu'il affiche notre case à cocher personnalisée non cochée.

- -
: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;
-
-/* Ce qui suit est utilisé pour ajuster la position des cases à cocher
-   sur la ligne de base suivante */
-
-  vertical-align: bottom;
-  position: relative;
-  bottom: 2px;
-}
- -

Nous utilisons les pseudo-classes {{cssxref(":checked")}} et {{cssxref(":disabled")}} sur la case à cocher d'origine pour changer l'état de notre case à cocher personnalisée en conséquence. Comme nous utilisons un fantôme des CSS, tout ce que nous avons à faire est de changer la position de l'arrière-plan.

- -
: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;
-}
- -

Une dernière chose (mais très importante) : lorsqu'un utilisateur utilise le clavier pour naviguer d'un widget à un autre, chaque widget qui reçoit le focus doit être marqué visuellement. Comme nous cachons les cases à cocher natives, nous devons implémenter cette fonctionnalité nous-mêmes : l'utilisateur doit pouvoir voir où elles se trouvent dans le formulaire. Le CSS suivant met en œuvre le focus sur les cases à cocher personnalisées.

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

Voyez directement ici le résultat :

- -

{{EmbedLiveSample("Un_exemple_un_peu_plus_compliqué", 250, 130)}}

- -

Gérer le cauchemar <select>

- -

L'élément {{HTMLElement("select")}} est considéré comme un widget « truand », car il est impossible de lui composer un style cohérent entre les plateformes. Toutefois, certaines choses restent possibles. Plutôt qu'une longue explication, voyons un exemple :

- -
<select>
-  <option>Cerise</option>
-  <option>Banane</option>
-  <option>Fraise</option>
-</select>
- -
select {
-  width   : 80px;
-  padding : 10px;
-}
-
-option {
-  padding : 5px;
-  color   : red;
-}
- -

Le tableau suivant montre comment divers navigateurs gèrent cela, dans deux cas. Les deux premières colonnes ne sont que l'exemple ci-dessus. Les deux colonnes suivantes utilisent des CSS personnalisés supplémentaires, pour avoir plus de contrôle sur l'apparence du widget :

- -
select, option {
-  -webkit-appearance : none; /* Pour avoir le contrôle de l'apparence sur WebKit/Chromium */
-  -moz-appearance : none; /* Pour avoir le contrôle sur l'apparence sur Gecko */
-
-  /* Pour avoir le contrôle sur l'apparence et sur Trident (IE)
-     Notez que cela fonctionne aussi sur Gecko et a des effets limités sur WebKit */
-  background : none;
-}
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NavigateurRendu classiqueRendu travaillé
ferméouvertferméouvert
Firefox 57 (Mac OSX)
Firefox 57 (Windows 10)
Chrome 63 (Mac OSX)
Chrome 63 (Windows 10)
Opera 49 (Mac OSX)
IE11 (Windows 10)
Edge 16 (Windows 10)
- -

Comme vous pouvez le voir, malgré l'aide des propriétés -*-appearance, il reste quelques problèmes :

- - - -

De plus, avec notre exemple, nous n'utilisons que trois propriétés CSS. Imaginez le désordre quand on considère encore plus de propriétés CSS. Comme vous pouvez le voir, les CSS ne sont pas adaptées pour changer l'apparence et la convivialité de ces widgets de manière cohérente, mais elles vous permettent quand même d'ajuster certaines choses. Pour autant que vous soyez prêt à vivre avec des différences d'un navigateur et d'un système d'exploitation à l'autre.

- -

Nous vous aiderons à comprendre quelles sont les propriétés qui conviennent dans l'article suivant : Tableau de compatibilité des propriétés entre les widgets de formulaire.

- -

Vers des formulaires plus sympas : bibliothèques utiles et « polyfill » (prothèses d'émulation)

- -

Bien que les CSS soient assez expressives pour les cases à cocher et les boutons radio, c'est loin d'être vrai pour les widgets plus avancés. Même si certaines choses sont possibles avec l'élément {{HTMLElement("select")}}, le widget file ne peut pas être stylisé du tout. Il en est de même pour le sélecteur de date, etc.

- -

Si vous souhaitez avoir un contrôle total sur les widgets de formulaire, vous n'avez pas d'autre choix que de compter sur JavaScript. Dans l'article Comment créer des widgets de formulaires personnalisés, nous voyons comment le faire nous-mêmes, mais il existe des bibliothèques très utiles pouvant vous aider :

- - - -

Les bibliothèques suivantes ne visent pas seulement les formulaires, mais elles ont des fonctionnalités très intéressantes pour les traiter :

- - - -

Rappelez-vous que lier CSS et JavaScript peut avoir des effets collatéraux. Donc, si vous choisissez d'utiliser l'une de ces bibliothèques, vous devez toujours prévoir des solutions de repli dans les feuilles de style en cas d'échec du script. Il y a de nombreuses raisons pour lesquelles les scripts peuvent échouer, surtout dans le monde des mobiles et vous devez concevoir votre site Web ou votre application pour traiter ces cas le mieux possible.

- -

Conclusion

- -

 

- -

Bien qu'il y ait encore des points noirs avec l'utilisation des CSS dans les formulaires HTML, il y a souvent moyen de les contourner. Il n'existe pas de solution générale et nette, mais les navigateurs modernes offrent de nouvelles possibilités. Pour l'instant, la meilleure solution est d'en savoir plus sur la façon dont les divers navigateurs prennent en charge les CSS, telles qu'appliquées aux widgets de formulaires HTML.

- -

Dans le prochain article de ce guide, nous explorerons comment les différents widgets de formulaire HTML prennent en charge  les plus importantes propriétés des CSS : Tableau de compatibilité des propriétés entre widgets de formulaire.

- -

Voir aussi

- - - -

{{PreviousMenuNext("Web/Guide/HTML/Formulaires/Apparence_des_formulaires_HTML", "Web/Guide/HTML/Formulaires/Property_compatibility_table_for_form_widgets", "Web/Guide/HTML/Formulaires")}}

- -

Dans ce module

- - diff --git a/files/fr/web/guide/html/formulaires/apparence_des_formulaires_html/index.html b/files/fr/web/guide/html/formulaires/apparence_des_formulaires_html/index.html deleted file mode 100644 index fbdafe47d4..0000000000 --- a/files/fr/web/guide/html/formulaires/apparence_des_formulaires_html/index.html +++ /dev/null @@ -1,391 +0,0 @@ ---- -title: Mise en forme des formulaires HTML -slug: Web/Guide/HTML/Formulaires/Apparence_des_formulaires_HTML -tags: - - CSS - - Exemple - - Formulaires - - Guide - - HTML - - Intermédiaire - - Web -translation_of: Learn/Forms/Styling_web_forms ---- -
{{LearnSidebar}}{{PreviousMenuNext("Web/Guide/HTML/Formulaires/HTML_forms_in_legacy_browsers", "Web/Guide/HTML/Formulaires/Advanced_styling_for_HTML_forms", "Web/Guide/HTML/Formulaires")}}
- -
-

Dans cet article, nous allons apprendre comment utiliser les CSS avec les formulaires HTML pour (espérons-le) améliorer leur apparence. Étonnamment, ceci peut être délicat. Pour des raisons techniques et historiques, les widgets de formulaires ne s'allient pas très bien avec CSS. À cause de ces difficultés, de nombreux développeurs préfèrent construire leurs propres widgets HTML pour avoir plus de maîtrise sur leur apparence. Toutefois, avec les navigateurs modernes, les web designers ont de plus en plus d'emprise sur l'apparence de leurs formulaires. Voyons cela de plus près.

-
- -

Pourquoi est-ce si difficile de modifier l'apparence des formulaires avec CSS ?

- -

Dans la jeunesse du Web — aux alentours de 1995 — les formulaires ont été ajoutés au HTML dans la spécification HTML 2. À cause de la complexité des formulaires, ceux qui les mettaient en œuvre ont préféré s'appuyer sur le système d'exploitation sous‑jacent pour les gérer et les afficher.

- -

Quelques années plus tard, les CSS ont été créées et ce qui était une nécessité technique — c'est-à-dire, utiliser des widgets natifs pour les contrôles de formulaire — est devenu un préalable stylistique. Dans la jeunesse des CSS, l'apparence des formulaires n'était pas une priorité.

- -

Comme les utilisateurs étaient habitués à l'apparence visuelle de leurs plateformes respectives, les fournisseurs de navigateurs étaient réticents à rendre possible la modification de l'apparence des formulaires. Et pour être honnête, il est toujours extrêmement difficile de reconstruire tous les contrôles pour que leur apparence soit modifiable.

- -

Même aujourd'hui, aucun des navigateurs n'a entièrement mis en œuvre les CSS 2.1. Avec le temps, les fournisseurs de navigateurs ont toutefois amélioré la compatibilité des CSS avec les éléments de formulaires, et bien que ce soit de mauvaise réputation pour leur utilisation, vous pouvez désormais modifier l'apparence des formulaires HTML.

- -

Tous les widgets ne sont pas égaux devant les CSS

- -

Actuellement, quelques difficultés subsistent dans l'utilisation des CSS avec les formulaires. Ces problèmes peuvent être classés en trois catégories.

- -

Le bon

- -

L'apparence de certains éléments peut être modifiée sans poser beaucoup de problèmes suivant les diverses plateformes. Ceci inclut les éléments structurels suivants :

- -
    -
  1. {{HTMLElement("form")}}
  2. -
  3. {{HTMLElement("fieldset")}}
  4. -
  5. {{HTMLElement("label")}}
  6. -
  7. {{HTMLElement("output")}}
  8. -
- -

Ceci inclut aussi tous les widgets de champs textuels (qu'ils soient mono ou multi‑lignes), ainsi que les boutons.

- -

La brute

- -

L'apparence de certains éléments ne peut être modifiée que rarement et peut nécessiter quelques astuces complexes, et parfois une connaissance avancée des CSS3.

- -

Ceci inclut l'élément {{HTMLElement("legend")}}. Ce dernier ne peut pas être positionné correctement sur toutes les plateformes. De plus, l'apparence des cases à cocher et des boutons radio ne peut pas être modifiée directement. Toutefois, grâce à CSS3 c'est possible de contourner cette limitation. L'apparence du contenu {{htmlattrxref("placeholder", "input")}} ne peut pas être modifiée d'une manière standard. Mais tous les navigateurs qui sont compatible avec cet attribut ont aussi implémenté des pseudo-classes ou pseudo-élément propriétaires qui permettent de modifier son apparence.

- -

Nous allons voir comment gérer ces cas particuliers dans l'article Apparence avancée des formulaires HTML.

- -

Le truand

- -

L'apparence de certains éléments n'est tout bonnement pas modifiable en utilisant les CSS. Ceci inclut toutes les interfaces avancées comme les intervalles, la sélection de couleur ou de date ainsi que les éléments déroulants, y compris les éléments {{HTMLElement("select")}}, {{HTMLElement("option")}}, {{HTMLElement("optgroup")}} et {{HTMLElement("datalist")}}. La sélection de fichiers est aussi connue pour ne pas pouvoir changer d'apparence. Les nouveaux éléments {{HTMLElement("progress")}} et {{HTMLElement("meter")}} font aussi partie de cette catégorie.

- -

Le principal problème avec tous ces widgets vient du fait que leur structure est très complexe et les CSS n'ont pas assez d'expressions pour décrire et modifier l'apparence des éléments. Si vous souhaitez modifier l'apparence des widgets vous devez utiliser JavaScript pour construire une arborescence DOM qui vous permet de modifier l'apparence. Nous explorons cette possibilité dans l'article Comment créer des widgets de formulaire personnalisés.

- -

Compositions stylistiques de base

- -

Pour changer l'apparence des éléments facilement modifiables avec les CSS, vous ne devriez pas rencontrer de problèmes, puisqu'ils se comportent comme n'importe quel autre élément HTML. Toutefois, les feuilles de style peuvent ne pas être cohérentes entre navigateurs, il y a donc un certain nombre d'astuces à connaître.

- -

Champs de recherche

- -

Les boîtes de recherche sont le seul type de champ textuel dont l'apparence peut être un peu complexe à modifier. Sur les navigateurs utilisant WebKit (Chrome, Safari, etc.) vous devrez utiliser la propriété CSS propriétaire -webkit-appearance. Nous allons aborder le sujet plus en détails dans dans l'article : Apparence avancée des formulaires HTML.

- -

Exemple

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

This is a screenshot of a search filed on Chrome, with and without the use of -webkit-appearance

- -

Comme vous pouvez le voir sur la capture d'écran pour Chrome, les deux champs ont une bordure, mais le premier champ n'utilise pas la propriété -webkit-appearance tandis que le second a recours à la propriété -webkit-appearance:none. La différence est notable.

- -

Texte et polices de caractères

- -

Les fonctionnalités liées au texte et aux polices de caractères dans les CSS peuvent être utilisées facilement avec n'importe quel widget (et oui, vous pouvez utiliser {{cssxref("@font-face")}} avec les formulaires). Toutefois, le comportement des navigateurs est souvent incompatible. Par défaut, certains éléments comme {{cssxref("font-family")}} {{cssxref("font-size")}} n'héritent pas de leurs parents. De nombreux navigateurs utilisent les valeurs du système d'exploitation. Pour que l'apparence des formulaires soit cohérente avec le reste de votre contenu, vous pouvez ajouter les règles suivantes à votre feuille de style :

- -
button, input, select, textarea {
-  font-family : inherit;
-  font-size   : 100%;
-}
- -

La capture d'écran ci-dessous montre les différences. Sur la gauche il y a l'affichage par défaut de Firefox pour Mac OS X, avec les réglages de police par défaut du système. Sur la droite, les mêmes éléments avec la règle d'harmonisation utilisée.

- -

This is a screenshot of the main form widgets on Firefox on Mac OSX, with and without font harmonization

- -

Il existe un débat animé sur le fait qu'un formulaire ait une meilleure apparence en utilisant les valeurs par défaut du système d'exploitation ou en utilisant des valeurs unifiant l'apparence. C'est à vous de décider en tant que designer du site ou de l'application.

- -

Modèle de boîte

- -

Tous les champs textuels sont compatibles avec les différentes propriétés du modèle de boîte CSS ({{cssxref("width")}}, {{cssxref("height")}}, {{cssxref("padding")}}, {{cssxref("margin")}} et {{cssxref("border")}}). Toutefois, comme précédemment les navigateurs s'appuient sur l'apparence par défaut du système d'exploitation. C'est votre décision de choisir si vous souhaitez intégrer vos formulaires à votre contenu du point de vue de l'apparence. Si vous souhaitez conserver l'apparence originale des blocs, vous aurez des difficultés à leur donner des dimensions cohérentes.

- -

Chacun des blocs a ses propres règles concernant les bordures, la marge intérieure (padding) et extérieure (margin). Si vous souhaitez qu'ils aient tous la même dimension, vous devrez utiliser la propriété {{cssxref("box-sizing")}} :

- -
input, textarea, select, button {
-  width : 150px;
-  margin: 0;
-
-  -webkit-box-sizing: border-box; /* Pour les anciennes versions des navigateurs WebKit */
-     -moz-box-sizing: border-box; /* Pour tous les navigateurs Gecko */
-          box-sizing: border-box;
-}
- -

This is a screenshot of the main form widgets on Chrome on Windows 7, with and without the use of box-sizing.

- -

Dans la capture d'écran ci-dessous, la colonne de gauche n'utilise pas {{cssxref("box-sizing")}}, alors que la colonne de droite utilise la propriété CSS border-box. Remarquez comment tous les éléments occupent le même espace, malgré les valeurs par défaut de la plateforme pour chacun des blocs.

- -

Positionnement

- -

Le positionnement des formulaires HTML n'est pas un problème de manière générale. Seulement deux éléments nécessitent une attention particulière :

- -

legend

- -

L'apparence de l'élément {{HTMLElement("legend")}} est facile à modifier à l'exception de sa position. Dans chaque navigateur, l'élément {{HTMLElement("legend")}} est positionné au-dessus de la bordure supérieure de son élément {{HTMLElement("fieldset")}} parent. Il n'existe aucune manière de changer sa position dans le flux HTML. Vous pouvez toutefois le positionner de manière absolue ou relative en utilisant la propriété {{cssxref("position")}}, sinon, ce sera une partie de la bordure de l'élément fieldset.

- -

Comme l'élément {{HTMLElement("legend")}} est très important pour des raisons d'accessibilité (nous parlerons des techniques pour l'assistance à propos de l'attribut  label de chaque élément de formulaire du fieldset), il est souvent associé à un intitulé, puis caché à l'accessibilité, comme ceci :

- -
HTML
- -
<fieldset>
-  <legend>Hi!</legend>
-  <h1>Hello</h1>
-</fieldset>
- -
CSS
- -
legend {
-  width: 1px;
-  height: 1px;
-  overflow: hidden;
-}
- -

textarea

- -

Par défaut, tous les navigateurs considèrent l'élément {{HTMLElement("textarea")}} comme un bloc incorporé aligné sur la ligne du bas du texte. C'est rarement ce que nous souhaitons vraiment. Pour passer d'inline-block à block, il est assez facile d'utiliser la propriété {{cssxref("display")}}. Mais si vous voulez l'utiliser en ligne, il est courant de changer son alignement vertical :

- -
textarea {
-  vertical-align: top;
-}
- -

Exemple

- -

Regardons sur un exemple concret la façon de composer un formulaire HTML. Cela aidera à clarifier nombre de ces concepts. Nous allons construire un formulaire de contact sous forme de « carte postale » :

- -

C'est ce que nous voulons réaliser avec le HTML et les CSS.

- -

HTML

- -

Le HTML n'est qu'à peine plus développé que celui de l'exemple du premier article de ce guide ; il ne comporte que quelques identifiants supplémentaires et un titre.

- -
<form>
-  <h1>à: Mozilla</h1>
-
-  <div id="from">
-    <label for="name">de :</label>
-    <input type="text" id="name" name="user_name">
-  </div>
-
-  <div id="reply">
-    <label for="mail">répondre à :</label>
-    <input type="email" id="mail" name="user_email">
-  </div>
-
-  <div id="message">
-    <label for="msg">Votre message :</label>
-    <textarea id="msg" name="user_message"></textarea>
-  </div>
-
-  <div class="button">
-    <button type="submit">Poster le message</button>
-  </div>
-</form>
- -

Organiser les ressources

- -

C'est ici que le « fun » commence ! Avant de commencer à coder, nous avons besoin de trois ressources supplémentaires :

- -
    -
  1. L'image de fond de la carte postale — téléchargez cette image et sauvegardez‑la dans le même répertoire que votre fichier HTML de travail.
  2. -
  3. Une police de machine à écrire : « Secret Typewriter » de fontsquirrel.com — téléchargez le fichier TTF dans le même répertoire que ci‑dessus.
  4. -
  5. Une police d'écriture manuelle :  « Journal » de fontsquirrel.com — téléchargez le fichier TTF dans le même répertoire que ci‑dessus.
  6. -
- -

 

- -

Les polices demandent un supplément de traitement avant de débuter :

- -
    -
  1. Allez sur le Webfont Generator de fontsquirrel.
  2. -
  3. En utilisant le formulaire, téléversez les fichiers de polices et créez un kit de polices pou le Web. Téléchargez le kit sur votre ordinateur.
  4. -
  5. Décompressez le fichier zip fourni.
  6. -
  7. Dans le contenu décompressé vous trouverez deux fichiers .woff et deux fichiers .woff2. Copiez ces quatre fichiers dans un répertoire nommé fonts, dans le même répertoire que ci‑dessus. Nous utilisons deux fichiers différents pour maximiser la compatibilité avec les navigateurs ; voyez notre article sur les Web fonts pour des informations plus détaillées.
  8. -
- -

Le CSS

- -

 

- -

Maintenant nous pouvons approfondir les CSS de l'exemple. Ajoutez tous les blocs de code affichés ci‑dessous dans un élément {{htmlelement("style")}}, l'un après l'autre.

- -

D'abord, la préparation de base en définissant les règles de {{cssxref("@font-face")}} et les base des éléments {{HTMLElement("body")}} et {{HTMLElement("form")}}.

- -
@font-face{
-  font-family : "handwriting";
-  src: url('fonts/journal-webfont.woff2') format('woff2'),
-       url('fonts/journal-webfont.woff') format('woff');
-  font-weight: normal;
-  font-style: normal;
-}
-
-@font-face{
-  font-family : "typewriter";
-  src: url('fonts/veteran_typewriter-webfont.woff2') format('woff2'),
-       url('fonts/veteran_typewriter-webfont.woff') format('woff');
-  font-weight: normal;
-  font-style: normal;
-}
-
-body {
-  font  : 21px sans-serif;
-
-  padding : 2em;
-  margin  : 0;
-
-  background : #222;
-}
-
-form {
-  position: relative;
-
-  width  : 740px;
-  height : 498px;
-  margin : 0 auto;
-
-  background: #FFF url(background.jpg);
-}
- -

Maintenant nous pouvons placer nos éléments, y compris le titre et tous les éléments du formulaire.

- -
h1 {
-  position : absolute;
-  left : 415px;
-  top  : 185px;
-
-  font : 1em "typewriter", sans-serif;
-}
-
-#from {
-  position: absolute;
-  left : 398px;
-  top  : 235px;
-}
-
-#reply {
-  position: absolute;
-  left : 390px;
-  top  : 285px;
-}
-
-#message {
-  position: absolute;
-  left : 20px;
-  top  : 70px;
-}
- -

C'est là que nous commençons à travailler sur les éléments du formulaire eux-mêmes. Tout d'abord, assurons-nous que l'élément {{HTMLElement("label")}} est doté de la bonne police de caractères.

- -
label {
-  font : .8em "typewriter", sans-serif;
-}
- -

Les champs texte nécessitent quelques règles courantes. Mettons‑les simplement, nous supprimons {{cssxref("border","borders")}} et {{cssxref("background","backgrounds")}} et redéfinissons {{cssxref("padding")}} et {{cssxref("margin")}}.

- -
input, textarea {
-  font    : .9em/1.5em "handwriting", sans-serif;
-
-  border  : none;
-  padding : 0 10px;
-  margin  : 0;
-  width   : 240px;
-
-  background: none;
-}
- -

Lorsque l'un de ces champs reçoit le focus, nous le mettons en évidence avec un fond gris clair et transparent. Notez qu'il est important d'ajouter la propriété {{cssxref("outline")}} pour supprimer le focus par défaut ajouté par certains navigateurs.

- -
input:focus, textarea:focus {
-  background   : rgba(0,0,0,.1);
-  border-radius: 5px;
-  outline      : none;
-}
- -

Maintenant que nos champs texte sont terminés, nous devons ajuster l'affichage de ceux à une et ceux à plusieurs lignes pour qu'ils correspondent, car ils ne sont généralement pas du tout identiques par défaut.

- -

Le champ texte à une seule ligne a besoin de quelques ajustements pour un bon rendu dans Internet Explorer. Internet Explorer ne définit pas la hauteur des champs en fonction de la hauteur naturelle de la police (qui est le comportement de tous les autres navigateurs). Pour résoudre ce problème, nous devons ajouter une hauteur explicite au champ, comme suit :

- -
input {
-    height: 2.5em; /* pour IE */
-    vertical-align: middle; /* optionnel mais donne meilleur aspect pour IE */
-}
- -

Les éléments {{HTMLElement("textarea")}} sont rendus par défaut en tant qu'élément bloc. Les deux choses importantes ici sont les propriétés {{cssxref("resize")}} et {{cssxref("overflow")}}. Comme notre design est à taille fixe, nous utiliserons la propriété resize pour empêcher les utilisateurs de redimensionner le champ texte multiligne. La propriété {{cssxref("overflow")}} est utilisée pour rendre le champ plus cohérent d'un navigateur à l'autre ; certains navigateurs utilisent la valeur auto et d'autres la valeur par défaut pour scroll lorsqu'elle n'est pas précisée. Dans notre cas, il vaut mieux s'assurer que tout le monde utilise auto.

- -
textarea {
-  display : block;
-
-  padding : 10px;
-  margin  : 10px 0 0 -10px;
-  width   : 340px;
-  height  : 360px;
-
-  resize  : none;
-  overflow: auto;
-}
- -

L'élément {{HTMLElement("button")}} est très accommodant avec les CSS ; vous faites ce que vous voulez, même en utilisant les pseudo-elements !

- -
button {
-  position     : absolute;
-  left         : 440px;
-  top          : 360px;
-
-  padding      : 5px;
-
-  font         : bold .6em sans-serif;
-  border       : 2px solid #333;
-  border-radius: 5px;
-  background   : none;
-
-  cursor       : pointer;
-
--webkit-transform: rotate(-1.5deg);
-   -moz-transform: rotate(-1.5deg);
-    -ms-transform: rotate(-1.5deg);
-     -o-transform: rotate(-1.5deg);
-        transform: rotate(-1.5deg);
-}
-
-button:after {
-  content: " >>>";
-}
-
-button:hover,
-button:focus {
-  outline   : none;
-  background: #000;
-  color   : #FFF;
-}
- -

Et voilà ! (en français dans le texte)

- -
-

Note : si cet exemple ne fonctionne pas tout à fait comme vous l'attendez et que vous voulez vérifier votre version, vous la trouverez sur GitHub — voyez‑la fonctionner en direct (et revoyez son code source).

-
- -

Conclusion

- -

Comme vous pouvez le voir, tant que nous voulons construire des formulaires avec seulement des champs de texte et des boutons, il est facile de les styliser à l'aide des CSS. Si vous voulez en savoir plus sur les petites astuces des CSS qui peuvent vous faciliter la vie lorsque vous travaillez avec des widgets de formulaire, jetez un coup d'oeil à la partie formulaire du projet normalize.css.

- -

Dans le prochain article, nous verrons comment gérer les widgets des catégories « brutes » et « truands ».

- -

{{PreviousMenuNext("Web/Guide/HTML/Formulaires/HTML_forms_in_legacy_browsers", "Web/Guide/HTML/Formulaires/Advanced_styling_for_HTML_forms", "Web/Guide/HTML/Formulaires")}}

- -

Dans ce module

- - diff --git "a/files/fr/web/guide/html/formulaires/comment_construire_des_widgets_de_formulaires_personnalis\303\251s/example_3/index.html" "b/files/fr/web/guide/html/formulaires/comment_construire_des_widgets_de_formulaires_personnalis\303\251s/example_3/index.html" deleted file mode 100644 index a647cfaba3..0000000000 --- "a/files/fr/web/guide/html/formulaires/comment_construire_des_widgets_de_formulaires_personnalis\303\251s/example_3/index.html" +++ /dev/null @@ -1,247 +0,0 @@ ---- -title: Exemple 3 -slug: >- - Web/Guide/HTML/Formulaires/Comment_construire_des_widgets_de_formulaires_personnalisés/Example_3 -tags: - - Formulaires - - HTML -translation_of: Learn/Forms/How_to_build_custom_form_controls/Example_3 ---- -

Ceci est le troisième exemple expliquant comment construire des widgets de formulaire personnalisés.

- -

Changement d'état

- -

Contenu HTML

- -
<form class="no-widget">
-  <select name="myFruit" tabindex="-1">
-      <option>Cerise</option>
-      <option>Citron</option>
-      <option>Banane</option>
-      <option>Fraise</option>
-      <option>Pomme</option>
-  </select>
-
-  <div class="select" tabindex="0">
-    <span class="value">Cerise</span>
-    <ul class="optList hidden">
-      <li class="option">Cerise</li>
-      <li class="option">Citron</li>
-      <li class="option">Banane</li>
-      <li class="option">Fraise</li>
-      <li class="option">Pomme</li>
-    </ul>
-  </div>
-</form>
- -

Contenu du CSS

- -
.widget select,
-.no-widget .select {
-  position : absolute;
-  left     : -5000em;
-  height   : 0;
-  overflow : hidden;
-}
-
-/* --------------- */
-/* Styles Requis   */
-/* --------------- */
-
-.select {
-  position: relative;
-  display : inline-block;
-}
-
-.select.active,
-.select:focus {
-  box-shadow: 0 0 3px 1px #227755;
-  outline: none;
-}
-
-.select .optList {
-  position: absolute;
-  top     : 100%;
-  left    : 0;
-}
-
-.select .optList.hidden {
-  max-height: 0;
-  visibility: hidden;
-}
-
-/* ------------ */
-/* Style  chic  */
-/* ------------ */
-
-.select {
-  font-size   : 0.625em; /* 10px */
-  font-family : Verdana, Arial, sans-serif;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  padding : 0.1em 2.5em 0.2em 0.5em; /* 1px 25px 2px 5px */
-  width   : 10em; /* 100px */
-
-  border        : 0.2em solid #000; /* 2px */
-  border-radius : 0.4em; /* 4px */
-
-  box-shadow : 0 0.1em 0.2em rgba(0,0,0,.45); /* 0 1px 2px */
-
-  background : #F0F0F0;
-  background : -webkit-linear-gradient(90deg, #E3E3E3, #fcfcfc 50%, #f0f0f0);
-  background : linear-gradient(0deg, #E3E3E3, #fcfcfc 50%, #f0f0f0);
-}
-
-.select .value {
-  display  : inline-block;
-  width    : 100%;
-  overflow : hidden;
-
-  white-space   : nowrap;
-  text-overflow : ellipsis;
-  vertical-align: top;
-}
-
-.select:after {
-  content : "▼";
-  position: absolute;
-  z-index : 1;
-  height  : 100%;
-  width   : 2em; /* 20px */
-  top     : 0;
-  right   : 0;
-
-  padding-top : .1em;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  text-align : center;
-
-  border-left  : .2em solid #000;
-  border-radius: 0 .1em .1em 0;
-
-  background-color : #000;
-  color : #FFF;
-}
-
-.select .optList {
-  z-index : 2;
-
-  list-style: none;
-  margin : 0;
-  padding: 0;
-
-  background: #f0f0f0;
-  border: .2em solid #000;
-  border-top-width : .1em;
-  border-radius: 0 0 .4em .4em;
-
-  box-shadow: 0 .2em .4em rgba(0,0,0,.4);
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  min-width : 100%;
-  max-height: 10em; /* 100px */
-  overflow-y: auto;
-  overflow-x: hidden;
-}
-
-.select .option {
-  padding: .2em .3em;
-}
-
-.select .highlight {
-  background: #000;
-  color: #FFFFFF;
-}
- -

Contenu JavaScript

- -
// ----------- //
-// UTILITAIRES //
-// ----------- //
-
-NodeList.prototype.forEach = function (callback) {
-  Array.prototype.forEach.call(this, callback);
-}
-
-// ------------------------- //
-// Définitions des fonctions //
-// ------------------------- //
-
-function deactivateSelect(select) {
-  if (!select.classList.contains('active')) return;
-
-  var optList = select.querySelector('.optList');
-
-  optList.classList.add('hidden');
-  select.classList.remove('active');
-}
-
-function activeSelect(select, selectList) {
-  if (select.classList.contains('active')) return;
-
-  selectList.forEach(deactivateSelect);
-  select.classList.add('active');
-};
-
-function toggleOptList(select, show) {
-  var optList = select.querySelector('.optList');
-
-  optList.classList.toggle('hidden');
-}
-
-function highlightOption(select, option) {
-  var optionList = select.querySelectorAll('.option');
-
-  optionList.forEach(function (other) {
-    other.classList.remove('highlight');
-  });
-
-  option.classList.add('highlight');
-};
-
-// ------------------- //
-// Lien aux événements //
-// ------------------- //
-
-window.addEventListener("load", function () {
-  var form = document.querySelector('form');
-
-  form.classList.remove("no-widget");
-  form.classList.add("widget");
-});
-
-window.addEventListener('load', function () {
-  var selectList = document.querySelectorAll('.select');
-
-  selectList.forEach(function (select) {
-    var optionList = select.querySelectorAll('.option');
-
-    optionList.forEach(function (option) {
-      option.addEventListener('mouseover', function () {
-        highlightOption(select, option);
-      });
-    });
-
-    select.addEventListener('click', function (event) {
-      toggleOptList(select);
-    },  false);
-
-    select.addEventListener('focus', function (event) {
-      activeSelect(select, selectList);
-    });
-
-    select.addEventListener('blur', function (event) {
-      deactivateSelect(select);
-    });
-  });
-});
- -

Résultat

- -

{{ EmbedLiveSample('Change_states') }}

diff --git "a/files/fr/web/guide/html/formulaires/comment_construire_des_widgets_de_formulaires_personnalis\303\251s/example_4/index.html" "b/files/fr/web/guide/html/formulaires/comment_construire_des_widgets_de_formulaires_personnalis\303\251s/example_4/index.html" deleted file mode 100644 index 4bd1a9a069..0000000000 --- "a/files/fr/web/guide/html/formulaires/comment_construire_des_widgets_de_formulaires_personnalis\303\251s/example_4/index.html" +++ /dev/null @@ -1,297 +0,0 @@ ---- -title: Exemple 4 -slug: >- - Web/Guide/HTML/Formulaires/Comment_construire_des_widgets_de_formulaires_personnalisés/Example_4 -tags: - - Avancé - - Exemple - - Formulaires - - Guide - - HTML - - Web -translation_of: Learn/Forms/How_to_build_custom_form_controls/Example_4 ---- -

Ceci est le quatrième exemple expliquant comment construire des widgets de formulaire personnalisés.

- -

Changement d'état

- -

Contenu HTML

- -
<form class="no-widget">
-  <select name="myFruit">
-    <option>Cerise</option>
-    <option>Citron</option>
-    <option>Banane</option>
-    <option>Fraise</option>
-    <option>Pomme</option>
-  </select>
-
-  <div class="select">
-    <span class="value">Cerise</span>
-    <ul class="optList hidden">
-      <li class="option">Cerise</li>
-      <li class="option">Citron</li>
-      <li class="option">Banane</li>
-      <li class="option">Fraise</li>
-      <li class="option">Pomme</li>
-    </ul>
-  </div>
-</form>
- -

Contenu CSS

- -
.widget select,
-.no-widget .select {
-  position : absolute;
-  left     : -5000em;
-  height   : 0;
-  overflow : hidden;
-}
-
-/* --------------- */
-/* Styles Requis   */
-/* --------------- */
-
-.select {
-  position: relative;
-  display : inline-block;
-}
-
-.select.active,
-.select:focus {
-  box-shadow: 0 0 3px 1px #227755;
-  outline: none;
-}
-
-.select .optList {
-  position: absolute;
-  top     : 100%;
-  left    : 0;
-}
-
-.select .optList.hidden {
-  max-height: 0;
-  visibility: hidden;
-}
-
-/* ------------ */
-/* Styles chic  */
-/* ------------ */
-
-.select {
-  font-size   : 0.625em; /* 10px */
-  font-family : Verdana, Arial, sans-serif;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  padding : 0.1em 2.5em 0.2em 0.5em; /* 1px 25px 2px 5px */
-  width   : 10em; /* 100px */
-
-  border        : 0.2em solid #000; /* 2px */
-  border-radius : 0.4em; /* 4px */
-
-  box-shadow : 0 0.1em 0.2em rgba(0,0,0,.45); /* 0 1px 2px */
-
-  background : #F0F0F0;
-  background : -webkit-linear-gradient(90deg, #E3E3E3, #fcfcfc 50%, #f0f0f0);
-  background : linear-gradient(0deg, #E3E3E3, #fcfcfc 50%, #f0f0f0);
-}
-
-.select .value {
-  display  : inline-block;
-  width    : 100%;
-  overflow : hidden;
-
-  white-space   : nowrap;
-  text-overflow : ellipsis;
-  vertical-align: top;
-}
-
-.select:after {
-  content : "▼";
-  position: absolute;
-  z-index : 1;
-  height  : 100%;
-  width   : 2em; /* 20px */
-  top     : 0;
-  right   : 0;
-
-  padding-top : .1em;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  text-align : center;
-
-  border-left  : .2em solid #000;
-  border-radius: 0 .1em .1em 0;
-
-  background-color : #000;
-  color : #FFF;
-}
-
-.select .optList {
-  z-index : 2;
-
-  list-style: none;
-  margin : 0;
-  padding: 0;
-
-  background: #f0f0f0;
-  border: .2em solid #000;
-  border-top-width : .1em;
-  border-radius: 0 0 .4em .4em;
-
-  box-shadow: 0 .2em .4em rgba(0,0,0,.4);
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  min-width : 100%;
-  max-height: 10em; /* 100px */
-  overflow-y: auto;
-  overflow-x: hidden;
-}
-
-.select .option {
-  padding: .2em .3em;
-}
-
-.select .highlight {
-  background: #000;
-  color: #FFFFFF;
-}
- -

Contenu JavaScript

- -
// ----------- //
-// UTILITAIRES //
-// ----------- //
-
-NodeList.prototype.forEach = function (callback) {
-  Array.prototype.forEach.call(this, callback);
-}
-
-// ------------------------- //
-// Définitions des fonctions //
-// ------------------------- //
-
-function deactivateSelect(select) {
-  if (!select.classList.contains('active')) return;
-
-  var optList = select.querySelector('.optList');
-
-  optList.classList.add('hidden');
-  select.classList.remove('active');
-}
-
-function activeSelect(select, selectList) {
-  if (select.classList.contains('active')) return;
-
-  selectList.forEach(deactivateSelect);
-  select.classList.add('active');
-};
-
-function toggleOptList(select, show) {
-  var optList = select.querySelector('.optList');
-
-  optList.classList.toggle('hidden');
-}
-
-function highlightOption(select, option) {
-  var optionList = select.querySelectorAll('.option');
-
-  optionList.forEach(function (other) {
-    other.classList.remove('highlight');
-  });
-
-  option.classList.add('highlight');
-};
-
-function updateValue(select, index) {
-  var nativeWidget = select.previousElementSibling;
-  var value = select.querySelector('.value');
-  var optionList = select.querySelectorAll('.option');
-
-  nativeWidget.selectedIndex = index;
-  value.innerHTML = optionList[index].innerHTML;
-  highlightOption(select, optionList[index]);
-};
-
-function getIndex(select) {
-  var nativeWidget = select.previousElementSibling;
-
-  return nativeWidget.selectedIndex;
-};
-
-// -------------------- //
-// Liens aux événements //
-// -------------------- //
-
-window.addEventListener("load", function () {
-  var form = document.querySelector('form');
-
-  form.classList.remove("no-widget");
-  form.classList.add("widget");
-});
-
-window.addEventListener('load', function () {
-  var selectList = document.querySelectorAll('.select');
-
-  selectList.forEach(function (select) {
-    var optionList = select.querySelectorAll('.option');
-
-    optionList.forEach(function (option) {
-      option.addEventListener('mouseover', function () {
-        highlightOption(select, option);
-      });
-    });
-
-    select.addEventListener('click', function (event) {
-      toggleOptList(select);
-    });
-
-    select.addEventListener('focus', function (event) {
-      activeSelect(select, selectList);
-    });
-
-    select.addEventListener('blur', function (event) {
-      deactivateSelect(select);
-    });
-  });
-});
-
-window.addEventListener('load', function () {
-  var selectList = document.querySelectorAll('.select');
-
-  selectList.forEach(function (select) {
-    var optionList = select.querySelectorAll('.option'),
-        selectedIndex = getIndex(select);
-
-    select.tabIndex = 0;
-    select.previousElementSibling.tabIndex = -1;
-
-    updateValue(select, selectedIndex);
-
-    optionList.forEach(function (option, index) {
-      option.addEventListener('click', function (event) {
-        updateValue(select, index);
-      });
-    });
-
-    select.addEventListener('keyup', function (event) {
-      var length = optionList.length,
-          index  = getIndex(select);
-
-      if (event.keyCode === 40 && index < length - 1) { index++; }
-      if (event.keyCode === 38 && index > 0) { index--; }
-
-      updateValue(select, index);
-    });
-  });
-});
- -

Résultat

- -

{{ EmbedLiveSample('Change_states') }}

diff --git "a/files/fr/web/guide/html/formulaires/comment_construire_des_widgets_de_formulaires_personnalis\303\251s/example_5/index.html" "b/files/fr/web/guide/html/formulaires/comment_construire_des_widgets_de_formulaires_personnalis\303\251s/example_5/index.html" deleted file mode 100644 index bf1143d186..0000000000 --- "a/files/fr/web/guide/html/formulaires/comment_construire_des_widgets_de_formulaires_personnalis\303\251s/example_5/index.html" +++ /dev/null @@ -1,290 +0,0 @@ ---- -title: Exemple 5 -slug: >- - Web/Guide/HTML/Formulaires/Comment_construire_des_widgets_de_formulaires_personnalisés/Example_5 -tags: - - Formulaires - - HTML -translation_of: Learn/Forms/How_to_build_custom_form_controls/Example_5 ---- -

Voici le dernier exemple expliquant comment construire des widgets de formulaire personnalisés.

- -

Changement d'état

- -

Contenu HTML

- -
<form class="no-widget">
-  <select name="myFruit">
-    <option>Cerise</option>
-    <option>Citron</option>
-    <option>Banane</option>
-    <option>Fraise</option>
-    <option>Pomme</option>
-  </select>
-
-  <div class="select" role="listbox">
-    <span class="value">Cerise</span>
-    <ul class="optList hidden" role="presentation">
-      <li class="option" role="option" aria-selected="true">Cerise</li>
-      <li class="option" role="option">Citron</li>
-      <li class="option" role="option">Banane</li>
-      <li class="option" role="option">Fraise</li>
-      <li class="option" role="option">Pomme</li>
-    </ul>
-  </div>
-</form>
- -

Contenu CSS

- -
.widget select,
-.no-widget .select {
-  position : absolute;
-  left     : -5000em;
-  height   : 0;
-  overflow : hidden;
-}
-
-/* --------------- */
-/* Styles Requis   */
-/* --------------- */
-
-.select {
-  position: relative;
-  display : inline-block;
-}
-
-.select.active,
-.select:focus {
-  box-shadow: 0 0 3px 1px #227755;
-  outline: none;
-}
-
-.select .optList {
-  position: absolute;
-  top     : 100%;
-  left    : 0;
-}
-
-.select .optList.hidden {
-  max-height: 0;
-  visibility: hidden;
-}
-
-/* ------------ */
-/* Styles Chic  */
-/* ------------ */
-
-.select {
-  font-size   : 0.625em; /* 10px */
-  font-family : Verdana, Arial, sans-serif;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  padding : 0.1em 2.5em 0.2em 0.5em; /* 1px 25px 2px 5px */
-  width   : 10em; /* 100px */
-
-  border        : 0.2em solid #000; /* 2px */
-  border-radius : 0.4em; /* 4px */
-
-  box-shadow : 0 0.1em 0.2em rgba(0,0,0,.45); /* 0 1px 2px */
-
-  background : #F0F0F0;
-  background : -webkit-linear-gradient(90deg, #E3E3E3, #fcfcfc 50%, #f0f0f0);
-  background : linear-gradient(0deg, #E3E3E3, #fcfcfc 50%, #f0f0f0);
-}
-
-.select .value {
-  display  : inline-block;
-  width    : 100%;
-  overflow : hidden;
-
-  white-space   : nowrap;
-  text-overflow : ellipsis;
-  vertical-align: top;
-}
-
-.select:after {
-  content : "▼";
-  position: absolute;
-  z-index : 1;
-  height  : 100%;
-  width   : 2em; /* 20px */
-  top     : 0;
-  right   : 0;
-
-  padding-top : .1em;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  text-align : center;
-
-  border-left  : .2em solid #000;
-  border-radius: 0 .1em .1em 0;
-
-  background-color : #000;
-  color : #FFF;
-}
-
-.select .optList {
-  z-index : 2;
-
-  list-style: none;
-  margin : 0;
-  padding: 0;
-
-  background: #f0f0f0;
-  border: .2em solid #000;
-  border-top-width : .1em;
-  border-radius: 0 0 .4em .4em;
-
-  box-shadow: 0 .2em .4em rgba(0,0,0,.4);
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  min-width : 100%;
-  max-height: 10em; /* 100px */
-  overflow-y: auto;
-  overflow-x: hidden;
-}
-
-.select .option {
-  padding: .2em .3em;
-}
-
-.select .highlight {
-  background: #000;
-  color: #FFFFFF;
-}
- -

Contenu JavaScript

- -
// ----------- //
-// UTILITAIRES //
-// ----------- //
-
-NodeList.prototype.forEach = function (callback) {
-  Array.prototype.forEach.call(this, callback);
-}
-
-// ------------------------- //
-// Définitions des fonctions //
-// ------------------------- //
-
-function deactivateSelect(select) {
-  if (!select.classList.contains('active')) return;
-
-  var optList = select.querySelector('.optList');
-
-  optList.classList.add('hidden');
-  select.classList.remove('active');
-}
-
-function activeSelect(select, selectList) {
-  if (select.classList.contains('active')) return;
-
-  selectList.forEach(deactivateSelect);
-  select.classList.add('active');
-};
-
-function toggleOptList(select, show) {
-  var optList = select.querySelector('.optList');
-
-  optList.classList.toggle('hidden');
-}
-
-function highlightOption(select, option) {
-  var optionList = select.querySelectorAll('.option');
-
-  optionList.forEach(function (other) {
-    other.classList.remove('highlight');
-  });
-
-  option.classList.add('highlight');
-};
-
-function updateValue(select, index) {
-  var nativeWidget = select.previousElementSibling;
-  var value = select.querySelector('.value');
-  var optionList = select.querySelectorAll('.option');
-
-  optionList.forEach(function (other) {
-    other.setAttribute('aria-selected', 'false');
-  });
-
-  optionList[index].setAttribute('aria-selected', 'true');
-
-  nativeWidget.selectedIndex = index;
-  value.innerHTML = optionList[index].innerHTML;
-  highlightOption(select, optionList[index]);
-};
-
-function getIndex(select) {
-  var nativeWidget = select.previousElementSibling;
-
-  return nativeWidget.selectedIndex;
-};
-
-// -------------------- //
-// Liens aux événements //
-// -------------------- //
-
-window.addEventListener("load", function () {
-  var form = document.querySelector('form');
-
-  form.classList.remove("no-widget");
-  form.classList.add("widget");
-});
-
-window.addEventListener('load', function () {
-  var selectList = document.querySelectorAll('.select');
-
-  selectList.forEach(function (select) {
-    var optionList = select.querySelectorAll('.option'),
-        selectedIndex = getIndex(select);
-
-    select.tabIndex = 0;
-    select.previousElementSibling.tabIndex = -1;
-
-    updateValue(select, selectedIndex);
-
-    optionList.forEach(function (option, index) {
-      option.addEventListener('mouseover', function () {
-        highlightOption(select, option);
-      });
-
-      option.addEventListener('click', function (event) {
-        updateValue(select, index);
-      });
-    });
-
-    select.addEventListener('click', function (event) {
-      toggleOptList(select);
-    });
-
-    select.addEventListener('focus', function (event) {
-      activeSelect(select, selectList);
-    });
-
-    select.addEventListener('blur', function (event) {
-      deactivateSelect(select);
-    });
-
-    select.addEventListener('keyup', function (event) {
-      var length = optionList.length,
-          index  = getIndex(select);
-
-      if (event.keyCode === 40 && index < length - 1) { index++; }
-      if (event.keyCode === 38 && index > 0) { index--; }
-
-      updateValue(select, index);
-    });
-  });
-});
-
- -

Résultat

- -

{{ EmbedLiveSample('Change_states') }}

diff --git "a/files/fr/web/guide/html/formulaires/comment_construire_des_widgets_de_formulaires_personnalis\303\251s/exemple_1/index.html" "b/files/fr/web/guide/html/formulaires/comment_construire_des_widgets_de_formulaires_personnalis\303\251s/exemple_1/index.html" deleted file mode 100644 index 045f631079..0000000000 --- "a/files/fr/web/guide/html/formulaires/comment_construire_des_widgets_de_formulaires_personnalis\303\251s/exemple_1/index.html" +++ /dev/null @@ -1,420 +0,0 @@ ---- -title: Exemple 1 -slug: >- - Web/Guide/HTML/Formulaires/Comment_construire_des_widgets_de_formulaires_personnalisés/Exemple_1 -tags: - - Formulaires - - Guide - - HTML -translation_of: Learn/Forms/How_to_build_custom_form_controls/Example_1 ---- -

C'est le premier exemple de code qui explique comment construire un widget de formulaire personnalisé.

- -

État initial

- -

HTML

- -
<div class="select">
-  <span class="value">Cerise</span>
-  <ul class="optList hidden">
-    <li class="option">Cerise</li>
-    <li class="option">Citron</li>
-    <li class="option">Banane</li>
-    <li class="option">Fraise</li>
-    <li class="option">Pomme</li>
-  </ul>
-</div>
- -

CSS

- -
/* --------------- */
-/* Styles Requis   */
-/* --------------- */
-
-.select {
-  position: relative;
-  display : inline-block;
-}
-
-.select.active,
-.select:focus {
-  box-shadow: 0 0 3px 1px #227755;
-  outline: none;
-}
-
-.select .optList {
-  position: absolute;
-  top     : 100%;
-  left    : 0;
-}
-
-.select .optList.hidden {
-  max-height: 0;
-  visibility: hidden;
-}
-
-/* ------------ */
-/* Style  Chic  */
-/* ------------ */
-
-.select {
-  font-size   : 0.625em; /* 10px */
-  font-family : Verdana, Arial, sans-serif;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  padding : 0.1em 2.5em 0.2em 0.5em; /* 1px 25px 2px 5px */
-  width   : 10em; /* 100px */
-
-  border        : 0.2em solid #000; /* 2px */
-  border-radius : 0.4em; /* 4px */
-
-  box-shadow : 0 0.1em 0.2em rgba(0,0,0,.45); /* 0 1px 2px */
-
-  background : #F0F0F0;
-  background : -webkit-linear-gradient(90deg, #E3E3E3, #fcfcfc 50%, #f0f0f0);
-  background : linear-gradient(0deg, #E3E3E3, #fcfcfc 50%, #f0f0f0);
-}
-
-.select .value {
-  display  : inline-block;
-  width    : 100%;
-  overflow : hidden;
-
-  white-space   : nowrap;
-  text-overflow : ellipsis;
-  vertical-align: top;
-}
-
-.select:after {
-  content : "▼";
-  position: absolute;
-  z-index : 1;
-  height  : 100%;
-  width   : 2em; /* 20px */
-  top     : 0;
-  right   : 0;
-
-  padding-top : .1em;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  text-align : center;
-
-  border-left  : .2em solid #000;
-  border-radius: 0 .1em .1em 0;
-
-  background-color : #000;
-  color : #FFF;
-}
-
-.select .optList {
-  z-index : 2;
-
-  list-style: none;
-  margin : 0;
-  padding: 0;
-
-  background: #f0f0f0;
-  border: .2em solid #000;
-  border-top-width : .1em;
-  border-radius: 0 0 .4em .4em;
-
-  box-shadow: 0 .2em .4em rgba(0,0,0,.4);
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  min-width : 100%;
-  max-height: 10em; /* 100px */
-  overflow-y: auto;
-  overflow-x: hidden;
-}
-
-.select .option {
-  padding: .2em .3em;
-}
-
-.select .highlight {
-  background: #000;
-  color: #FFFFFF;
-}
-
- -

Resultat pour l'état initial

- -
{{ EmbedLiveSample("Basic_state", 120, 130) }}
- -

État actif

- -

HTML

- -
<div class="select active">
-  <span class="value">Cerise</span>
-  <ul class="optList hidden">
-    <li class="option">Cerise</li>
-    <li class="option">Citron</li>
-    <li class="option">Banane</li>
-    <li class="option">Fraise</li>
-    <li class="option">Pomme</li>
-  </ul>
-</div>
- -

CSS

- -
/* --------------- */
-/* Styles Requis   */
-/* --------------- */
-
-.select {
-  position: relative;
-  display : inline-block;
-}
-
-.select.active,
-.select:focus {
-  box-shadow: 0 0 3px 1px #227755;
-  outline: none;
-}
-
-.select .optList {
-  position: absolute;
-  top     : 100%;
-  left    : 0;
-}
-
-.select .optList.hidden {
-  max-height: 0;
-  visibility: hidden;
-}
-
-/* ------------ */
-/* Style  Chic  */
-/* ------------ */
-
-.select {
-  font-size   : 0.625em; /* 10px */
-  font-family : Verdana, Arial, sans-serif;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  padding : 0.1em 2.5em 0.2em 0.5em; /* 1px 25px 2px 5px */
-  width   : 10em; /* 100px */
-
-  border        : 0.2em solid #000; /* 2px */
-  border-radius : 0.4em; /* 4px */
-
-  box-shadow : 0 0.1em 0.2em rgba(0,0,0,.45); /* 0 1px 2px */
-
-  background : #F0F0F0;
-  background : -webkit-linear-gradient(90deg, #E3E3E3, #fcfcfc 50%, #f0f0f0);
-  background : linear-gradient(0deg, #E3E3E3, #fcfcfc 50%, #f0f0f0);
-}
-
-.select .value {
-  display  : inline-block;
-  width    : 100%;
-  overflow : hidden;
-
-  white-space   : nowrap;
-  text-overflow : ellipsis;
-  vertical-align: top;
-}
-
-.select:after {
-  content : "▼";
-  position: absolute;
-  z-index : 1;
-  height  : 100%;
-  width   : 2em; /* 20px */
-  top     : 0;
-  right   : 0;
-
-  padding-top : .1em;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  text-align : center;
-
-  border-left  : .2em solid #000;
-  border-radius: 0 .1em .1em 0;
-
-  background-color : #000;
-  color : #FFF;
-}
-
-.select .optList {
-  z-index : 2;
-
-  list-style: none;
-  margin : 0;
-  padding: 0;
-
-  background: #f0f0f0;
-  border: .2em solid #000;
-  border-top-width : .1em;
-  border-radius: 0 0 .4em .4em;
-
-  box-shadow: 0 .2em .4em rgba(0,0,0,.4);
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  min-width : 100%;
-  max-height: 10em; /* 100px */
-  overflow-y: auto;
-  overflow-x: hidden;
-}
-
-.select .option {
-  padding: .2em .3em;
-}
-
-.select .highlight {
-  background: #000;
-  color: #FFFFFF;
-}
- -

Résultat pour état actif

- -
{{ EmbedLiveSample("Active_state", 120, 130) }}
- -

État ouvert

- -

HTML

- -
<div class="select active">
-  <span class="value">Cerise</span>
-  <ul class="optList">
-    <li class="option highlight">Cerise</li>
-    <li class="option">Citron</li>
-    <li class="option">Banane</li>
-    <li class="option">Fraise</li>
-    <li class="option">Pomme</li>
-  </ul>
-</div>
- -

CSS

- -
/* --------------- */
-/* Styles Requis   */
-/* --------------- */
-
-.select {
-  position: relative;
-  display : inline-block;
-}
-
-.select.active,
-.select:focus {
-  box-shadow: 0 0 3px 1px #227755;
-  outline: none;
-}
-
-.select .optList {
-  position: absolute;
-  top     : 100%;
-  left    : 0;
-}
-
-.select .optList.hidden {
-  max-height: 0;
-  visibility: hidden;
-}
-
-/* ------------ */
-/* Style  Chic  */
-/* ------------ */
-
-.select {
-  font-size   : 0.625em; /* 10px */
-  font-family : Verdana, Arial, sans-serif;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  padding : 0.1em 2.5em 0.2em 0.5em; /* 1px 25px 2px 5px */
-  width   : 10em; /* 100px */
-
-  border        : 0.2em solid #000; /* 2px */
-  border-radius : 0.4em; /* 4px */
-
-  box-shadow : 0 0.1em 0.2em rgba(0, 0, 0, .45); /* 0 1px 2px */
-
-  background : #F0F0F0;
-  background : -webkit-linear-gradient(90deg, #E3E3E3, #fcfcfc 50%, #f0f0f0);
-  background : linear-gradient(0deg, #E3E3E3, #fcfcfc 50%, #f0f0f0);
-}
-
-.select .value {
-  display  : inline-block;
-  width    : 100%;
-  overflow : hidden;
-
-  white-space   : nowrap;
-  text-overflow : ellipsis;
-  vertical-align: top;
-}
-
-.select:after {
-  content : "▼";
-  position: absolute;
-  z-index : 1;
-  height  : 100%;
-  width   : 2em; /* 20px */
-  top     : 0;
-  right   : 0;
-
-  padding-top : .1em;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  text-align : center;
-
-  border-left  : .2em solid #000;
-  border-radius: 0 .1em .1em 0;
-
-  background-color : #000;
-  color : #FFF;
-}
-
-.select .optList {
-  z-index : 2;
-
-  list-style: none;
-  margin : 0;
-  padding: 0;
-
-  background: #f0f0f0;
-  border: .2em solid #000;
-  border-top-width : .1em;
-  border-radius: 0 0 .4em .4em;
-
-  box-shadow: 0 .2em .4em rgba(0,0,0,.4);
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  min-width : 100%;
-  max-height: 10em; /* 100px */
-  overflow-y: auto;
-  overflow-x: hidden;
-}
-
-.select .option {
-  padding: .2em .3em;
-}
-
-.select .highlight {
-  background: #000;
-  color: #FFF;
-}
- -

Resultat pour état ouvert

- -
{{ EmbedLiveSample("Open_state", 120, 130) }}
diff --git "a/files/fr/web/guide/html/formulaires/comment_construire_des_widgets_de_formulaires_personnalis\303\251s/exemple_2/index.html" "b/files/fr/web/guide/html/formulaires/comment_construire_des_widgets_de_formulaires_personnalis\303\251s/exemple_2/index.html" deleted file mode 100644 index dfb0eb3b6a..0000000000 --- "a/files/fr/web/guide/html/formulaires/comment_construire_des_widgets_de_formulaires_personnalis\303\251s/exemple_2/index.html" +++ /dev/null @@ -1,215 +0,0 @@ ---- -title: Exemple 2 -slug: >- - Web/Guide/HTML/Formulaires/Comment_construire_des_widgets_de_formulaires_personnalisés/Exemple_2 -tags: - - Formulaires - - HTML -translation_of: Learn/Forms/How_to_build_custom_form_controls/Example_2 ---- -

Ceci est le deuxième exemple expliquant comment construire un formulaire personnalisé.

- -

JS

- -

HTML Content

- -
<form class="no-widget">
-  <select name="myFruit">
-      <option>Cerise</option>
-      <option>Citron</option>
-      <option>Banane</option>
-      <option>Fraise</option>
-      <option>Pomme</option>
-  </select>
-
-  <div class="select">
-    <span class="value">Cerise</span>
-    <ul class="optList hidden">
-      <li class="option">Cerise</li>
-      <li class="option">Citron</li>
-      <li class="option">Banane</li>
-      <li class="option">Fraise</li>
-      <li class="option">Pomme</li>
-    </ul>
-  </div>
-<form>
-
- -

CSS Content

- -
.widget select,
-.no-widget .select {
-  position : absolute;
-  left     : -5000em;
-  height   : 0;
-  overflow : hidden;
-}
-
-/* --------------- */
-/* Styles requis   */
-/* --------------- */
-
-.select {
-  position: relative;
-  display : inline-block;
-}
-
-.select.active,
-.select:focus {
-  box-shadow: 0 0 3px 1px #227755;
-  outline: none;
-}
-
-.select .optList {
-  position: absolute;
-  top     : 100%;
-  left    : 0;
-}
-
-.select .optList.hidden {
-  max-height: 0;
-  visibility: hidden;
-}
-
-/* ------------ */
-/* Styles décor */
-/* ------------ */
-
-.select {
-  font-size   : 0.625em; /* 10px */
-  font-family : Verdana, Arial, sans-serif;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  padding : 0.1em 2.5em 0.2em 0.5em; /* 1px 25px 2px 5px */
-  width   : 10em; /* 100px */
-
-  border        : 0.2em solid #000; /* 2px */
-  border-radius : 0.4em; /* 4px */
-
-  box-shadow : 0 0.1em 0.2em rgba(0,0,0,.45); /* 0 1px 2px */
-
-  background : #F0F0F0;
-  background : -webkit-linear-gradient(90deg, #E3E3E3, #fcfcfc 50%, #f0f0f0);
-  background : linear-gradient(0deg, #E3E3E3, #fcfcfc 50%, #f0f0f0);
-}
-
-.select .value {
-  display  : inline-block;
-  width    : 100%;
-  overflow : hidden;
-
-  white-space   : nowrap;
-  text-overflow : ellipsis;
-  vertical-align: top;
-}
-
-.select:after {
-  content : "▼";
-  position: absolute;
-  z-index : 1;
-  height  : 100%;
-  width   : 2em; /* 20px */
-  top     : 0;
-  right   : 0;
-
-  padding-top : .1em;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  text-align : center;
-
-  border-left  : .2em solid #000;
-  border-radius: 0 .1em .1em 0;
-
-  background-color : #000;
-  color : #FFF;
-}
-
-.select .optList {
-  z-index : 2;
-
-  list-style: none;
-  margin : 0;
-  padding: 0;
-
-  background: #f0f0f0;
-  border: .2em solid #000;
-  border-top-width : .1em;
-  border-radius: 0 0 .4em .4em;
-
-  box-shadow: 0 .2em .4em rgba(0,0,0,.4);
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  min-width : 100%;
-  max-height: 10em; /* 100px */
-  overflow-y: auto;
-  overflow-x: hidden;
-}
-
-.select .option {
-  padding: .2em .3em;
-}
-
-.select .highlight {
-  background: #000;
-  color: #FFFFFF;
-}
- -

Contenu JavaScript

- -
window.addEventListener("load", function () {
-  var form = document.querySelector('form');
-
-  form.classList.remove("no-widget");
-  form.classList.add("widget");
-});
- -

Résultat avec JavaScript

- -

{{ EmbedLiveSample('JS', 120, 130) }}

- -

Sans JS

- -

HTML Content

- -
<form class="no-widget">
-  <select name="myFruit">
-      <option>Cerise</option>
-      <option>Citron</option>
-      <option>Banane</option>
-      <option>Fraise</option>
-      <option>Pomme</option>
-  </select>
-
-  <div class="select">
-    <span class="value">Cerise</span>
-    <ul class="optList hidden">
-      <li class="option">Cerise</li>
-      <li class="option">Citron</li>
-      <li class="option">Banane</li>
-      <li class="option">Fraise</li>
-      <li class="option">Pomme</li>
-    </ul>
-  </div>
-<form>
- -

CSS Content

- -
.widget select,
-.no-widget .select {
-  position : absolute;
-  left     : -5000em;
-  height   : 0;
-  overflow : hidden;
-}
- -

Result for No JS

- -

{{ EmbedLiveSample('No_JS', 120, 130) }}

- -

 

diff --git "a/files/fr/web/guide/html/formulaires/comment_construire_des_widgets_de_formulaires_personnalis\303\251s/index.html" "b/files/fr/web/guide/html/formulaires/comment_construire_des_widgets_de_formulaires_personnalis\303\251s/index.html" deleted file mode 100644 index 4173ff9f9c..0000000000 --- "a/files/fr/web/guide/html/formulaires/comment_construire_des_widgets_de_formulaires_personnalis\303\251s/index.html" +++ /dev/null @@ -1,837 +0,0 @@ ---- -title: Comment construire des widgets de formulaires personnalisés -slug: >- - Web/Guide/HTML/Formulaires/Comment_construire_des_widgets_de_formulaires_personnalisés -tags: - - Avancé - - Exemple - - Formulaires - - Guide - - HTML - - Web -translation_of: Learn/Forms/How_to_build_custom_form_controls ---- -
{{LearnSidebar}}{{PreviousMenuNext("Web/Guide/HTML/Formulaires/Validation_donnees_formulaire", "Web/Guide/HTML/Formulaires/Sending_forms_through_JavaScript", "Web/Guide/HTML/Formulaires")}}
- -

Dans de nombreux cas les widgets de formulaires HTML disponibles ne suffisent pas. Si vous voulez composer certains widgets dans un style avancé tels que l'élément {{HTMLElement("select")}} ou si vous voulez leur donner des comportements personnalisés, vous n'avez pas d'autre choix que de créer vos propres widgets.

- -

Dans cet article, nous verrons comment construire un tel widget. Pour cela, nous allons travailler avec un exemple : reconstruire l'élément {{HTMLElement("select")}}.

- -
-

Note : Nous nous resterons centrés sur la construction des widgets, et non sur la façon de rendre le code générique et réutilisable ; cela impliquerait une manipulation de code JavaScript et de DOM dans un contexte inconnu, et nous sortirions de la portée de cet article.

-
- -

Conception, structure et sémantique

- -

Avant de créer un widget personnalisé, il faut commencer par déterminer exactement ce que vous voulez. Vous gagnerez ainsi un temps précieux. En particulier, il est important de définir clairement tous les états de votre widget. Pour ce faire, il est bon de commencer par un widget existant dont les états et le comportement sont bien connus, afin que vous puissiez simplement les imiter autant que possible.

- -

Dans notre exemple, nous allons reconstruire l'élément {{HTMLElement("select")}}}. Voici le résultat que nous voulons atteindre :

- -

The three states of a select box

- -

Cette capture d'écran montre les trois états principaux du widget : l'état normal (à gauche), l'état actif (au milieu) et l'état ouvert (à droite).

- -

En termes de comportement, nous voulons que notre widget soit utilisable aussi bien avec une souris qu'avec un clavier, comme n'importe quel widget natif. Commençons par définir comment le widget atteint chaque état :

- -
-
Le widget est dans son état normal :
-
-
    -
  • la page se charge
  • -
  • le widget était actif et l'utilisateur a cliqué quelque part en dehors du widget
  • -
  • le widget était actif et l'utilisateur a déplacé le focus sur un autre avec le clavier
  • -
-
-
- -

 

- -
-
-
-

Note : Déplacer le focus dans la page entre les divers widgets se fait généralement en appuyant sur la touche de tabulation, mais ce n'est pas la norme partout. Par exemple, circuler parmi les liens sur une page se fait dans Safari par défaut en utilisant la combinaison Option+Tab.

-
-
-
Le widget est sans son état actif :
-
-
    -
  • l'utilisateur clique sur lui
  • -
  • l'utilisateur presse la touche Tabulation et obtient le focus
  • -
  • le widget était dans l'état ouvert et l'utilisateur a cliqué dessus.
  • -
-
-
Le widget est dans un état ouvert :
-
-
    -
  • le widget est dans un état autre que ouvert et l'utilisateur clique dessus.
  • -
-
-
- -

Maintenant que nous savons comment changer les états du widget, il est important de définir comment changer la valeur du widget :

- -
-
La valeur change quand :
-
-
    -
  • l'utilisateur clique sur une option quand le widget est dans l'état ouvert
  • -
  • l'utilisateur presse la touche ou quand le widget est dans l'état actif
  • -
-
-
- -

Enfin, définissons comment les options du widget doivent se comporter :

- - - -

Pour les besoins de notre exemple, nous nous arrêterons là ; cependant, si vous êtes un lecteur attentif, vous remarquerez que certains comportements ne sont pas précisés. Par exemple, que pensez-vous qu'il se passe si l'utilisateur appuie sur la touche Tabulation alors que le widget est dans l'état ouvert ? La réponse est… rien. D'accord, le bon comportement semble évident mais le fait est que, comme il n'est pas défini dans nos spécifications, il est très facile de fermer les yeux sur ce comportement. Dans un travail collaboratif, lorsque les personnes concevant le comportement du widget sont différentes de celles qui le mettent en œuvre, cette démarche se vérifiera.

- -

Autre exemple amusant : que se passera-t-il si l'utilisateur presse les touches ou alors que le widget est à l'état ouvert ? Ici, c'est un peu plus délicat. Si vous considérez que l'état actif et l'état ouvert sont totalement différents, la réponse est encore une fois « rien ne se produira » parce que nous n'avons pas défini d'interactions clavier pour l'état ouvert. D'autre part, si vous considérez que l'état actif et l'état ouvert coïncident, la valeur peut changer mais l'option ne sera certainement pas mise en valeur en conséquence, encore une fois parce que nous n'avons pas défini d'interactions clavier sur les options lorsque le widget est dans son état ouvert (nous avons seulement défini ce qui doit se passer lorsque le widget est ouvert, mais rien après).

- -

Dans notre exemple, les spécifications manquantes sont évidentes et nous les traiterons, mais cela peut devenir un problème réel sur de nouveaux widgets exotiques, pour lesquels personne n'a la moindre idée de ce qu'est le bon comportement. Il est donc toujours bon de passer du temps à l'étape conception, car si vous définissez pauvrement le comportement, ou si vous oubliez de le définir, il sera très difficile de le redéfinir une fois les utilisateurs habitués. Si vous avez des doutes, demandez l'avis des autres, et si vous avez le budget pour cela, n'hésitez pas à faire des tests utilisateur. Ce processus est appelé UX Design (User eXperience). Si vous voulez en savoir plus sur ce sujet, vous devriez consulter les ressources utiles suivantes :

- - - -
-

Note : De plus, dans la plupart des systèmes, il y a moyen d'ouvrir l'élément {{HTMLElement("select")}} pour voir tous les choix disponibles (c'est la même chose que de cliquer sur l'élément {{HTMLElement("select")}} avec une souris). Cela se fait avec Alt+ sous Windows et n'a pas été implémenté dans notre exemple - mais il serait facile de le faire, car le mécanisme a déjà été implémenté pour l'événement click.

-
- -

Definition de la structure HTML et de la sémantique

- -

Maintenant que la fonctionnalité de base du widget a été décidée, il est temps de commencer à construire notre widget. La première étape consiste à définir sa structure HTML et à lui donner une sémantique de base. Voici ce dont nous avons besoin pour reconstruire un élément <select> :

- -
<!-- Ceci est notre conteneur principal pour le widget. L'attribut tabindex
-     est ce qui permet à l'utilisateur de mettre le focus sur le widget.
-     Nous verrons plus loin que c'est mieux de le faire avec JavaScript. -->
-<div class="select" tabindex="0">
-
-  <!-- Ce containeur sera utilisé pour afficher la valeur courante du widget -->
-  <span class="value">Cerise</span>
-
-  <!-- Ce conteneur contiendra toutes les options disponibles pour le widget.
-       Comme c'est une liste, il y sens à utiliser l'élément ul. -->
-  <ul class="optList">
-    <!-- Chaque option ne contient que la valeur à afficher, Nous verrons plus loin
-         comment gérer la valeur réelle qui sera envoyée avec les données du formulaire -->
-    <li class="option">Cerise</li>
-    <li class="option">Citron</li>
-    <li class="option">Banane</li>
-    <li class="option">Fraise</li>
-    <li class="option">Pomme</li>
-  </ul>
-
-</div>
- -

Notez l'utilisation de noms de classes qui identifient chaque partie pertinente indépendamment des éléments HTML sous-jacents utilisés. Ceci est important pour s'assurer que nous n'allons pas lier les CSS et JavaScript à une structure HTML forte, pour pouvoir faire des changements d'implémentation plus tard sans casser le code qui utilise le widget. Par exemple, si vous souhaitez implémenter l'équivalent de l'élément {{HTMLElement("optgroup")}}.

- -

Composition et ressenti avec les CSS

- -

Maintenant que nous avons une structure, nous pouvons commencer à concevoir notre widget. Le but de construire un widget personnalisé est de pouvoir lui donner exactement le style que nous voulons. Pour cela, nous allons partager le travail sur les CSS en deux parties : la première relative aux règles des CSS absolument nécessaires pour que notre widget se comporte comme un élément {{HTMLElement("select")}}, la seconde constituée des décorations utilisés lui donnant un aspect personnalisé.

- -

Styles obligatoires

- -

Les styles obligatoires sont ceux nécessaires à la gestion des trois états du widget.

- -
.select {
-  /* Celui-ci crée un contexte de positionnement pour la liste des options */
-  position: relative;
-
-  /* Celui-ci fait que le widget devient partie du flot textuel
-     et devient en même temps dimensionnable */
-  display : inline-block;
-}
- -

Nous avons besoin d'une classe active supplémentaire pour définir l'apparence du widget dans son état actif. Comme le widget peut recevoir le focus, nous doublons ce style personnalisé avec la pseudo-classe {{cssxref(":focus")}} afin d'être sûrs qu'elles se comporteront de la même manière.

- -
.select.active,
-.select:focus {
-  outline: none;
-
-  /* Cette propriété box-shadow n'est pas requise à proprement parler, mais il est
-     important de s'assurer que l'état actif soit visible, c'est pourquoi nous
-     utilisons une valeur par défaut. Vous êtes libre de la modifier. */
-  box-shadow: 0 0 3px 1px #227755;
-}
- -

Passons maintenant à la liste des options :

- -
/* Le sélecteur .select ici est du sucre syntaxique (le fait de donner au
-   programmeur des possibilités d'écriture plus succinctes ou plus proches
-   d'une notation usuelle) pour s'assurer que les classes que nous définissons
-   sont les seules à l'intérieur du widget. */
-.select .optList {
-  /* Ceci assure que la liste des options sera affichée au dessous de la valeur
-     et en dehors du flot HTML */
-  position : absolute;
-  top      : 100%;
-  left     : 0;
-}
- -

Nous avons besoin d'une classe supplémentaire pour gérer la liste d'options cachée. Ceci est nécessaire pour la gestion des différences entre état actif et état ouvert qui ne correspondent pas exactement.

- -
.select .optList.hidden {
-  /* Ceci est un moyen simple pour cacher la liste tout en conservant l'accessibilité,
-     nous reparlerons plus loin d'accessibilité */
-  max-height: 0;
-  visibility: hidden;
-}
- -

Embellissements

- -

Maintenant que nous avons mis en place les fonctionnalités de base, le divertissement peut commencer. Ce qui suit n'est qu'un exemple de ce qui est possible, et correspondra à la capture d'écran au début de cet article. Cependant, vous devriez vous sentir libre d'expérimenter et de voir ce que cela donne.

- -
.select {
-  /* Toutes les tailles seront exprimées en valeurs em (lettre M, étalon
-     du cadratin : cadre dans lequel sont dessinées toutes les lettres d'une
-     police de caractères) pour des raisons d'accessibilité (pour être sûrs
-     que le widget reste redimensionnable si l'utilisateur utilise le zoom
-     du navigateur en mode texte exclusif). Les calculs sont faits en
-     supposant que 1em==16px qui est la valeur par défaut dans la majorité
-     des navigateurs. Si vous êtes perdus avec les conversions entre px et
-     em, essayez http://riddle.pl/emcalc/ */
-  font-size   : 0.625em; /* ceci (10px) est le nouveau contexte de taille de
-     police pour la valeur em dans ce contexte. */
-  font-family : Verdana, Arial, sans-serif;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  /* Nous avons besoin de plus d'espace pour la flèche vers le bas que nous
-     allons ajouter. */
-  padding : .1em 2.5em .2em .5em; /* 1px 25px 2px 5px */
-  width   : 10em; /* 100px */
-
-  border        : .2em solid #000; /* 2px */
-  border-radius : .4em; /* 4px */
-  box-shadow    : 0 .1em .2em rgba(0,0,0,.45); /* 0 1px 2px */
-
-  /* La première déclaration concerne les navigateurs qui ne prennent pas en
-     charge les gradients linéaires. La deuxième déclaration est parce que
-     les navigateurs basés sur WebKit ne l'ont pas encore préfixé. Si vous
-     souhaitez prendre en charge les anciens navigateurs, essayez
-     http://www.colorzilla.com/gradient-editor/ */
-  background : #F0F0F0;
-  background : -webkit-linear-gradient(90deg, #E3E3E3, #fcfcfc 50%, #f0f0f0);
-  background : linear-gradient(0deg, #E3E3E3, #fcfcfc 50%, #f0f0f0);
-}
-
-.select .value {
-  /* Comme la valeur peut être plus large que le widget, nous devons nous
-     assurer qu'elle ne changera pas la largeur du widget. */
-  display  : inline-block;
-  width    : 100%;
-  overflow : hidden;
-
-  vertical-align: top;
-
-  /* Et si le contenu déborde, c'est mieux d'avoir une jolie abreviation. */
-  white-space  : nowrap;
-  text-overflow: ellipsis;
-
- -

Nous n'avons pas besoin d'un élément supplémentaire pour concevoir la flèche vers le bas ; à la place, nous utilisons le pseudo-élément {{cssxref(":after:after")}}. Cependant, elle pourrait également être mise en œuvre à l'aide d'une simple image de fond sur la classe select.

- -
.select:after {
-  content : "▼"; /* Nous utilisons le caractère unicode U+25BC;
-                    voir http://www.utf8-chartable.de */
-  position: absolute;
-  z-index : 1; /* Il est important d'empêcher la flèche de chevaucher la liste des options */
-  top     : 0;
-  right   : 0;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  height  : 100%;
-  width   : 2em;  /* 20px */
-  padding-top : .1em; /* 1px */
-
-  border-left  : .2em solid #000; /* 2px */
-  border-radius: 0 .1em .1em 0;  /* 0 1px 1px 0 */
-
-  background-color : #000;
-  color : #FFF;
-  text-align : center;
-}
- -

Maintenant, composons la décoration de la liste des options :

- -
.select .optList {
-  z-index : 2; /* Nous disons explicitement que la liste des options doit toujours passer sur la flèche */
-
-  /* cela réinitialiser le style par défaut de l'élément ul */
-  list-style: none;
-  margin : 0;
-  padding: 0;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  /* Cela nous assure que même si les valeurs sont plus petites que le widget,
-     la liste des options sera aussi large que le widget lui‑même */
-  min-width : 100%;
-
-  /* Dans le cas où la liste est trop longue, son contenu débordera verticalement
-     (ce qui ajoutera une barre de déroulement automatiquement) mais jamais horizontalement
-     (car nous n'avons jamais défini de largeur, la liste ajustera automatiquement sa largeur
-     Si ce n'est pas possible, le contenu sera tronqué) */
-  max-height: 10em; /* 100px */
-  overflow-y: auto;
-  overflow-x: hidden;
-
-  border: .2em solid #000; /* 2px */
-  border-top-width : .1em; /* 1px */
-  border-radius: 0 0 .4em .4em; /* 0 0 4px 4px */
-
-  box-shadow: 0 .2em .4em rgba(0,0,0,.4); /* 0 2px 4px */
-  background: #f0f0f0;
-}
- -

Pour les options, nous devons ajouter une classe highlight pour pouvoir identifier la valeur que l'utilisateur choisira (ou a choisi).

- -
.select .option {
-  padding: .2em .3em; /* 2px 3px */
-}
-
-.select .highlight {
-  background: #000;
-  color: #FFFFFF;
-}
- -

Donc, voici le résultat avec les trois états :

- - - - - - - - - - - - - - - - - - - -
Basic stateActive stateOpen state
{{EmbedLiveSample('Basic_state',120,130, "", "Web/Guide/HTML/Formulaires/Comment_construire_des_widgets_de_formulaires_personnalisés/Exemple_1")}}{{EmbedLiveSample("Active_state",120,130, "", "Web/Guide/HTML/Formulaires/Comment_construire_des_widgets_de_formulaires_personnalisés/Exemple_1")}}{{EmbedLiveSample("Open_state",120,130, "", "Web/Guide/HTML/Formulaires/Comment_construire_des_widgets_de_formulaires_personnalisés/Exemple_1")}}
Check out the source code
- -

Donnez vie à votre widget avec JavaScript

- -

Maintenant que le design et la structure sont prêts, nous pouvons écrire le code JAvaScript pour que le widget fonctionne vraiment.

- -
-

Avertissement : Le code qui suit a été conçu à des fins éducatives et ne doit pas être utilisé tel quel. Entre autres choses, comme nous le verrons, il n'est pas à l'épreuve du temps et ne fonctionnera pas sur des navigateurs historiques. Il comporte également des parties redondantes. Elles devraient être optimisées pour du code de production.

-
- -
-

Note : Créer des widgets réutilisables peut se révéler un peu délicat. L'ébauche de la norme « W3C Web Component » apporte des réponses à cette question particulière. Le projet X-Tag est un essai de mise en œuvre de cette spécification ; nous vous encourageons à y jeter un coup d'œil.

-
- -

Pourquoi ne fonctionne-t-il pas ?

- -

 

- -

Avant de commencer, il est important de se rappeler quelque chose de très important à propos de JavaScript : dans un navigateur, c'est une technique peu fiable. Lorsque vous créez des widgets personnalisés, vous êtes obligé de faire appel à JavaScript parce que c'est un fil nécessaire pour tout lier ensemble. Cependant, il existe de nombreux cas dans lesquels JavaScript n'est pas capable de s'exécuter dans le navigateur :

- - - -

 

- -

 

- -

En raison de ces aléas, il est vraiment important de considérer avec sérieux ce qui se passe si JavaScript ne fonctionne pas. Traiter en détail cette question est hors de la portée de cet article parce qu'elle est étroitement liée à la façon dont vous voulez rendre votre script générique et réutilisable, mais nous prendrons en considération les bases de ce sujet dans notre exemple.

- -

Ainsi, si notre code JavaScript ne s'exécute pas, nous reviendrons à l'affichage d'un élément  {{HTMLElement("select")}} standard. Pour y parvenir, nous avons besoin de deux choses.

- -

Tout d'abord, nous devons ajouter un élément {{HTMLElement("select")}} régulier avant chaque utilisation de notre widget personnalisé. Ceci est également nécessaire pour pouvoir envoyer les données de notre widget personnalisé avec le reste de nos données du formulaire ; nous reviendrons sur ce point plus tard.

- -

 

- -
<body class="no-widget">
-  <form>
-    <select name="myFruit">
-      <option>Cerise</option>
-      <option>Citron</option>
-      <option>Banane</option>
-      <option>Fraise</option>
-      <option>Pomme</option>
-    </select>
-
-    <div class="select">
-      <span class="value">Cerise</span>
-      <ul class="optList hidden">
-        <li class="option">Cerise</li>
-        <li class="option">Citron</li>
-        <li class="option">Banane</li>
-        <li class="option">Fraise</li>
-        <li class="option">Pomme</li>
-      </ul>
-    </div>
-  </form>
-
-</body>
- -

 

- -

Deuxièmement, nous avons besoin de deux nouvelles classes pour nous permettre de cacher l'élément qui ne sert pas (c'est-à-dire l'élément{{HTMLElement("select")}} « réel »  si notre script ne fonctionne pas, ou le widget personnalisé s'il fonctionne). Notez que par défaut, le code HTML cache le widget personnalisé.

- -
.widget select,
-.no-widget .select {
-  /* Ce sélecteur CSS dit fondamentalement :
-     - soit la classe body est "widget" et donc l'élément {{HTMLElement("select")}} réel sera caché
-     - soit la classe body n'a pas changé, elle est toujours "no-widget",
-       et donc les éléments, dont la classe est « select », doivent être cachés */
-  position : absolute;
-  left     : -5000em;
-  height   : 0;
-  overflow : hidden;
-}
- -

 

- -

Maintenant nous avons juste besoin d'un commutateur JavaScript pour déterminer si le script est en cours d'exécution ou non. Cette bascule  est très simple : si au moment du chargement de la page notre script est en cours d'exécution, il supprime la classe no-widget et ajoute la classe widget, échangeant ainsi la visibilité de l'élément {{HTMLElement("select")}} et du widget personnalisé.

- -

 

- -

 

- -
window.addEventListener("load", function () {
-  document.body.classList.remove("no-widget");
-  document.body.classList.add("widget");
-});
- - - - - - - - - - - - - - - - - -
Sans JavaScriptAvec JavaScript
{{EmbedLiveSample("No_JS",120,130, "", "Web/Guide/HTML/Formulaires/Comment_construire_des_widgets_de_formulaires_personnalisés/Exemple_2")}}{{EmbedLiveSample("JS",120,130, "", "Web/Guide/HTML/Formulaires/Comment_construire_des_widgets_de_formulaires_personnalisés/Exemple_2")}}
Testez le code source
- -
-

Note : Si vous voulez vraiment rendre votre code générique et réutilisable, au lieu de faire un changement de classe, il est préférable d'ajouter la classe widget pour cacher les éléments {{HTMLElement("select")}} et d'ajouter dynamiquement l'arbre DOM représentant le widget personnalisé après chaque élément {{HTMLElement("select")}} dans la page.

-
- -

Rendre le travail plus facile

- -

 

- -

Dans le code que nous sommes sur le point de construire, nous utiliserons l'API standard DOM pour faire tout le travail dont nous avons besoin. Cependant, bien que la prise en charge de l'API DOM se soit améliorée dans les navigateurs, il y a toujours des problèmes avec les anciens navigateurs (surtout avec le bon vieux navigateur Internet Explorer).

- -

Si vous voulez éviter les problèmes avec les navigateurs anciens, il y a deux façons de le faire : en utilisant un framework dédié tel que jQuery, $dom, prototype, Dojo, YUI ou similaire, ou bien en remplissant la fonctionnalité manquante que vous voulez utiliser (ce qui peut facilement être fait par un chargement conditionnel, avec la bibliothèque yepnope par exemple).

- -

Les fonctionnalités que nous prévoyons d'utiliser sont les suivantes (classées de la plus risquée à la plus sûre) :

- -
    -
  1. {{domxref("element.classList","classList")}}
  2. -
  3. {{domxref("EventTarget.addEventListener","addEventListener")}}
  4. -
  5. forEach (ce n'est pas du DOM mais du JavaScript moderne)
  6. -
  7. {{domxref("element.querySelector","querySelector")}} et {{domxref("element.querySelectorAll","querySelectorAll")}}
  8. -
- -

Au-delà de la disponibilité de ces fonctionnalités spécifiques, il reste encore un problème avant de commencer. L'objet retourné par la fonction {{domxref("element.querySelectorAll","querySelectorAll()")}} est une {{domxref("NodeList")}} plutôt qu'un Array. C'est important, car les objets  Array acceptent la fonction forEach, mais {{domxref("NodeList")}} ne le fait pas. Comme {{domxref("NodeList")}} ressemble vraiment à un Array et que forEach est d'utilisation si commode, nous pouvons facilement ajouter la prise en charge de forEach à {{domxref("NodeList")}} pour nous faciliter la vie, comme ceci :

- -
NodeList.prototype.forEach = function (callback) {
-  Array.prototype.forEach.call(this, callback);
-}
- -

On ne plaisantait pas quand on a dit que c'était facile à faire.

- -

Construction des fonctions de rappel d'événements

- -

Les fondations sont prêtes, nous pouvons maintenant commencer à définir toutes les fonctions à utiliser chaque fois que l'utilisateur interagit avec notre widget.

- -
// Cette fonction est utilisée chaque fois que nous voulons désactiver un
-// widget personnalisé. Elle prend un paramètre
-// select : le nœud DOM avec la classe select à désactiver
-function deactivateSelect(select) {
-
-  // Si le widget n'est pas actif, il n'y a rien à faire
-  if (!select.classList.contains('active')) return;
-
-  // Nous devons obtenir la liste des options pour le widget personnalisé
-  var optList = select.querySelector('.optList');
-
-  // Nous cachons la liste des options
-  optList.classList.add('hidden');
-
-  // et nous désactivons le widget personnalisé lui-même
-  select.classList.remove('active');
-}
-
-// Cette fonction sera utilisée chaque fois que l'utilisateur veut (des)activer le widget
-// Elle prend deux paramètres :
-// select : le nœud DOM de la classe `select` à activer
-// selectList : la liste de tous les nœuds DOM de la classe `select`
-function activeSelect(select, selectList) {
-
-  // Si le widget est déjà actif il n'y a rien à faire
-  if (select.classList.contains('active')) return;
-
-  // Nous devons désactiver tous les widgets personnalisés
-  // comme la fonction deactivateSelect remplit toutes les fonctionnalités de la
-  // fonction de rappel forEach, nous l'utilisons directement sans utiliser
-  // une fonction anonyme intermédiaire.
-  selectList.forEach(deactivateSelect);
-
-  // Et nous activons l'état du widget donné
-  select.classList.add('active');
-}
-
-// Cette fonction sera utilisée chaque fois que l'utilisateur veut enrouler/dérouler la
-// liste des options
-// Elle prend un paramètre :
-// select : le nœud DOM de la liste à basculer
-function toggleOptList(select) {
-
-  // La liste est prise à partir du widget
-  var optList = select.querySelector('.optList');
-
-  // Nous changeons la classe de la liste pour l'enrouler/dérouler
-  optList.classList.toggle('hidden');
-}
-
-// Cett fonction sera utilisée chaque fois qu'il faut mettre en surbrillance
-// une option.  Elle prend deux paramètres :
-// select : le nœud DOM de la classe `select`
-//          contenant l'option à mettre en surbrillance
-// option : le nœud DOM de la classe `option` à mettre en surbrillance
-function highlightOption(select, option) {
-
-  // Obtenir la liste de toutes les options disponibles pour l'élémént sélectionné
-  var optionList = select.querySelectorAll('.option');
-
-  // Supprimer la surbrillance pour toutes les options
-  optionList.forEach(function (other) {
-    other.classList.remove('highlight');
-  });
-
-  // Mettre en surbrillance l'option correcte
-  option.classList.add('highlight');
-};
- -

C'est tout ce dont on a besoin pour gérer les différents états du widget personnalisé.

- -

Ensuite, nous assujettissons ces fonctions aux événement appropriés :

- -
// Nous lions le widget aux événements dès le chargement du document
-window.addEventListener('load', function () {
-  var selectList = document.querySelectorAll('.select');
-
-  // Chaque widget personnalisé doit être initialisé
-  selectList.forEach(function (select) {
-
-    // de même que tous les éléments `option`
-    var optionList = select.querySelectorAll('.option');
-
-    // Chaque fois que l'utilisateur passe le pointeur de souris
-    // sur une option, nous mettons en surbrillance la dite option
-
-    optionList.forEach(function (option) {
-      option.addEventListener('mouseover', function () {
-        // Note : les variables `select` et `option` sont des "closures"
-        // disponibles dans la portée de notre appel de fonction.
-        highlightOption(select, option);
-      });
-    });
-
-    // Chaque fois que l'utilisateur clique sur un élément personnalisé
-    select.addEventListener('click', function (event) {
-      // Note : la variable `select` est une "closure"
-      // available dans la portée de notre appel de fonction.
-
-      // Nous basculons la visibilité de la liste des options
-      toggleOptList(select);
-    });
-
-    // Dans le cas où le widget obtient le focus
-    // Le widget obtient le focus chaque fois que l'utilisateur clique dessus
-    // ou presse la touche Tab pour avoir accès au widget
-    select.addEventListener('focus', function (event) {
-      // Note : les variable `select` et `selectList` sont des "closures"
-      // disponibles dans la portée de notre appel de fonction.
-
-      // Nous activons le widget
-      activeSelect(select, selectList);
-    });
-
-    // Dans le cas où le widget perd le focus
-    select.addEventListener('blur', function (event) {
-      // Note : la variable `select` est une "closure"
-      // disponible dans la portée de notre appel de fonction.
-
-      // Nous désactivons le widget
-      deactivateSelect(select);
-    });
-  });
-});
- -

A ce stade, notre widget change d'état comme nous l'avons conçu, mais sa valeur n'est pas encore mise à jour. On s'en occupera après.

- - - - - - - - - - - - - - - -
Exemple en direct
{{EmbedLiveSample("Change_states",120,130, "", "/Web/Guide/HTML/Formulaires/Comment_construire_des_widgets_de_formulaires_personnalisés/Example_3")}}
Revoir le code source
- -

Gérer la valeur du widget

- -

 

- -

Maintenant que notre widget fonctionne, nous devons ajouter du code pour mettre à jour la valeur en fonction des entrées utilisateur et envoyer cette valeur avec les données du formulaire.

- -

La façon la plus simple de le faire est d'utiliser un widget natif sous‑jacent. Un tel widget gardera une trace de la valeur avec tous les contrôles intégrés fournis par le navigateur, et la valeur sera envoyée comme d'habitude lorsque le formulaire sera soumis. Il ne sert à rien de réinventer la roue alors que tout cela peut être fait pour nous.

- -

Comme nous l'avons vu précédemment, nous utilisons déjà un widget de sélection natif comme solution de repli pour des raisons d'accessibilité ; nous pouvons simplement synchroniser sa valeur avec celle de notre widget personnalisé :

- -
// Cette fonction met à jour la valeur affichée et la synchronise avec celle
-// du widget natif. Elle prend deux paramètres :
-// select : le nœud DOM de la classe `select` contenant la valuer à mettre à jour
-// index  : l'index de la valeur choisie
-function updateValue(select, index) {
-  // Nous devons obtenir le widget natif correspondant au widget personnalisé
-  // Dans notre exemple, le widget natif est un parent du widget personnalisé
-  var nativeWidget = select.previousElementSibling;
-
-  // Nou devons aussi obtenir la valeur de remplacement du widget personnalisé
-  var value = select.querySelector('.value');
-
-  // Et nous avons besoin de toute la liste des options
-  var optionList = select.querySelectorAll('.option');
-
-  // Nous définissons l'index choisi à l'index du choix
-  nativeWidget.selectedIndex = index;
-
-  // Nous mettons à jour la valeur de remplacement en accord
-  value.innerHTML = optionList[index].innerHTML;
-
-  // Et nous mettons en surbrillance l'option correspondante du widget personnalisé
-  highlightOption(select, optionList[index]);
-};
-
-// Cette fonction renvoie l'index courant dans le widget natif
-// Elle prend un paramètre :
-// select : le nœud DOM avec la classe `select` relative au widget natif
-function getIndex(select) {
-  // Nous avons besoin d'avoir accès au widget natif pour le widget personnalisé
-  // Dans notre exemple, le widget natif est un parent du widget personnalisé
-  var nativeWidget = select.previousElementSibling;
-
-  return nativeWidget.selectedIndex;
-};
- -

Avec ces deux fonctions, nous pouvons lier les widgets natifs avec les personnalisés :

- -
// Nous lions le widget aux événements dès le chargement du document
-window.addEventListener('load', function () {
-  var selectList = document.querySelectorAll('.select');
-
-  // Chaque widget personnalisé doit être initialisé
-  selectList.forEach(function (select) {
-    var optionList = select.querySelectorAll('.option'),
-        selectedIndex = getIndex(select);
-
-    // Nous rendons le widget personnalisé capable d'avoir le focus
-    select.tabIndex = 0;
-
-    // Nous faisons en sorte que le widget natif ne puisse plus avoir le focus
-    select.previousElementSibling.tabIndex = -1;
-
-    // Nous nous assurons que la valeur sélectionnée par défaut est bien affichée
-    updateValue(select, selectedIndex);
-
-    // Chaque fois que l'utilisateur clique sur une option, nous mettons à
-    // jour la valeur en accord
-    optionList.forEach(function (option, index) {
-      option.addEventListener('click', function (event) {
-        updateValue(select, index);
-      });
-    });
-
-    // Chaque fois que l'utilisateur utilise le clavier sur un widget
-    // avec focus, les valeurs sont mises à jour en accord
-
-    select.addEventListener('keyup', function (event) {
-      var length = optionList.length,
-          index  = getIndex(select);
-
-      // Quand l'utilisateur presse ⇓, nous allons à l'option suivante
-      if (event.keyCode === 40 && index < length - 1) { index++; }
-
-      // Quand l'utilisateur presse ⇑, nous sautons à l'option suivante
-      if (event.keyCode === 38 && index > 0) { index--; }
-
-      updateValue(select, index);
-    });
-  });
-});
- -

Dans le code ci-dessus, il faut noter l'utilisation de la propriété tabIndex. Utiliser cette propriété est nécessaire pour être sûr que le widget natif n'obtiendra jamais le focus et que le widget personnalisé l'obtiendra quand l'utilisateur utilise le clavier ou la souris.

- -

Et voilà, nous avons terminé ! Voici le résultat :

- - - - - - - - - - - - - - - -
Exemple en direct
{{EmbedLiveSample("Change_states",120,130, "", "/Web/Guide/HTML/Formulaires/Comment_construire_des_widgets_de_formulaires_personnalisés/Example_4")}}
Revoir le code source
- -

Mais attendez, avons‑nous vraiment terminé ?

- -

Le rendre « accessible »

- -

 

- -

Nous venons de faire quelque chose qui fonctionne, même si nous sommes loin d'avoir une boîte de sélection avec toutes les fonctionnalités, elle fonctionne parfaitement. Mais ce que nous avons fait n'est rien de plus que de jouer avec les DOM. Elle n'a pas de sémantique réelle, et même si elle ressemble à une boîte de sélection, du point de vue du navigateur, ce n'en est pas une, de sorte que les technologies d'assistance ne pourront pas comprendre que c'est une boîte de sélection. Bref, cette jolie nouvelle boîte de sélection n'est pas accessible !

- -

Heureusement, il existe une solution et elle s'appelle ARIA. ARIA signifie « Accessible Rich Internet Application » et c'est une norme W3C spécialement conçue pour ce que nous faisons ici : rendre accessibles les applications web et les widgets personnalisés. Il s'agit essentiellement d'un ensemble d'attributs qui étendent le HTML afin que nous puissions mieux décrire les rôles, les états et les propriétés comme si l'élément que nous venons de concevoir était l'élément natif pour lequel il essaie de passer. L'utilisation de ces attributs est très simple, alors faisons-le.

- -

L'attribut role

- -

L'attribut clé utilisé par ARIA est l'attribut role. L'attribut role  accepte une valeur qui définit à quoi sert un élément. Chaque rôle définit ses propres exigences et comportements. Dans notre exemple, nous utiliserons le rôle de listbox. C'est un « rôle composite », ce qui signifie que les éléments ayant ce rôle s'attendent à avoir des enfants, chacun avec un rôle spécifique (dans ce cas, au moins un enfant avec le rôle option).

- -

Il faut aussi noter qu'ARIA définit les rôles appliqués par défaut aux balises HTML standard. Par exemple, l'élément {{HTMLElement("table")}} correspond au rôle grid, et l'élément {{HTMLElement("ul")}} correspond au rôle list. Comme nous utilisons un élément {{HTMLElement("ul")}}, nous voulons nous assurer que le rôle listbox de notre widget remplacera le rôle list de l'élément {{HTMLElement("ul")}}. À cette fin, nous utiliserons le rôle presentation. Ce rôle est conçu pour nous permettre d'indiquer qu'un élément n'a pas de signification particulière, et est utilisé uniquement pour présenter de l'information. Nous l'appliquerons à notre élément {{HTMLElement("ul")}}.

- -

Pour prendre en charge le rôle listbos, nous n'avons qu'à mettre à jour notre HTML comme ceci :

- -
<!-- Nous ajoutons le role="listbox" en attribut de l'élément de tête -->
-<div class="select" role="listbox">
-  <span class="value">Cherry</span>
-  <!-- Nous ajoutons aussi le role="presentation" à l'élément ul -->
-  <ul class="optList" role="presentation">
-    <!-- et le rôle="option" en attribut de tous les éléments li -->
-    <li role="option" class="option">Cherry</li>
-    <li role="option" class="option">Lemon</li>
-    <li role="option" class="option">Banana</li>
-    <li role="option" class="option">Strawberry</li>
-    <li role="option" class="option">Apple</li>
-  </ul>
-</div>
- -
-

Note : Inclure à la fois l'attribut role et l'attribut class n'est nécessaire que si vous souhaitez prendre en charge les navigateurs anciens qui n'acceptent pas les selecteurs d'attribut CSS.

-
- -

L'attribut  aria-selected

- -

Utiliser l'attribut role ne suffit pas. ARIA fournit également de nombreux états et attributs de propriété. Plus vous les utiliserez, mieux votre widget sera compris par les techniques d'assistance. Dans notre cas, nous limiterons notre utilisation à un seul attribut : aria-selected.

- -

L'attribut aria-selected s'utilise pour marquer l'option actuellement sélectionnée ; ceci permet aux techniques d'assistance d'informer l'utilisateur quelle est la sélection en cours. Nous l'utiliserons dynamiquement avec JavaScript pour marquer l'option sélectionnée chaque fois que l'utilisateur en choisit une. Pour cela, nous devons réviser la fonction updateValue() :

- -
function updateValue(select, index) {
-  var nativeWidget = select.previousElementSibling;
-  var value = select.querySelector('.value');
-  var optionList = select.querySelectorAll('.option');
-
-  // Nous nous assurons qu'aucune option n'est sélectionnée
-  optionList.forEach(function (other) {
-    other.setAttribute('aria-selected', 'false');
-  });
-
-  // Nous nous assurons que l'option choisie est sélectionnée
-  optionList[index].setAttribute('aria-selected', 'true');
-
-  nativeWidget.selectedIndex = index;
-  value.innerHTML = optionList[index].innerHTML;
-  highlightOption(select, optionList[index]);
-};
- -

Voici le résultat final de toutes ces modifications (vous obtiendrez un meilleur ressenti en les testant avec une technique d'assistance comme NVDA ou VoiceOver) :

- - - - - - - - - - - - - - - -
Exemple en direct
{{EmbedLiveSample("Change_states",120,130, "", "/Web/Guide/HTML/Formulaires/Comment_construire_des_widgets_de_formulaires_personnalisés/Example_5")}}
Revoir le code source
- -

Conclusion

- -

Nous venons de voir les bases pour la construction d'un widget de formulaire personnalisé, mais comme vous avez pu le voir, ce n'est pas facile à faire, et il est souvent préférable et plus facile de s'appuyer sur des bibliothèques tierces au lieu de les coder vous-même (sauf, bien sûr, si vous souhaitez bâtir une telle bibliothèque).

- -

Voici quelques bibliothèques à prendre en considération avant de coder les vôtres :

- - - -

Si vous voulez aller plus loin, le code de cet exemple mérite quelques amélioration avant de devenir générique et réutilisable. C'est un exercice que vous pouvez essayer de faire. Deux conseils pour vous aider : le premier argument pour toutes nos fonctions est le même, ce qui signifie que ces fonctions ont besoin du même contexte. Il serait avisé de construire un objet pour partager ce contexte. En outre, vous devrez éprouver ses fonctionnalités, c'est-à-dire qu'il doit pouvoir fonctionner avec les divers navigateurs dont la compatibilité avec les normes Web qu'ils utilisent varie. Amusez-vous bien !

- -

{{PreviousMenuNext("Web/Guide/HTML/Formulaires/Validation_donnees_formulaire", "Web/Guide/HTML/Formulaires/Sending_forms_through_JavaScript", "Web/Guide/HTML/Formulaires")}}

- -

Dans ce module

- - diff --git a/files/fr/web/guide/html/formulaires/comment_structurer_un_formulaire_html/exemple/index.html b/files/fr/web/guide/html/formulaires/comment_structurer_un_formulaire_html/exemple/index.html deleted file mode 100644 index 91cd643bd1..0000000000 --- a/files/fr/web/guide/html/formulaires/comment_structurer_un_formulaire_html/exemple/index.html +++ /dev/null @@ -1,166 +0,0 @@ ---- -title: Exemple -slug: Web/Guide/HTML/Formulaires/Comment_structurer_un_formulaire_HTML/Exemple -translation_of: Learn/Forms/How_to_structure_a_web_form/Example ---- -

Ceci est un exemple de formulaire de paiement basique extrait de l'article Comment structurer un formulaire HTML.

- -

Un formulaire de paiement

- -

Contenu HTML

- -
<form>
-        <h1>Formulaire de paiement</h1>
-        <p>Les champs obligatoires sont suivis par <strong><abbr title="required">*</abbr></strong>.</p>
-        <section>
-            <h2>Informations de contact</h2>
-            <fieldset>
-              <legend>Qualité</legend>
-              <ul>
-                  <li>
-                    <label for="title_1">
-                      <input type="radio" id="title_1" name="title" value="M." >
-                      Monsieur
-                    </label>
-                  </li>
-                  <li>
-                    <label for="title_2">
-                      <input type="radio" id="title_2" name="title" value="Mme.">
-                      Madame
-                    </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>e-mail :</span>
-                <strong><abbr title="required">*</abbr></strong>
-              </label>
-              <input type="email" id="mail" name="usermail">
-            </p>
-            <p>
-              <label for="password">
-                <span>Mot de passe :</span>
-                <strong><abbr title="required">*</abbr></strong>
-              </label>
-              <input type="password" id="pwd" name="password">
-            </p>
-        </section>
-        <section>
-            <h2>Informations de paiement</h2>
-            <p>
-              <label for="card">
-                <span>Type de carte :</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>Numéro :</span>
-                <strong><abbr title="required">*</abbr></strong>
-              </label>
-                <input type="text" id="number" name="cardnumber">
-            </p>
-            <p>
-              <label for="date">
-                <span>Validité :</span>
-                <strong><abbr title="required">*</abbr></strong>
-                <em>format mm/aa</em>
-              </label>
-              <input type="text" id="date" name="expiration">
-            </p>
-        </section>
-        <section>
-            <p> <button type="submit">Valider le paiement</button> </p>
-        </section>
-    </form>
- -

Contenu CSS

- -
      h1 {
-          margin-top: 0;
-      }
-
-      ul {
-          margin: 0;
-          padding: 0;
-          list-style: none;
-      }
-
-      form {
-          margin: 0 auto;
-          width: 450px;
-          padding: 1em;
-          border: 1px solid #CCC;
-          border-radius: 1em;
-      }
-
-      div+div {
-          margin-top: 1em;
-      }
-
-      label span {
-          display: inline-block;
-          width: 120px;
-          text-align: right;
-      }
-
-      input, textarea {
-          font: 1em sans-serif;
-          width: 250px;
-          box-sizing: border-box;
-          border: 1px solid #999;
-      }
-
-      input[type=checkbox], input[type=radio] {
-          width: auto;
-          border: none;
-      }
-
-      input:focus, textarea:focus {
-          border-color: #000;
-      }
-
-      textarea {
-          vertical-align: top;
-          height: 5em;
-          resize: vertical;
-      }
-
-      fieldset {
-          width: 250px;
-          box-sizing: border-box;
-          margin-left: 146px;
-          border: 1px solid #999;
-      }
-
-      button {
-          margin: 20px 0 0 124px;
-      }
-
-      label {
-        position: relative;
-      }
-
-      label em {
-        position: absolute;
-        right: 5px;
-        top: 20px;
-      }
- -

Résultat

- -

{{ EmbedLiveSample("Un_formulaire_de_paiement", "100%", "620") }}

- -

 

diff --git a/files/fr/web/guide/html/formulaires/comment_structurer_un_formulaire_html/index.html b/files/fr/web/guide/html/formulaires/comment_structurer_un_formulaire_html/index.html deleted file mode 100644 index f7d2e7db7d..0000000000 --- a/files/fr/web/guide/html/formulaires/comment_structurer_un_formulaire_html/index.html +++ /dev/null @@ -1,310 +0,0 @@ ---- -title: Comment structurer un formulaire HTML -slug: Web/Guide/HTML/Formulaires/Comment_structurer_un_formulaire_HTML -tags: - - Apprentissage - - Débutant - - Exemple - - Formulaires - - Guide - - HTML - - Structure - - Web -translation_of: Learn/Forms/How_to_structure_a_web_form ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Web/Guide/HTML/Formulaires/Mon_premier_formulaire_HTML", "Web/Guide/HTML/Formulaires/Les_blocs_de_formulaires_natifs", "Web/Guide/HTML/Formulaires")}}
- -

Les bases vues, nous examinons maintenant plus en détail les éléments utilisés pour structurer et donner un sens aux différentes parties d'un formulaire.

- - - - - - - - - - - - -
Prérequis :Notions concernant les ordinateurs et les connaissances de base du HTML.
Objectif :Comprendre comment structurer les formulaires HTML et leur adjoindre la sémantique pour qu'ils soient utilisables et accessibles.
- -

La souplesse des formulaires HTML fait d'eux une des structures les plus complexes en HTML. vous pouvez construire n'importe quel type de formulaire basique en utilisant les éléments et attributs qui leur sont dédiés. En utilisant une architecture correcte lors de la construction d'un formulaire, vous serez sûrs que le formulaire est à la fois utilisable et accessible.

- -

L'élément <form>

- -

L'élément {{HTMLElement("form")}} définit conventionnellement un formulaire et des attributs qui déterminent le comportement du‑dit formulaire. Chaque fois que vous voulez créer un formulaire HTML, vous devez le débuter par cet élément et mettre tout son contenu à l'intérieur. De nombreuses techniques d'assistance ou greffons de navigateur peuvent détecter les éléments {{HTMLElement("form")}} et implémenter des accroches spéciales pour les rendre plus faciles à utiliser.

- -

Nous l'avons déjà rencontré dans l'article précédent.

- -
Note : Il est strictement interdit d'imbriquer un formulaire dans un autre formulaire. L'imbrication peut conduire à des comportements imprévisibles selon le navigateur utilisé.
- -

Notez qu'il est toujours possible d'utiliser un widget de formulaire en dehors d'un élément {{HTMLElement("form")}} mais si vous le faites, ce widget de formulaire n'a rien à voir avec un formulaire. De tels widgets peuvent être utilisés en dehors d'un formulaire, mais alors vous devriez avoir un plan spécial pour de tels widgets, puisqu'ils ne feront rien tout seuls. Vous devrez personnaliser leur comportement avec JavaScript.

- -
-

Note: HTML5 introduit l'attribut form dans les éléments form du HTML. Il devrait vous permettre de lier explicitement un élément avec un formulaire même s'il n'est pas inclus dans un {{ HTMLElement("form") }}. Malheureusement, pour l'instant, l'implémentation de cette fonctionnalité dans les navigateurs n'est pas encore assez fiable.

-
- -

Les éléments <fieldset> et <legend>

- -

L'élément {{HTMLElement("fieldset")}} est un moyen pratique de créer des groupes de widgets qui partagent le même but, pour le style et la sémantique. Vous pouvez étiqueter un {{HTMLElement("fieldset")}} en incluant un élément {{HTMLElement("legend")}} juste en dessous de la balise d'ouverture <fieldset>. Le contenu textuel de l'élément {{HTMLElement("legend")}} décrit formellement le but de l'élément {{HTMLElement("fieldset")}} inclus à l'intérieur.

- -

De nombreuses technologies d'assistance utiliseront l'élément {{HTMLElement("legend")}} comme s'il faisait partie de l'étiquette de chaque widget à l'intérieur de l'élément {{HTMLElement("fieldset")}} correspondant. Par exemple, certains lecteurs d'écran comme Jaws ou NVDA énonceront le contenu de la légende avant d'indiquer l'étiquette de chaque widget.

- -

Voici un petit exemple :

- -
<form>
-  <fieldset>
-    <legend>Taille du jus de fruits</legend>
-    <p>
-      <input type="radio" name="size" id="size_1" value="small">
-      <label for="size_1">Petite</label>
-    </p>
-    <p>
-      <input type="radio" name="size" id="size_2" value="medium">
-      <label for="size_2">Moyenne</label>
-    </p>
-    <p>
-      <input type="radio" name="size" id="size_3" value="large">
-      <label for="size_3">Grande</label>
-    </p>
-  </fieldset>
-</form>
- -
-

Note : Vous trouverez cet exemple dans fieldset-legend.html (voir directement aussi).

-
- -

En lisant le formulaire ci-dessus, un lecteur d'écran dira « Taille du jus de fruit : petit » pour le premier widget, « Taille du jus de fruit : moyenne » pour le second, et « Taille du jus de fruit : grande » pour le troisième.

- -

Le scenario d'utilisation du lecteur dans cet exemple est l'un des plus importants. Chaque fois que vous avez un ensemble de boutons radio, vous devez les imbriquer dans un élément {{HTMLElement("fieldset")}}. Il y a d'autres scenarii d'utilisation, et en général l'élément {{HTMLElement("fieldset")}} peut aussi être utilisé pour partager un formulaire. Idéalement, les formulaires longs doivent être éclatés sur plusieurs pages, mais si un formulaire long doit être sur une page unique, le fait de placer les différentes sections connexes dans de différents {{HTMLElement("fieldset")}} peut en améliorer l'utilisation.

- -

En raison de son influence sur les techniques d'assistance, l'élément {{HTMLElement("fieldset")}} est l'un des éléments clés pour la création de formulaires accessibles ; cependant, il vous appartient de ne pas en abuser. Si possible, chaque fois que vous créez un formulaire, essayez d'écouter comment un lecteur d'écran l'interprète. Si cela ne paraît pas naturel, essayez d'améliorer la structure du formulaire.

- -

L'élément <label>

- -

Comme nous l'avons vu dans l'article précédent, l'élément {{HTMLElement("label")}} est le moyen naturel de définir une étiquette pour un widget de formulaire HTML. C'est l'élément le plus important si vous voulez créer des formulaires accessibles — lorsqu'ils sont correctement implémentés, les lecteurs d'écran énonceront l'étiquette d'un élément de formulaire selon toutes les instructions associées. Prenons cet exemple, que nous avons vu dans l'article précédent :

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

Avec un élément <label> correctement associé à <input> par l'intermédiaire respectivement des attributs for et id (l'attribut for de <label> référence l'attibut id du widget correspondant), un lecteur d'écran lira et dira quelque chose comme « Nom, texte indiqué ».

- -

Si l'étiquette n'est pas correctement paramétrée, le lecteur d'écran dira quelque chose comme « Texte édité vierge », ce qui n'est pas utile du tout.

- -

Notez qu'un widget peut être incorporé dans son élément {{HTMLElement("label")}}, ainsi :

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

Toutefois, même dans ce cas, il est considéré de bonne pratique de définir l'attribut for parce que certaines techniques d'assistance ne font pas implicitement le lien entre les étiquettes et les widgets.

- -

Les étiquettes peuvent être cliquées, aussi !

- -

Autre avantage de bien configurer les étiquettes : vous pouvez cliquer sur l'étiquette pour activer le widget correspondant, dans tous les navigateurs. Utile, par exemple, pour des entrées de texte : vous pouvez cliquer sur l'étiquette ou la zone de texte pour y obtenir le curseur, mais c'est encore plus utile pour les boutons radio et les cases à cocher — la surface active au clic pour une telle commande peut être très réduite, il est donc utile de l'agrandir autant que possible.

- -

Par exemple :

- -
<form>
-  <p>
-    <label for="taste_1">J'aime les cerises</label>
-    <input type="checkbox" id="taste_1" name="taste_cherry" value="1">
-  </p>
-  <p>
-    <label for="taste_2">J'aime les bananes</label>
-    <input type="checkbox" id="taste_2" name="taste_banana" value="2">
-  </p>
-</form>
- -
-

Note : Vous trouverez cet exemple dans checkbox-label.html (à voir directement aussi).

-
- -

Étiquettes multiples

- -

En fait, il est possible d'associer plusieurs étiquettes à un seul widget, mais ce n'est pas une bonne idée car certaines techniques d'assistance peuvent éprouver du trouble pour leur gestion. Dans le cas d'étiquettes multiples, vous devez incorporer le widget et son étiquette dans un seul élément {{htmlelement("label")}}.

- -

Considérons cet exemple :

- -
<p>Les champs obligatoires sont suivis de <abbr title="required">*</abbr>.</p>
-
-<!-- Donc ceci : -->
-<div>
-  <label for="username">Nom :</label>
-  <input type="text" name="username">
-  <label for="username"><abbr title="required">*</abbr></label>
-</div>
-
-<!-- sera mieux programmé ainsi : -->
-<div>
-  <label for="username">
-    <span>Nom :</span>
-    <input id="username" type="text" name="username">
-    <abbr title="required">*</abbr>
-  </label>
-</div>
-
-<!-- mais ceci est probablement encore meilleur : -->
-<div>
-  <label for="username">Nom :<abbr title="required">*</abbr></label>
-  <input id="username" type="text" name="username">
-</div>
- -

Le paragraphe du haut définit la règle pour les éléments obligatoires. Ce doit être au début pour s'assurer que les techniques d'assistance telles que les lecteurs d'écran l'afficheront ou le vocaliseront à l'utilisateur avant qu'il ne trouve un élément obligatoire. Ainsi, ils sauront ce que signifie l'astérisque. Un lecteur d'écran mentionnera l'astérisque en disant « astérisque » ou « obligatoire », selon les réglages du lecteur d'écran — dans tous les cas, ce qui sera dit est clairement précisé dans le premier paragraphe.

- - - -
-

Note : Vous pouvez obtenir des résultats légérement différents, selon votre lecteur d'écran. Ce qui précéde a été testé avec VoiceOver (et NVDA se comporte de la même façon). Nous aimerions avoir un retour sur vos expériences également.

-
- -
-

Note : Vous trouverez cet exemple sur GitHub dans required-labels.html (à voir directement aussi). Ne lancez pas l'exemple avec 2 ou 3 version non mises en commentaires — le lecteur d'écran serait totalement embrouillé s'il y a plusieurs étiquettes ET plusieurs entrées avec le même ID !

-
- -

Structures HTML courantes dans les formulaires

- -

Au-delà des structures propres aux formulaires HTML,rappelons‑nous que les formulaires sont du pur HTML. Vous pouvez donc utiliser toute la puissance du HTML pour structurer un formulaire.

- -

Comme vous avez pu le voir dans les exemples, il est de pratique courante d'envelopper une étiquette et son widget avec un élément {{HTMLElement("div")}}. Les éléments {{HTMLElement("p")}} sont aussi couramment utilisés, tout comme les listes HTML (ces dernières sont très courantes pour structurer plusieurs cases à cocher ou boutons radio).

- -

En plus de l'élément {{HTMLElement("fieldset")}}, il est habituel d'utiliser des titres HTML (par exemple {{htmlelement("h1")}}, {{htmlelement("h2")}}) et des sections (par exemple {{htmlelement("section")}}) pour structurer un formulaire complexe.

- -

Par-dessus tout, il vous appartient de trouver un style où vous vous sentez à l'aise pour coder, et qui se traduit aussi par des formulaires accessibles et utilisables.

- -

Chaque groupe de fonctionnalités séparées doit être contenu dans un élément {{htmlelement("section")}} et les boutons radio dans un élément {{htmlelement("fieldset")}}.

- -

Apprentissage actif : construire une structure de formulaire

- -

Mettons ces idées en pratique et construisons une structure de formulaire un peu plus sophistiquée — un formulaire de paiement. Il contiendra un certain nombre de types de widgets que vous ne comprenez pas encore — ne vous inquiétez pas pour l'instant ; vous découvrirez comment ils fonctionnent dans l'article suivant (Les widgets natifs pour formulaire). Pour l'instant, lisez attentivement les descriptions en suivant les instructions ci-dessous et commencez à vous faire une idée des éléments enveloppes que nous utilisons pour structurer le formulaire, et pourquoi.

- -
    -
  1. Pour commencer, faites une copie locale de notre fichier modèle vierge et des CSS pour notre formulaire de paiement dans un nouveau répertoire.
  2. -
  3. Primo, appliquez les CSS au HTML en ajoutant la ligne suivante dans l'élément {{htmlelement("head")}} du HTML : -
    <link href="payment-form.css" rel="stylesheet">
    -
  4. -
  5. Ensuite, commencez le formulaire en ajoutant un élément {{htmlelement("form")}} : -
    <form>
    -
    -</form>
    -
  6. -
  7. Entre les balises <form>, ajoutez un en‑tête et un paragraphe pour informer les utilisateurs comment sont marqués les champs obligatoires : -
    <h1>Formulaire de paiement</h1>
    -<p>Les champs obligatoires sont suivis par un <strong><abbr title="required">*</abbr></strong>.</p>
    -
  8. -
  9. Ensuite, nous ajoutons une grande section de code dans le formulaire, sous la précédente. Ici vous verrez que nous enveloppons les champs d'informations de contact dans des éléments {{htmlelement("section")}} distincts. De plus, nous avons un ensemble de deux boutons radio, que nous mettons chacun à l'intérieur de leur propre élément de liste ({{htmlelement("li")}}). Enfin, nous avons deux zones de texte standard {{htmlelement("input")}} et leurs éléments {{htmlelement("label")}} associés, chacun contenu dans un élément {{htmlelement("p")}}, plus une entrée pour le mot de passe. Ajoutez ce code à votre formulaire maintenant : -
    <section>
    -    <h2>Informations de contact</h2>
    -    <fieldset>
    -      <legend>Qualité</legend>
    -      <ul>
    -          <li>
    -            <label for="title_1">
    -              <input type="radio" id="title_1" name="title" value="M." >
    -              Monsieur
    -            </label>
    -          </li>
    -          <li>
    -            <label for="title_2">
    -              <input type="radio" id="title_2" name="title" value="Mme.">
    -              Madame
    -            </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>e-mail :</span>
    -        <strong><abbr title="required">*</abbr></strong>
    -      </label>
    -      <input type="email" id="mail" name="usermail">
    -    </p>
    -    <p>
    -      <label for="pwd">
    -        <span>Mot de passe :</span>
    -        <strong><abbr title="required">*</abbr></strong>
    -      </label>
    -      <input type="password" id="pwd" name="password">
    -    </p>
    -</section>
    -
  10. -
  11. Nous arrivons maintenant à la deuxième <section> de notre formulaire — l'information de paiement. Ici nous avons trois widgets distincts avec leur étiquette, chacun contenu dans un paragraphe <p>. Le premier est un menu déroulant ({{htmlelement("select")}}) pour le choix du type de la carte de crédit. Le deuxième  est un élément <input> de type nombre pour entrer le numéro de la carte de crédit. Le dernier est un élément <input> de type date pour entrer la date d'expiration de la carte de crédit (il sera accompagné d'un widget dateur pour les navigateurs prenant en charge cette fonctionnalité, et sera un simple champ textuel pour les navigateurs ne la prenant pas en charge). À nouveau, entrez ce qui suit après la section ci‑dessus : -
    
    -<section>
    -    <h2>Informations de paiement</h2>
    -    <p>
    -      <label for="card">
    -        <span>Type de carte :</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>Numéro de carte :</span>
    -        <strong><abbr title="required">*</abbr></strong>
    -      </label>
    -      <input type="text" id="number" name="cardnumber">
    -    </p>
    -    <p>
    -      <label for="date">
    -        <span>Validité :</span>
    -        <strong><abbr title="required">*</abbr></strong>
    -        <em>format mm/aa</em>
    -      </label>
    -      <input type="text" id="date" name="expiration">
    -    </p>
    -</section>
    -
  12. -
  13. La dernière section est plus simple ; elle ne contient qu'un bouton {{htmlelement("button")}} de type submit, pour adresser les données du formulaire. Ajoutez ceci au bas du formulaire : -
    <p> <button type="submit">Valider le paiement</button> </p>
    -
  14. -
- -

Vous pouvez voir le formulaire terminé en action ci‑dessous (vous le trouverez aussi sur GitHub — voir la source payment-form.html et une exécution directe):

- -

{{EmbedLiveSample("Un_formulaire_de_paiement","100%","620", "", "Web/Guide/HTML/Formulaires/Comment_structurer_un_formulaire_HTML/Exemple")}}

- -

Résumé

- -

Nous savons maintenant ce qu'il faut faire pour structurer de manière appropriée un formulaire HTML ; l'article suivant approfondira la mise en œuvre  des divers types de widgets pour formulaire pour collecter les informations utilisateur.

- -

Voir aussi

- - - -

{{PreviousMenuNext("Web/Guide/HTML/Formulaires/Mon_premier_formulaire_HTML", "Web/Guide/HTML/Formulaires/Les_blocs_de_formulaires_natifs", "Web/Guide/HTML/Formulaires")}}

- -

Dans ce module

- - diff --git "a/files/fr/web/guide/html/formulaires/envoyer_et_extraire_les_donn\303\251es_des_formulaires/index.html" "b/files/fr/web/guide/html/formulaires/envoyer_et_extraire_les_donn\303\251es_des_formulaires/index.html" deleted file mode 100644 index bc81996fda..0000000000 --- "a/files/fr/web/guide/html/formulaires/envoyer_et_extraire_les_donn\303\251es_des_formulaires/index.html" +++ /dev/null @@ -1,371 +0,0 @@ ---- -title: Envoyer et extraire les données des formulaires -slug: Web/Guide/HTML/Formulaires/Envoyer_et_extraire_les_données_des_formulaires -tags: - - Débutant - - En-têtes - - Fichier - - Formulaire - - Guide - - HTML - - HTTP - - Sécurité - - Web -translation_of: Learn/Forms/Sending_and_retrieving_form_data ---- -
{{learnSidebar}}{{PreviousMenuNext("Web/Guide/HTML/Formulaires/Les_blocs_de_formulaires_natifs", "Web/Guide/HTML/Formulaires/Validation_donnees_formulaire", "Web/Guide/HTML/Formulaires")}}
- -

Cet article examine ce qui arrive quand un utilisateur soumet un formulaire — où les données vont-elles et comment les gère-t-on une fois à destination ? Nous examinerons aussi quelques problèmes de sécurité associés à l'envoi des données d'un formulaire.

- - - - - - - - - - - - -
Prérequis :Notions concernant les ordinateurs, compréhension du HTML, et connaissances de base de HTTP et programmation côté serveur.
Objectif :Comprendre ce qui arrive quand les données d'un formulaire sont soumises, y compris les notions de la façon dont les données sont traitées sur le serveur.
- -

Où vont les données ?

- -

Dans ce paragraphe, nous expliquons ce qui arrive aux données lors de la soumission d'un formulaire.

- -

A propos de l'architecture client / serveur

- -

Le web se fonde sur une architecture client/serveur élémentaire ; en résumé : un client (généralement un navigateur Web) envoie une requête à un serveur (le plus souvent un serveur web comme Apache, Nginx, IIS, Tomcat...), en utilisant le protocole HTTP. Le serveur répond à la requête en utilisant le même protocole.

- -

Un schéma élémentaire d'architecture client/serveur sur le Web

- -

Côté client, un formulaire HTML n'est rien d'autre qu'un moyen commode et convivial de configurer une requête HTTP pour envoyer des données à un serveur. L'utilisateur peut ainsi adresser des informations à joindre à la requête HTTP.

- -
-

Note: Pour une meilleure idée du fonctionnement de l'architecture client‑serveur, lisez notre module Programmation d'un site web côté‑serveur : premiers pas.

-
- -

Côté client : définition de la méthode d'envoi des données

- -

L'élément  {{HTMLElement("form")}} définit la méthode d'envoi des données. Tous ses attributs sont conçus pour vous permettre de configurer la requête à envoyer quand un utilisateur presse le bouton d'envoi. Les deux attributs les plus importants sont {{htmlattrxref("action","form")}} et {{htmlattrxref("method","form")}}.

- -

L'attribut {{htmlattrxref("action","form")}}

- -

Cet attribut définit où les données sont envoyées. Sa valeur doit être une URL valide. S'il n'est pas fourni, les données seront envoyées à l'URL de la page contenant le formulaire.

- -

Dans cet exemple, les données sont envoyées à une URL précise — http://foo.com :

- -
<form action="http://foo.com">
- -

Ici, nous utilisons une URL relative — les données sont envoyées à une URL différente sur le serveur :

- -
<form action="/somewhere_else">
- -

Sans attribut, comme ci-dessous, les données de {{HTMLElement("form")}} sont envoyées à la même page que celle du formulaire  :

- -
<form>
- -

De nombreuses pages anciennes utilisent la notation suivante pour indiquer que les données doivent être envoyées à la page qui contient le formulaire. C'était nécessaire car jusqu'à HTML5, l'attribut {{htmlattrxref("action", "form")}} était requis. Il n'y en a donc plus besoin.

- -
<form action="#">
- -
-

Note : Il est possible de spécifier une URL qui utilise le protocole HTTPS (HTTP sécurisé). Quand vous faites ceci, les données sont chiffrées avec le reste de la requête, même si le formulaire lui-même est hébergé dans une page non sécurisée à laquelle on accède via HTTP. D'autre part, si le formulaire est hébergé sur une page sécurisée mais qu'on spécifique une URL non sécurisée avec l'attribut {{htmlattrxref("action","form")}}, tous les navigateurs affichent une alerte de sécurité pour l'utilisateur chaque fois qu'il envoie des données car celles-ci ne sont pas chiffrées.

-
- -

L'attribut {{htmlattrxref("method","form")}}

- -

Cet attribut définit comment les données sont envoyées. Le Protocole HTTP fournit plusieurs façons d'envoyer une requête. Les données des formulaires HTML peuvent être envoyées via au moins deux méthodes : la méthode GET et la méthode POST.

- -

Pour bien comprendre la différence entre ces deux méthodes, il convient d'examiner comment le protocole HTTP marche. Chaque fois qu'on veut atteindre une ressource sur Internet, le navigateur envoie une requête à une URL. Une requête HTTP consiste en deux parties : un en-tête (header) qui contient les métadonnées sur les capacités du navigateur, et un corps (body) qui contient les informations nécessaires au serveur pour effectuer la requête.

- -
La méthode GET
- -

La méthode GET est utilisée par le navigateur pour demander au serveur de renvoyer une certaine ressource. "Hé le serveur, je veux cette ressource." Dans ce cas, le navigateur envoie un corps vide. Du coup, si un formulaire est envoyé avec cette méthode, les données envoyées au serveur sont ajoutées à l'URL.

- -

Considérons le formulaire suivant :

- -
<form action="http://foo.com" method="get">
-  <div>
-    <label for="say">Quel salut voulez-vous adresser ?</label>
-    <input name="say" id="say" value="Hi">
-  </div>
-  <div>
-    <label for="to">À qui voulez‑vous l'adresser ?</label>
-    <input name="to" value="Mom">
-  </div>
-  <div>
-    <button>Send my greetings</button>
-  </div>
-</form>
- -

Comme nous avons utilisé la méthode GET, vous verrez l'URL www.foo.com/?say=Hi&to=Mom apparaître dans la barre du navigateur quand vous soumettez le formulaire.

- -

Message d'erreur: le serveur est introuvable

- -

Les données sont ajoutées à l'URL sous forme d'une suite de paires nom/valeur. À la fin de l'URL de l'adresse Web, il y a un point d'interrogation (?) suivi par les paires nom/valeur séparés par une esperluette (&). Dans ce cas, nous passons deux éléments de données au serveur :

- - - -

La requête HTTP ressemble à quelque chose comme :

- -
GET /?say=Hi&to=Mom HTTP/1.1
-Host: foo.com
- -
-

Note : Vous trouverez cet exemple sur GitHub — voyez get-method.html (à voir directement aussi).

-
- -
La méthode POST
- -

La méthode POST est un peu différente.C'est la méthode que le navigateur utilise pour demander au serveur une réponse prenant en compte les données contenues dans le corps de la requête HTTP : « Hé serveur ! vois ces données et renvoie-moi le résultat approprié ». Si un formulaire est envoyé avec cette méthode, les données sont ajoutées au corps de la requête HTTP.

- -

Voyons un exemple — c'est le même formulaire que celui que nous avons vu pour GET ci‑dessus, mais avec post comme valeur de l'attribut  {{htmlattrxref("method","form")}}.

- -
<form action="http://foo.com" method="post">
-  <div>
-    <label for="say">Quel salut voulez‑vous adresser ?</label>
-    <input name="say" id="say" value="Hi">
-  </div>
-  <div>
-    <label for="to">À qui voulez‑vous l'adresser ?</label>
-    <input name="to" value="Mom">
-  </div>
-  <div>
-    <button>Send my greetings</button>
-  </div>
-</form>
- -

Quand le formulaire est soumis avec la méthode POST, aucune donnée n'est ajoutée à l'URL et la requête HTTP ressemble à ceci, les données incorporées au corps de requête :

- -
POST / HTTP/1.1
-Host: foo.com
-Content-Type: application/x-www-form-urlencoded
-Content-Length: 13
-
-say=Hi&to=Mom
- -

L'en-tête Content-Length indique la taille du corps, et l'en-tête Content-Type indique le type de ressources envoyées au serveur. Nous discuterons de ces en-têtes dans un moment.

- -
-

Note : Vous trouverez cet exemple sur GitHub — voyez post-method.html (à voir directement aussi).

-
- -

Voir les requêtes HTTP

- -

Les requêtes HTTP ne sont jamais montrées à l'utilisateur (si vous voulez les voir, vous devez utiliser des outils comme la Console Web de Firefox ou les Chrome Developer Tools). À titre d'exemple, les données de formulaire sont visibles comme suit dans l'onglet Chrome Network.  Après avoir soumis le formulaire :

- -
    -
  1. Pressez F12
  2. -
  3. Selectionnez « Réseau »
  4. -
  5. Selectionnez « Tout »
  6. -
  7. Selectionnez « foo.com » dans l'onglet « Nom »
  8. -
  9. Selectionnez « En‑tête »
  10. -
- -

Vous obtiendrez les données du formulaire, comme l'image suivante le montre.

- -

- -

La seule chose affichée à l'utilisateur est l'URL appelée. Comme mentionné ci‑dessus, avec une requête GET l'utilisateur verra les données dans la barre de l'URL, mais avec une requête POST il ne verra rien. Cela peut être important pour deux raisons :

- -
    -
  1. -

    Si vous avez besoin d'envoyer un mot de passe (ou toute autre donnée sensible), n'utilisez jamais la méthode GET ou vous risquez de l'afficher dans la barre d'URL, ce qui serait très peu sûr.

    -
  2. -
  3. -

    Si vous avez besoin d'envoyer une grande quantité de données, la méthode POST est préférable car certains navigateurs limitent la taille des URLs. De plus, de nombreux serveurs limitent la longueur des URL qu'ils acceptent.

    -
  4. -
- -

Côté serveur : récupérer les données

- -

Quelle que soit la méthode HTTP qu'on choisit, le serveur reçoit une chaîne de caractères qui sera décomposée pour récupérer les données comme une liste de paires clé/valeur. La façon d'accéder à cette liste dépend de la plateforme de développement utilisée et des modèles qu'on peut utiliser avec. La technologie utilisée détermine aussi comment les clés dupliquées sont gérées ; souvent, la priorité est donnée à la valeur de clé la plus récente.

- -

Exemple : PHP brut

- -

Le PHP met à disposition des objets globaux pour accéder aux données. En supposant que vous avez utilisé la méthode POST, l'exemple suivant récupère les données et les affiche à l'utilisateur. Bien sûr, ce que vous en faites dépend de vous. Vous pouvez les afficher, les ranger dans une base de données, les envoyer par mail ou les traiter autrement.

- -
<?php
-  // La variable globale $_POST vous donne accès aux données envoyées avec la méthode POST par leur nom
-  // Pour avoir accès aux données envoyées avec la méthode GET, utilisez $_GET
-  $say = htmlspecialchars($_POST['say']);
-  $to  = htmlspecialchars($_POST['to']);
-
-  echo  $say, ' ', $to;
- -

Cet exemple affiche une page avec les données envoyées. Vous pouvez voir ceci opérer avec notre fichier exemple php-example.html — il contient le même formulaire exemple que celui vu précédemment avec la méthode post avec php-example.php en action. À la soumission du formulaire, il envoie les données de ce dernier à php-example.php, contenant le code ci‑dessus. Quand le code est exécuté, la sortie dans le navigateur est Bonjour, M'an.L'exécution du code PHP déclenche l'affichage de Bonjour, M'an

- -
-

Note : Cet exemple ne fonctionnera pas si vous le chargez localement dans un navigateur — les navigateurs ne savent pas interpréter le code PHP, donc quand le formulaire est soumis, le navigateur vous offrira seulement de télécharger le fichier PHP pour vous. Pour qu'il s'exécute, il est nécessaire de lancer l'exemple par l'intermédiaire d'un serveur PHP de n'importe quel type. Les bons choix pour des tests locaux de PHP sont MAMP (Mac et Windows) et AMPPS (Mac, Windows, Linux).

-
- -

Exemple: Python

- -

Cet exemple vous montre comment utiliser Python pour faire la même chose — afficher les données sur une page web. Celui‑ci utilise Flask framework pour le rendu des modèles, la gestion de la soumission des données du formulaire, etc (voyez python-example.py).

- -
from flask import Flask, render_template, request
-app = Flask(__name__)
-
-@app.route('/', methods=['GET', 'POST'])
-def form():
-    return render_template('form.html')
-
-@app.route('/hello', methods=['GET', 'POST'])
-def hello():
-    return render_template('greeting.html', say=request.form['say'], to=request.form['to'])
-
-if __name__ == "__main__":
-    app.run()
- -

Les deux prototypes  référencés dans le code ci‑dessus sont les suivants :

- - - -
-

Note : À nouveau, ce code ne fonctionnera pas si vous tentez de le charger directement dans le navigateur. Python fonctionne un peu différemment de PHP — pour exécuter ce code localement il est nécessaire d'installer Python/PIP, puis Flask avec « pip3 install flask ». À ce moment‑là vous pourrez exécuter l'exemple avec « python3 python-example.py », puis en allant sur « localhost:5000 » dans votre navigateur.

-
- -

Autres langages et canevas de structures

- -

Il y a de nombreuses autres techniques côté serveur utilisables pour gérer des formulaires, comme Perl, Java, .Net, Ruby... retenez juste votre préférée. Cela dit, il faut noter qu'il n'est pas très courant d'utiliser ces techniques directement car cela peut être délicat. Il est plus fréquent d'utiliser l'un des jolis canevas qui permettent de gérer des formulaires plus facilement, comme :

- - - -

Enfin il faut noter que même en utilisant ces canevas, travailler avec des formulaires n'est pas toujours facile. Mais c'est quand même bien plus facile que d'essayer d'en écrire vous‑même les fonctionnalités et cela vous économisera pas mal de temps.

- -
-

Note : Nous déborderions du cadre de cet article en vous initiant aux langages côté serveur ou aux canevas. Les liens ci‑dessus vous donneront des informations si vous souhaitez en apprendre plus.

-
- -

Cas particulier : envoyer des fichiers

- -

L'envoi de fichiers avec une formulaire HTML est cas particulier. Les fichiers sont des données binaires — ou considérées comme telles — alors que toutes les autres données sont des données textuelles. Comme HTTP est un protocole de texte, il y a certaines conditions particulières à remplir pour gérer des données binaires.

- -

L'attribut {{htmlattrxref("enctype","form")}}

- -

Cet attribut vous permet de préciser la valeur de l'en-tête HTTP Content-Type incorporé dans la requête générée au moment de la soumission du formulaire. Cet en-tête est très important car il indique au serveur le type de données envoyées. Par défaut, sa valeur est application/x-www-form-urlencoded. Ce qui signifie : « Ce sont des données de formulaire encodées à l'aide de paramètres URL ».

- -

Mais si vous voulez envoyer des fichiers, il faut faire deux choses en plus :

- - - -

 Par exemple :

- -
<form method="post" enctype="multipart/form-data">
-  <div>
-    <label for="file">Choose a file</label>
-    <input type="file" id="file" name="myFile">
-  </div>
-  <div>
-    <button>Send the file</button>
-  </div>
-</form>
- -
-

Note : Certains navigateurs prennent en charge l'attribut {{htmlattrxref("multiple","input")}} de l'élément {{HTMLElement("input")}}pour envoyer plus d'un fichier avec seulement un élément d'entrée. La façon dont le serveur gère ces fichiers dépend de la technologie du serveur. Comme évoqué précédemment, utiliser un modèle rendra les choses plus faciles.

-
- -
-

Attention : De nombreux serveurs sont configurés avec une limite de taille pour les fichiers et les requêtes HTTP pour éviter les abus. Il est important de vérifier cette limite avec l'administrateur du serveur avant d'envoyer un fichier.

-
- -

Problèmes courants de sécurité

- -

Chaque fois qu'on envoie des données à un serveur, il faut considérer la sécurité. Les formulaires HTML sont l'un des principaux vecteurs d'attaque (emplacements d'où les attaques peuvent provenir) contre les serveurs. Les problèmes ne viennent jamais des formulaires eux-mêmes — ils proviennent de la façon dont les serveurs gèrent les données.

- -

Selon ce que vous faites, il y a quelques problèmes de sécurité bien connus que vous pouvez aisément contrer :

- -

XSS et CSRF

- -

Les attaques Cross-Site Scripting (XSS) et Cross-Site Request Forgery (CSRF) sont des attaques fréquentes qui surviennent quand vous affichez des données renvoyées par un utilisateur à celui-ci ou à un autre utilisateur. 

- -

XSS permet aux attaquants d'injecter des scripts  côté‑client dans les pages Web vues par d'autres utilisateurs. La vulnérabilité au XSS peut être utilisée par les attaquants pour contourner les contrôles d'accès comme la same-origin policy (ou politique de même origine). Les effets de ces attaques peuvent aller d'une nuisance mineure à un risque significatif de sécurité.

- -

Les attaques CSRF sont similaires aux attaques XSS en ce qu'elles commencent de la même façon — en injectant des scripts côté‑client sur des pages Web — mais leur cible est différente. Les attaquants CSRF essaient d'accroître leurs privilèges pour atteindre ceux d'un utilisateur privilégié (par exemple l'administrateur du site) pour effectuer une action qu'ils ne devraient pas pouvoir faire (par exemple, envoyer des données à un utilisateur non habilité).

- -

Les attaques XSS exploitent la confiance qu'un utilisateur a pour un site, alors que les attaques  CSRF exploitent la confiance qu'un site a pour ses utilisateurs.

- -

Pour éviter ces attaques, vous devez toujours vérifier les données qu'un utilisateur envoie à votre serveur et (si vous avez besoin de les afficher) essayez de ne pas afficher le contenu HTML tel que fourni par l'utilisateur. A la place, vous devez traiter les données fournies par l'utilisateur afin de ne pas les afficher verbatim. La quasi totalité des modèles du marché implémentent un filtre minimum qui enlève les éléments {{HTMLElement("script")}}, {{HTMLElement("iframe")}} et {{HTMLElement("object")}} des données envoyées par les utilisateurs. Cela permet d'atténuer les risques sans toutefois les éradiquer.

- -

Injection SQL

- -

L'injection SQL est un type d'attaque qui essaie d'effectuer certaines actions sur les bases de données utilisées par le site web cible. Cela consiste d'ordinaire à envoyer une requête SQL en espérant que le serveur l'exécutera (généralement quand le serveur essaie de ranger les informations envoyées par un utilisateur). C'est assurément l'un des vecteurs d'attaque les plus fréquents contre les sites web.

- -

Les conséquences peuvent être terribles, de la perte de données à l'accès à l'infrastructure en utilisant l'augmentation des privilèges. C'est une menace sérieuse et vous ne devez jamais ranger des données envoyées par un utilisateur sans asepsie préalable (par exemple en utilisant mysql_real_escape_string() sur une infrastructure PHP/MySQL).

- -

Injection d'en-tête HTTP et injection d'email

- -

Ces attaques peuvent arrivent quand votre application construit des en-têtes HTTP ou des emails basés sur les données entrées par un utilisateur sur un formulaire. Elles ne vont pas directement endommager votre serveur ou affecter vos utilisateurs mais elles sont la porte ouverte à des problèmes plus graves comme le piratage de session ou les attaques par hameçonnage (phishing).

- -

Ces attaques sont généralement silencieuses et peuvent transformer votre serveur en zombie.

- -

Soyez paranoïaque : ne faites jamais confiances à vos utilisateurs

- -

Alors, comment combattre ces menaces ? Ce sujet va bien au-delà de ce guide mais il y a quelques règles à garder en tête. La principale est de ne jamais faire confiance à ses utilisateurs, vous-même compris : même un utilisateur de confiance peut s'être fait pirater.

- -

Toute donnée qui va dans un serveur doit être vérifiée et nettoyée. Toujours. Sans exception.

- - - -

Vous devriez vous éviter beaucoup de problèmes en suivant ces trois règles, mais cela reste néanmoins une bonne idée de faire un examen de sécurité auprès d'une tierce personne compétente. Ne pensez pas, à tort, avoir anticipé tous les problèmes de sécurité !

- -
-

Note : L'article « Sécurité des sites Web » de notre sujet d'apprentissage « côté‑serveur » discute les problèmes ci‑dessus et leurs solutions possibles plus en détail.

-
- -

Conclusion

- -

Comme vous pouvez le voir, envoyer un formulaire est facile, mais sécuriser son application peut s'avérer plus délicat. N'oubliez pas qu'un développeur n'est pas celui qui doit définir le modèle de sécurité des données. Comme nous allons le voir, il est possible d'effectuer la validation des données côté client, mais le serveur ne peut pas faire confiance à cette validation car il n'a aucun moyen de savoir ce qui se passe réellement du côté client.

- -

Voir aussi

- -

Si vous voulez en savoir plus par rapport aux applications web, vous pouvez consulter ces ressources :

- - - -
-
{{PreviousMenuNext("Web/Guide/HTML/Formulaires/Les_blocs_de_formulaires_natifs", "Web/Guide/HTML/Formulaires/Validation_donnees_formulaire", "Web/Guide/HTML/Formulaires")}}
-
- -

Dans ce module

- - diff --git a/files/fr/web/guide/html/formulaires/html_forms_in_legacy_browsers/index.html b/files/fr/web/guide/html/formulaires/html_forms_in_legacy_browsers/index.html deleted file mode 100644 index 6c1d043659..0000000000 --- a/files/fr/web/guide/html/formulaires/html_forms_in_legacy_browsers/index.html +++ /dev/null @@ -1,220 +0,0 @@ ---- -title: Formulaires HTML dans les navigateurs historiques -slug: Web/Guide/HTML/Formulaires/HTML_forms_in_legacy_browsers -translation_of: Learn/Forms/HTML_forms_in_legacy_browsers ---- -
{{LearnSidebar}}{{PreviousMenuNext("Web/Guide/HTML/Formulaires/Sending_forms_through_JavaScript", "Web/Guide/HTML/Formulaires/Apparence_des_formulaires_HTML", "Web/Guide/HTML/Formulaires")}}
- -

Tout développeur apprend très rapidement (parfois difficilement) que le Web est un endroit assez inconfortable. Le pire des fléaux est le « navigateur historique ». Oui, admettons‑le, si on dit « navigateur historique », nous pensons tous aux anciennes versions d'Internet Explorer ... mais elles sont loin d'être les seules. Les premières versions de Firefox, comme la version ESR, sont aussi des « navigateurs historiques ». Et dans le monde du mobile ? Quand ni le navigateur ni l'OS ne peut être mis à jour? Oui, il y a beaucoup de vieux smartphones Android ou des iPhones dont le navigateur par défaut n'est pas à jour. Ceux-ci sont aussi des « navigateurs historiques ».

- -

Malheureusement, parcourir cette jungle est une facette du métier. Mais opportunément, il existe quelques astuces pour nous aider à résoudre 80 % des problèmes causés par ces vieilles versions de navigateur.

- -

S'informer sur les difficultés

- -

En fait, lire la documentation sur ces navigateurs est la chose la plus importante pour essayer de comprendre les modèles communs. Par exemple, la prise en charge des CSS est un problème majeur du formulaire HTML dans la plupart des cas. Vous êtes au bon endroit pour commencer. Il suffit de vérifier la prise en charge des éléments (ou interface DOM) que vous voulez utiliser. MDN dispose de tables de compatibilité pour de nombreux éléments, propriétés ou API pouvant être utilisées dans une page Web. Mais il existe d'autres ressources étonnamment utiles :

- -

Documentation du fournisseur du navigateur

- - - -

Documentation indépendante

- - - -

Rendre les choses simples

- -

 

- -

Comme les formulaires HTML impliquent des interactions complexes, une règle empirique : restez aussi simple que possible. Il y a tant de cas où nous voudrions que des formulaires soient  « plus beaux » ou « avec des fonctionnalités avancées » ! Mais construire des formulaires HTML efficaces n'est pas une question de design ou de technique. Pour rappel, prenez le temps de lire cet article sur l'ergonomie des formulaires sur UX For The Masses (en anglais).

- -

La simplification élégante est la meilleure amie du développeur Web

- -

Une simplification élégante et des améliorations progressives sont des modèles de développement qui permettent de construire des grands projets prenant en charge une large gamme de navigateurs simultanément. Quand vous créez quelque chose pour un navigateur moderne, et que vous voudriez être sûrs que, l'un l'autre, il fonctionne sur des navigateurs historiques, vous faites de la simplification élégante.

- -

Voyons quelques exemples relatifs aux formulaires en HTML.

- -

Types d'entrées en HTML

- -

Les nouveaux types d'entrées amenés par HTML5 sont très sympas car la façon dont ils simplifient est grandement prévisible. Si un navigateur ne connaît pas la valeur de l'attribut {{htmlattrxref("type","input")}} d'un élément {{HTMLElement("input")}}, il prendra une valeur text en recours.

- -
<label for="myColor">
- Choisir une couleur
-  <input type="color" id="myColor" name="color">
-</label>
- - - - - - - - - - - - - - -
Chrome 24Firefox 18
Capture d'écran de l'entrée de couleur sur Chrome pour Mac OSXCapture d'écran de l'entrée de couleur sur Firefox
- -

Sélecteurs d'attributs CSS

- -

Les sélecteurs d'attributs CSS sont très utiles avec les formulaires HTML, mais certains navigateurs historiques ne les prennent pas en charge. Dans ce cas, il est courant de doubler le type avec une classe équivalente :

- -
<input type="number" class="number">
- -
input[type=number] {
-  /* Ceci peut échouer avec certains navigateurs */
-}
-
-input.number {
-  /* Ceci fonctionne partout */
-}
- -

Notez que ce qui suit n'est pas utile (car redondant) et peut échouer dans certains navigateurs :

- -
input[type=number],
-input.number {
-  /* Ceci peut échouer dans certains navigateurs ; s'il ne comprennent pas
-     l'un des sélecteurs, il sautent la totalité de la règle */
-}
- -

Boutons et formulaires

- -

Il y a deux manières de définir un bouton dans un formulaire HTML :

- - - -

L'élément {{HTMLElement("input")}} peut rendre les choses compliquées si vous voulez appliquer des CSS avec un sélecteur d'élément :

- -
<input type="button" class="button" value="Cliquez‑moi">
- -
input {
-  /* Cette règle annule le rendu par défaut défini avec un élément input */
-  border: 1px solid #CCC;
-}
-
-input.button {
-  /* Le rendu par défaut N'EST PAS restauré avec ceci */
-  border: none;
-}
-
-input.button {
-  /* Avec ceci non plus ! En fait, il n'y a pas de méthode standard pour
-     le faire quel que soit le navigateur */
-  border: auto;
-}
- -

L'élément {{HTMLElement("button")}} présente deux problèmes potentiels :

- - - -
<!-- Cliquer sur ce boutton envoie « <em>Do A</em> » au lieu de « A » dans certains cas -->
-<button type="submit" name="IWantTo" value="A">
-  <em>Do A</em>
-</button>
- -

Le choix de l'une ou l'autre solution vous appartient, selon les contraintes du projet.

- -

Laissez tomber les CSS

- -

Le plus gros problème avec les formulaires HTML et les navigateurs historiques est la prise en charge des CSS. Comme vous pouvez le constater, vu la complexité de la Table de compatibilité des propriétés pour les widgets de formulaire, c'est très difficile. Même s'il est toujours possible de faire quelques ajustements sur les éléments de texte (comme la taille ou la couleur de police), il y a toujours des effets secondaires. La meilleure approche reste de ne faire aucune composition des widgets de formulaire HTML. Mais vous pouvez toujours appliquer des styles à tous les éléments environnants. Si vous êtes un professionnel et que votre client le réclame, dans ce cas, vous pouvez étudier certaines techniques difficiles telles que la construction de widgets avec JavaScript. Mais dans ce cas, n'hésitez pas à facturer votre client pour ce caprice.

- -

Détection de fonctionnalité et prothèses d'émulation (polyfills)

- -

Bien que JavaScript soit un langage de programmation remarquable pour les navigateurs modernes, les navigateurs historiques ont de nombreux problèmes avec cette technique.

- -

JavaScript non obstructif

- -

Un des plus gros problèmes est la disponibilité des API. Pour cette raison, il est considéré comme de bonne pratique de travailler avec du JavaScript « non obstructif ». C'est un modèle de développement défini par deux obligations :

- - - -

Les principes d'un JavaScript non obstructif (écrit à l'origine par Peter-Paul Koch pour Dev.Opera.com et maintenant mis sur Docs.WebPlatform.org) descrit très bien ces idées.

- -

La bibliothèque Modernizr

- -

Dans de nombreux cas, une bonne prothèse d'émulation (« polyfill ») peut aider en fournissant une API manquante. Un « polyfill » est un petit morceau de JavaScript qui « remplit un trou » dans les fonctionnalités des navigateurs historiques. Bien qu'ils puissent être utilisés pour améliorer la prise en charge de n'importe quelle fonctionnalité, leur utilisation dans le JavaScript est moins risquée que dans les CSS ou le HTML ; il existe de nombreux cas où JavaScript peut casser (problèmes de réseau, conflits de script, etc.). Mais avec le JavaScript, à condition de travailler avec un JavaScript non obstructif, si les polyfills manquent, ce ne sera pas grave.

- -

La meilleure façon de remplir un trou d'API manquante consiste à utiliser la bibliothèque Modernizr et son projet dérivé : YepNope. Modernizr est une bibliothèque qui vous permet de tester la disponibilité d'une fonctionnalité pour une action en accord. YepNope est une bibliothèqe de chargements conditionnels.

- -

Voici un exemple :

- -
Modernizr.load({
-  // Cette ligne teste si le navigateur prend en charge l'API
-  // de validation de formulaires HTML5
-  test : Modernizr.formvalidation,
-
-  // Si ce n'est pas le cas, le polyfill suivant sera chargé
-  nope : form-validation-API-polyfill.js,
-
-  // En tout cas, le fichier au cœur de l'application, et dont elle dépend,
-  // est chargé
-  both : app.js,
-
-  // Une fois les deux fichiers chargés, cette fonction est appelée
-  // dans le but d'initialiser l'application
-  complete : function () {
-    app.init();
-  }
-});
- -

L'équipe de Modernizr fait une maintenance opportune de grande liste de « polyfills ». Prenez celui dont vous avez besoin.

- -
-

Note : Modernizr a d'autres fonctionnalités remarquables pour faciliter le traitement du JavaScript non obstructif et les tecniques de simplifications élégantes. Prenez connaissance de  la documentation de Modernizr.

-
- -

Faites attention aux performances

- -

Même si des scripts comme Modernizr sont très attentifs aux performances, le chargement d'un polyfill de 200 kilooctets peut affecter les performances de votre application.  Ceci est particulièrement critique avec les navigateurs historiques ; beaucoup d'entre eux ont un moteur JavaScript très lent qui peut rendre l'exécution de tous vos polyfills pénibles pour l'utilisateur. La performance est un sujet en soi ; les navigateurs historiques y sont très sensibles : fondamentalement, ils sont lents et ils ont plus besoin de polyfills, et donc ils ont besoin de traiter encore plus de JavaScript. Ils sont donc doublement surchargés par rapport aux navigateurs modernes. Testez votre code avec les navigateurs historiques pour voir comment leur fonctionnement en conditions réelles. Parfois, l'abandon de certaines fonctionnalités amène un meilleur ressenti pour l'utilisateur que d'avoir exactement la même fonctionnalité dans tous les navigateurs. Dernier rappel : pensez toujours à l'utilisateur final.

- -

Conclusion

- -

Comme vous pouvez le constater, opérer avec des navigateurs historiques  n'est pas qu'une question de formulaires. C'est tout un ensemble de techniques ; mais les maîtriser toutes dépasserait le cadre de cet article.

- -

Si vous avez lu tous les articles de ce guide à propos des formulaires en HTML, vous devriez maintenant être à l'aise avec leur utilisation. Si vous trouvez de nouvelles techniques ou de nouvelles astuces, aidez‑nous à améliorer ce guide.

- -

{{PreviousMenuNext("Web/Guide/HTML/Formulaires/Sending_forms_through_JavaScript", "Web/Guide/HTML/Formulaires/Apparence_des_formulaires_HTML", "Web/Guide/HTML/Formulaires")}}

- -

Dans ce module

- - diff --git a/files/fr/web/guide/html/formulaires/index.html b/files/fr/web/guide/html/formulaires/index.html deleted file mode 100644 index 9927bd3385..0000000000 --- a/files/fr/web/guide/html/formulaires/index.html +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: Formulaires HTML -slug: Web/Guide/HTML/Formulaires -tags: - - Apprentissage - - Featured - - Formulaires - - Guide - - HTML - - Web -translation_of: Learn/Forms ---- -

{{learnSidebar}}

- -
-

Ce guide est constitué d'une série d'articles qui vous aideront à maîtriser les formulaires HTML. Les formulaires HTML sont des outils très puissants pour interagir avec l'utilisateur ; toutefois, à cause de raisons historiques et techniques, il n'est pas forcément évident de savoir comment les utiliser de manière optimale. Nous allons aborder tous les aspects des formulaires HTML, de la structure à la décoration, de la gestion des données aux widgets sur-mesure.

-
- -

Prérequis

- -

Avant de vous lancer dans  ce module, vous devez au moins avoir travaillé notre Introduction au HTML. À partir de là, vous devriez trouver les {{anch("Éléments de base")}} faciles à comprendre et également être capable de vous servir du guide pour  les widgets natifs pour formulaire.

- -

Le reste du module est toutefois un peu plus difficile — il est facile de placer des widgets de formulaire dans une page, mais vous ne pourrez pas en faire vraiment quelque chose sans utiliser quelques fonctionnalités plus avancées, les CSS et le JavaScript. C'est pourquoi, avant de regarder ces autres parties, nous vous recommandons de faire un détour et de procéder d'abord à l'étude des CSS et du JavaScript.

- -
-

Note : Si vous travaillez sur un ordinateur/tablette/autre appareil sur lequel vous n'avez pas la possiblité de créer vos propres fichiers, vous pourrez essayer (la pluspart) des exemples de code sur un programme de codage en ligne comme JSBin ou Thimble.

-
- -

Éléments de base

- -
-
Mon premier formulaire HTML
-
Le premier article de notre série vous donne une toute première expérience de création de formulaire en HTML, y compris sa conception, sa mise en œuvre en utilisant les bons éléments HTML, l'ajout de quelques très simples décorations avec les CSS et le comment de l'envoi des données à un serveur.
-
Comment structurer un formulaire HTML
-
Les bases vues, nous examinons maintenant plus en détail les éléments utilisés pour structurer et donner un sens aux différentes parties d'un formulaire.
-
- -

Quels sont les widgets pour formulaire disponibles ?

- -
-
Les widgets natifs pour formulaire
-
Nous examinons maintenant en détail les fonctionnalités des widgets pour formulaire, en regardant quelles sont les options disponibles pour collecter différentes types de données.
-
- -

Validation et soumission des données de formulaires

- -
-
Envoi des données de formulaire
-
Cet article examine ce qui arrive quand un utilisateur soumet un formulaire — où les données vont-elles et comment les gère-t-on une fois à destination ? Nous examinerons aussi quelques problèmes de sécurité associés à l'envoi des données d'un formulaire.
-
Validation des données de formulaire
-
Ce n'est pas tout d'envoyer des données — il faut aussi s'assurer que les données mises dans un formulaire par un utilisateur sont de format correct pour pouvoir les traiter correctement et qu'elles ne vont pas casser nos applications. Nous voulons également aider les utilisateurs à compléter les formulaires correctement et à ne pas ressentir de frustration en essayant d'utiliser nos applications. La validation et la soumission des données des formulaires vous aidera à remplir ces objectifs — cet article indique ce qui est nécessaire de savoir.
-
- -

Guides avancés

- -
-
Comment construire des widgets de formulaires personnalisés
-
Nous allons voir quelques cas où les widgets natifs ne donnent pas ce dont vous avez besoin, pour des raisons fonctionnelles ou de style par exemple. Dans de tels cas, vous pouvez avoir besoin de construire vous même un widget de formulaire en dehors du HTML brut. Cet article explique comment faire, ainsi que les considérations à prendre en compte ce faisant, le tout à l'aide de l'étude d'un cas particulier.
-
Envoi de formulaires à l'aide du JavaScript
-
Cet article examine les manières d'utiliser un formulaire pour assembler une requête HTTP et l'adresser par l'intermédiaire d'un JavaScript personnalisé, au lieu d'une soumission standard de formulaire. Il examine aussi pourquoi vous pouvez souhaiter faire ainsi et ce que cela implique corrélativement. (Voir aussi « Utilisation des objets FormData ».)
-
Formulaires HTML dans les navigateurs anciens
-
Cet article couvre les détections de fonctionnalité, etc. Elles doivent être redirigées dans le module de tests croisés entre navigateurs, car la même problématique y sera mieux traitée.
-
- -

Guides de mise en forme des formulaires

- -
-
Mise en forme des formulaires HTML
-
Cet article est une introduction à la mise en forme des formulaires à l'aide des CSS, y compris tous les éléments de base qu'il est nécessaire de connaître pour les tâches de décoration élémentaires.
-
Mise en forme avancée des formulaires HTML
-
Dans cet article, nous regarderons des techniques de mise en forme plus avancées qu'il est nécessaire d'utiliser pour opérer sur les éléments les plus difficiles à traiter.
-
Tableau de compatibilité des propriétés entre widgets de formulaire
-
Ce dernier article fournit un référentiel pratique vous permettant de rechercher quelles propriétés des CSS sont compatibles avec tel ou tel élément de formulaire.
-
- -

Voir aussi

- - diff --git a/files/fr/web/guide/html/formulaires/les_blocs_de_formulaires_natifs/index.html b/files/fr/web/guide/html/formulaires/les_blocs_de_formulaires_natifs/index.html deleted file mode 100644 index 6b692ee256..0000000000 --- a/files/fr/web/guide/html/formulaires/les_blocs_de_formulaires_natifs/index.html +++ /dev/null @@ -1,683 +0,0 @@ ---- -title: Les widgets de formulaire natifs -slug: Web/Guide/HTML/Formulaires/Les_blocs_de_formulaires_natifs -tags: - - Contrôles - - Exemple - - Formulaires - - Guide - - HTML - - Web - - Widgets -translation_of: Learn/Forms/Basic_native_form_controls ---- -
{{LearnSidebar}}
-{{PreviousMenuNext("Web/Guide/HTML/Formulaires/Comment_structurer_un_formulaire_HTML", "Web/Guide/HTML/Formulaires/Envoyer_et_extraire_les_données_des_formulaires", "Web/Guide/HTML/Formulaires")}}
- -

Nous examinerons maintenant en détail les fonctionnalités des divers widgets pour formulaires, en soulignant les options disponibles pour collecter les différents types de données. Ce guide vise à être exhaustif en couvrant tous les widgets natifs de formulaire disponibles.

- - - - - - - - - - - - -
Prérequis :Notions concernant les ordinateurs et les connaissances de base du HTML.
Objectif :Comprendre quels sont les types de widgets de forme native disponibles dans les navigateurs pour collecter des données et comment les mettre en œuvre en se servant du HTML.
- -

Ici, nous nous attarderons sur les widgets de formulaires intégrés aux navigateurs, mais comme les formulaires HTML restent très circonscrits et que la qualité des implémentations peut être très différente d'un navigateur à l'autre, les développeurs web construisent parfois leurs propres widgets de formulaires — voir Comment construire des widgets de formulaires personnalisés plus loin dans ce même module pour plus d'idées à ce propos.

- -
-

Note : La plupart des fonctionnalités discutées dans cet article sont abondamment explicitées dans les navigateurs ; nous soulignerons les exceptions à ce sujet. Si vous voulez plus de précisions, consultez les références aux éléments de formulaires HTML, et en particulier nos références détaillées aux types <input>.

-
- -

Attributs communs

- -

Beaucoup d'éléments utilisés pour définir les widgets de formulaire ont leurs propres attributs. Cependant, il y a un jeu d'attributs communs à tous les éléments de formulaire. Il vous permettent un certain contrôle sur ces widgets. Voici une liste de ces attributs communs :

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Nom de l'attributValeur par défautDescription
autofocus(false)Cet attribut, booléen, vous permet de spécifier que cet élément doit avoir automatiquement le focus au chargement de la page, sauf si l'utilisateur prend la main, en faisant, par exemple, une saisie dans un autre contrôle. Seul un élément associé à un formulaire peut avoir cet attribut activé.
disabled(false)Cet attribut est un booléen. Il indique que l'utilisateur ne peut pas avoir d'action sur cet élément. S'il n'est pas précisé, l'élément hérite son comportement de l'élément contenant, comme, {{HTMLElement("fieldset")}} ; si le conteneur n'a pas d'attribut disabled mis, l'élément est activé.
formL'élément <form> auquel le widget est associé. La valeur de l'attribut doit être l'attribut id d'un élément {{HTMLElement("form")}} dans le même document. En théorie, il vous permet de mettre un widget en dehors d'un élément {{HTMLElement("form")}}. En pratique, toutefois, il n'y a pas de navigateur qui prenne en charge cette fonctionnalité.
nameLe nom de l'élément ; il sera soumis en même temps que les données du formulaire.
valueLa valeur initiale de l'élément.
- -

Champs de saisie de texte

- -

Les champs {{htmlelement("input")}} de saisie de texte sont les widgets de formulaire les plus élémentaires. Ils sont très pratiques pour permettre à un utilisateur de saisir n'importe quel type de données. Toutefois, certains champs textuels peuvent être spécialisés pour répondre à des besoins précis. Nous avons déjà vu quelques exemples.

- -
-

Note : Les champs textuels dans les formulaires HTML sont des contrôles de saisie de texte brut. Cela signifie que vous ne pouvez pas les utiliser pour réaliser de la mise en forme riche (gras, italique, etc.). Tous les éditeurs de textes évolués que vous rencontrez utilisent des widgets personnalisés créés avec HTML, CSS et JavaScript.

-
- -

Tous les champs textuels ont des comportement en commun :

- - - -
-

Note : L'élément {{htmlelement("input")}} est spécial car il peut être pratiquement n'importe quoi. En réglant simplement ses attributs de type, il peut changer radicalement, et il est utilisé pour créer la plupart des types de widgets de formulaire allant des champs texte sur une seule ligne, contrôles sans entrée de texte, contrôles de date et heure jusqu'aux boutons. Il y a toutefois des exceptions, comme {{htmlelement("textarea")}} pour les entrées multi-lignes. Prenez bien note de ceci en lisant cet article.

-
- -

 Champs texte sur une seule ligne

- -

On crée un champ texte sur une seule ligne avec l'élément {{HTMLElement("input")}} dont l'attribut {{htmlattrxref("type", "input")}} est mis à text (maisi, si vous n'indiquez pas l'attribut {{htmlattrxref("type", "input")}}, text est la valeur par défaut). text est aussi la valeur de repli si celle indiquée pour l'attribut {{htmlattrxref("type", "input")}} est inconnue du navigateur (par exemple, si vous spécifiez type="date" et que le navigateur ne prend pas en charge les sélecteurs de date natifs).

- -
-

Note : Vous trouverez des exemples de tous les types de champ texte sur une ligne dans GitHub à single-line-text-fields.html (voir directement aussi).

-
- -

Voici un exemple élémentaire de champ texte sur une ligne :

- -
<input type="text" id="comment" name="comment" value="Je suis un champ texte">
- -

Les champs texte sur une ligne n'ont qu'une seule contrainte : si vous saisissez du texte avec des sauts de ligne, le navigateur les supprime avant d'envoyer les données.

- -

Screenshots of single line text fields on several platforms.

- -

HTML5 améliore le champ texte élémentaire sur une ligne par ajout de valeurs spéciales pour l'attribut {{htmlattrxref("type","input")}}. Ces valeurs conservent l'élément {{HTMLElement("input")}} en tant que champ texte sur une ligne mais ajoutent quelques contraintes et caractéristiques supplémentaires au champ.

- -

Champ d'adresse électronique

- -

Ce type de champ est défini en donnant la valeur email à l'attribut {{htmlattrxref("type","input")}} :

- -
    <input type="email" id="email" name="email" multiple>
- -

Avec ce type , l'utilisateur doit saisir un e‑mail valide dans le champ. Tout autre type de contenu amène le navigateur à émettre une erreur lors de la soumission du formulaire. Notez que cette validation s'opère côté client et est faite par le navigateur :

- -

Entrée d'un e-mail non valide déclenchant un message d'avertissement « Veuillez saisir une adresse électronique valide »

- -

Avec l'attribut {{htmlattrxref("multiple","input")}}, l'utilisateur pourra saisir plusieurs adresses électroniques dans la même entrée (avec une virgule comme séparateur).

- -

Sur certains périphériques (les mobiles en particulier), un clavier virtuel différent et mieux adapté à la saisie d'adresses électroniques peut être affiché.

- -
-

Note: Vous trouverez plus de détails sur la validation des formulaires dans l'article Validation des données de formulaires.

-
- -

Champ pour mot de passe

- -

Ce type de champ est défini en donnant la valeur password à l'attribut {{htmlattrxref("type","input")}} :

- -
    <input type="password" id="pwd" name="pwd">
- -

Aucune contrainte de saisie du texte n'est ajoutée, mais la valeur entrée dans le champ est masquée (avec des points ou des astérisques) afin qu'elle ne puisse pas être lue par d'autres.

- -

Gardez à l'esprit que ceci n'est qu'une fonction de l'interface utilisateur ; sauf si vous soumettez le formulaire de manière sécurisée, il sera envoyé en texte brut, ce qui est mauvais pour la sécurité — un tiers malicieux pourrait intercepter les données et voler le mot de passe, les détails de la carte de crédit ou autre texte soumis. La meilleure façon de protéger l'utilisateur contre ceci consiste à héberger toute page contenant des formulaires avec une connexion sécurisée (par ex. avec https:// ...), ainsi les données sont chiffrées avant expédition.

- -

Les navigateurs modernes reconnaissent les risques courus lors de l'envoi de formulaires avec une connexion non sécurisée et affichent des avertissements pour prévenir les utilisateurs. Pour plus de précisions sur ce que Firefox a mis en œuvre, voir Mots de passe peu sûrs.

- -

Champ de recherche

- -

Ce type de champ se définit avec la valeur search de l'attribut {{htmlattrxref("type","input")}} :

- -
    <input type="search" id="search" name="search">
- -

La principale différence entre un champ textuel et un champ de recherche est dans l'apparence — souvent, les champs de recherche sont affichés avec des coins arrondis, et/ou avec une « × » à cliquer pour effacer la valeur entrée. Toutefois, une fonction est aussi ajoutée : les valeurs saisies peuvent être automatiquement enregistrées afin d'être utilisées pour compléter des recherches sur plusieurs pages du même site.

- -

Screenshots of search fields on several platforms.

- -

Champ pour numéro de téléphone

- -

Ce type de champ se définit en donnant la valeur tel à l'attribut {{htmlattrxref("type","input")}} :

- -
    <input type="tel" id="tel" name="tel">
- -

À cause de la grande variété de formats de numéros de téléphones à travers le monde, ce type de champ n'ajoute pas de contrainte à la valeur saisie par l'utilisateur. C'est principalement une différence sémantique, bien que sur certains appareils (notamment mobiles) un clavier virtuel différent, mieux adapté à la saisie de numéros de téléphone, puisse être présenté.

- -

Champ d'URL

- -

Ce type de champ se définit en donnant la valeur url à l'attribut {{htmlattrxref("type","input")}} :

- -
    <input type="url" id="url" name="url">
- -

Il ajoute une contrainte de validation spéciale du champ ; le navigateur renvoie une erreur si une URL invalide est saisie.

- -
Note : ce n'est pas parce qu'une URL est bien formée qu'elle pointe vers un emplacement qui existe réellement.
- -
-

Note : La présence de champs avec contraintes spéciales considérés comme erronés bloquent l'envoi du formulaire. De plus, leur apparence peut être adaptée afin de mettre en évidence l'erreur. Nous allons discuter de cela dans l'article Validation de formulaires.

-
- -

Champs texte multilignes

- -

Un champ texte sur plusieurs lignes  se définit avec l'élément {{HTMLElement("textarea")}}, et non avec l'élément {{HTMLElement("input")}}.

- -
    <textarea cols="30" rows="10"></textarea>
- -

La principale différence entre un champ textarea et un champ monoligne est que, dans un textarea, l'utilisateur peut saisir du texte avec des sauts de ligne en dur (c'est à dire en pressant la touche Retour).

- -

Screenshots of multi-lines text fields on several platforms.

- -
-

Note : Vous trouverez un exemple de champ texte multiligne sur GitHub à l'adresse multi-line-text-field.html (voir aussi directement). Jetez-y un coup d'œil, et remarquez que dans la plupart des navigateurs, la zone de texte est dotée d'une poignée d'étirement en bas à droite pour permettre à l'utilisateur de la redimensionner. Cette capacité de redimensionnement peut être désactivée en réglant la propriété {{cssxref("resize")}} de la zone de texte à none dans les CSS.

-
- -

{{htmlelement("textarea")}} accepte également quelques attributs pour contrôler son rendu sur plusieurs lignes  (outre plusieurs autres) :

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
Attributs pour l'élément {{HTMLElement("textarea")}}
Nom de l'attributValeur par défautDescription
{{htmlattrxref("cols","textarea")}}20Largeur visible de la boîte de contrôle texte, mesurée en largeurs de caractères.
{{htmlattrxref("rows","textarea")}}Nombre de lignes de texte visibles dans la boîte de contrôle.
{{htmlattrxref("wrap","textarea")}}softIndique comment le contrôle va à la ligne. Les valeurs possibles sont : hard ou soft
- -

Notez que l'élément {{HTMLElement("textarea")}} est écrit un peu différemment de l'élément {{HTMLElement("input")}}. Ce dernier est un élément vide, ce qui signifie qu'il ne peut pas contenir d'élément enfant. A contrario, l'élément {{HTMLElement("textarea")}} est un élément régulier pouvant contenir des enfants contenus de texte.

- -

Deux points clés à noter ici :

- - - -

Contenu déroulant

- -

Les widgets déroulants sont une manière simple de permettre à l'utilisateur de choisir une option parmi plusieurs sans que cela prenne trop de place dans l'interface utilisateur. HTML dispose de deux types de contenus déroulants la boîte à sélections et la boîte à complétement automatique. Dans les deux cas l'interation est identique. Une fois le contrôle activé, le navigateur affiche une liste de valeurs ouverte au choix de l'utilisateur.

- -

Boîte à sélection

- -

Une boîte à sélection est créée avec l'élément {{HTMLElement("select")}} complétée d'un ou plusieurs éléments enfants {{HTMLElement("option")}} définissant les valeurs possibles.

- -
    <select>
-      <option>Banane</option>
-      <option>Cerise</option>
-      <option>Citron</option>
-    </select>
- -

Si nécessaire, la valeur par défaut de la boîte de sélection peut être définie en utilisant l'attribut {{htmlattrxref("selected","option")}} dans l'élément {{HTMLElement("option")}} désiré. Les éléments {{HTMLElement("option")}} peuvent être imbriqués dans des éléments {{HTMLElement("optgroup")}} pour créer des groupes de valeurs associées :

- -
    <select>
-      <optgroup label="Fruits">
-        <option>Banane</option>
-        <option selected>Cerise</option>
-        <option>Citron</option>
-      </optgroup>
-      <optgroup label="Légumes">
-        <option>Carotte</option>
-        <option>Aubergine</option>
-        <option>Pomme de terre</option>
-      </optgroup>
-    </select>
- -

Screenshots of single line select box on several platforms.

- -

Si un élément {{HTMLElement("option")}} est défini avec l'attribut value, la valeur de cet attribut est envoyée lorsque le formulaire est soumis. Si l'attribut value est omis, le contenu de l'élément {{HTMLElement("option")}} est utilisé comme valeur de la boîte de sélection.

- -

Sur l'élément {{HTMLElement("optgroup")}}, l'attribut label est affiché avant les valeurs, mais même s'il ressemble un peu à une option, il n'est pas sélectionnable.

- -

Boîte à sélections multiples

- -

Par défaut, une boîte de sélection ne permet à l'utilisateur de ne sélectionner qu'une seule valeur. En ajoutant l'attribut {{htmlattrxref("multiple","select")}} à l'élément {{HTMLElement("select")}}, l'utilisateur peut sélectionner plusieurs valeurs en utilisant le mécanisme par défaut du système d'exploitation (par ex. en pressant Cmd/Ctrl et en cliquant sur plusieur valeurs).

- -

Dans ce cas toutefois, la boîte d'utilisateur n'affiche plus les valeurs sous forme d'un menu déroulant. Les valeurs sont toutes affichées dans une liste.

- -
    <select multiple>
-      <option>Banane</option>
-      <option>Cerise</option>
-      <option>Citron</option>
-    </select>
- -

Screenshots of multi-lines select box on several platforms.

- -
Note : tous les navigateurs prenant en charge l'élément {{HTMLElement("select")}} prennent aussi en charge l'attribut {{htmlattrxref("multiple","select")}} sur lui.
- -

Contenus auto-complétés

- -

Vous pouvez suggérer des valeurs d'auto-complémentation pour les widgets avec un élément {{HTMLElement("datalist")}} accompagné d'éléments enfants {{HTMLElement("option")}} précisant les valeurs à afficher.

- -

La liste de données est alors liée à un champ texte (généralement un élément input) avec l'attribut {{htmlattrxref("list","input")}}.

- -

Une fois la liste de données affiliée au widget de formulaire, ses options s'utilisent comme complémentation du texte saisi par l'utilisateur ; cela se présente généralement à l'utilisateur sous forme d'une boîte déroulante listant des correspondances possibles avec ce qui doit être saisi dans la boîte.

- -
    <label for="onFruit">Quel est votre fruit préféré ?</label>
-    <input type="text" id="onFruit" list="maSuggestion" />
-    <datalist id="maSuggestion">
-      <option>Pomme</option>
-      <option>Banane</option>
-      <option>Mûre</option>
-      <option>Airelles</option>
-      <option>Citron</option>
-      <option>Litchi</option>
-      <option>Pêche</option>
-      <option>Poire</option>
-    </datalist>
- -
Note : Selon la norme HTML, l'attribut {{htmlattrxref("list","input")}} et l'élément {{HTMLElement("datalist")}} peuvent s'utiliser avec tout type de widget nécessitant une saisie utilisateur. Toutefois, les modalités de ce fonctionnement ne sont pas claire pour des contrôles autres que textuels (de couleur ou de date par ex.) et les divers navigateurs se comporteront de manière différente selon le cas. Pour cette raison, soyez prudent en utilisant cette fonctionnalité avec autre chose que des champs textuels.
- -
Screenshots of datalist on several platforms.
- -
-

Prise en charge de Datalist et recours

- -

L'élément {{HTMLElement("datalist")}} est un ajout très récent aux formulaires HTML, donc sa prise en charge par les navigateurs est un peu plus limitée que ce que nous avons vu précédemment. En particulier, il n'est pas pris en charge dans les versions d'IE inférieures à 10, et Safari ne le prend toujours pas en charge au moment de la rédaction de cet article.

- -

Pour gérer cela, voici une petite astuce offrant une bonne solution de repli pour ces navigateurs :

- -
<label for="myFruit">Quel est votre fruit préféré ? (avec repli)</label>
-<input type="text" id="myFruit" name="fruit" list="fruitList">
-
-<datalist id="fruitList">
-  <label for="suggestion">ou choisissez un fruit</label>
-  <select id="suggestion" name="altFruit">
-    <option>Pomme</option>
-    <option>Banane</option>
-    <option>Mûres</option>
-    <option>Airelles</option>
-    <option>Citron</option>
-    <option>Litchi</option>
-    <option>Pêche</option>
-    <option>Poire</option>
-  </select>
-</datalist>
- -

Les navigateurs qui prennent en charge l'élément {{HTMLElement("datalist")}} ignoreront tous les éléments qui ne sont pas {{HTMLElement("option")}} et fonctionneront comme prévu. D'autre part, les navigateurs qui ne prennent pas en charge l'élément {{HTMLElement("datalist")}} afficheront l'étiquette et la boîte de sélection. Bien sûr, il y a d'autres façons de gérer ce manque de prise en charge de l'élément {{HTMLElement("datalist")}}, mais c'est la manière la plus simple (d'autres ont besoin de JavaScript).

- - - - - - - - - - - - -
Safari 6Screenshot of the datalist element fallback with Safari on Mac OS
Firefox 18Screenshot of the datalist element with Firefox on Mac OS
-
- -

Éléments à cocher

- -

Les éléments à cocher sont des widgets dont l'état se modifie en cliquant sur eux. Il existe deux types d'éléments à cocher : la case à cocher et le bouton radio. Les deux utilisent l'attribut {{htmlattrxref("checked","input")}} pour indiquer si le widget est coché par défaut ou non.

- -

Il est important de noter que ces widgets ne se comportent pas tout à fait comme les autres widgets de formulaires. Pour la plupart des widgets, une fois que le formulaire est envoyé, tous les widgets dont l'attribut {{htmlattrxref("name","input")}} est défini sont envoyés, même s'ils ne sont pas renseignés. Dans le cas des éléments à cocher, leurs valeurs ne sont envoyées que s'ils sont cochés. S'ils ne sont pas cochés, rien n'est envoyé, pas même la valeur de leur attribut name.

- -
-

Note : Vous trouverez les exemples de cette section sur GitHub à l'adresse checkable-items.html (voir directement aussi).

-
- -

Pour un maximum de convivialité/accessibilité, il est conseillé d'entourer chaque liste d'éléments liés dans un {{htmlelement("fieldset")}}, avec un élément {{htmlelement("legend")}} fournissant une description globale de la liste.  Chaque paire individuelle d'éléments {{htmlelement("label")}}/{{htmlelement("input")}} doit être contenue dans son propre élément de liste (ou similaire), comme le montrent les exemples.

- -

Vous devez également fournir des valeurs pour ces types d'entrées dans l'attribut value si vous voulez qu'elles aient un sens — si aucune valeur n'est fournie, les cases à cocher et les boutons radio ont la valeur on.

- -

Case à cocher

- -

Une casce à cocher se crée avec l'élément {{HTMLElement("input")}} dont l'attribut {{htmlattrxref("type","input")}} a pour valeur checkbox.

- -
    <input type="checkbox" checked id="carrots" name="carrots" value="carrots">
-
- -

Mettre l'attribut checked fait que la case sera cochée au chargement de la page.

- -

Screenshots of check boxes on several platforms.

- -

Bouton radio

- -

Un bouton radio se crée avec un élément {{HTMLElement("input")}} dont l'attribut {{htmlattrxref("type","input")}} a la valeur radio.

- -
    <input type="radio" checked id="soup" name="meal">
- -

Plusieurs boutons radio peuvent être liés ensemble. S'ils partagent la même valeur pour leur attribut {{htmlattrxref("name","input")}}, ils seront considérés comme faisant partie d'un seul groupe de boutons. Seulement un bouton à la fois peut être coché par groupe. Ceci signifie que si l'un d'entre eux est coché, tous les autres sont automatiquement décochés. Lorsque le formulaire est envoyé, seule la valeur du bouton coché est envoyée. Si aucun des boutons n'est coché, l'ensemble des boutons du groupe est considéré comme étant dans un état inconnu et aucune valeur n'est envoyée avec le formulaire.

- -
<fieldset>
-  <legend>Quel est votre mets préféré ?</legend>
-  <ul>
-    <li>
-      <label for="soup">Soupe</label>
-      <input type="radio" checked id="soup" name="meal" value="soup">
-    </li>
-    <li>
-      <label for="curry">Curry</label>
-      <input type="radio" id="curry" name="meal" value="curry">
-    </li>
-    <li>
-      <label for="pizza">Pizza</label>
-      <input type="radio" id="pizza" name="meal" value="pizza">
-    </li>
-  </ul>
-</fieldset>
- -

Screenshots of radio buttons on several platforms.

- -

Boutons

- -

Dans les formulaires HTML, il existe trois types de boutons :

- -
-
Submit
-
Envoie les données du formulaire au serveur.
-
Reset
-
Réinitialise les widgets de formulaire à leurs valeurs par défaut.
-
Anonymous
-
Type de bouton n'ayant pas d'effet prédéfini mais qui peut être personnalisé grâce à du code JavaScript.
-
- -

Un bouton se crée avec un élément {{HTMLElement("button")}} ou un élément {{HTMLElement("input")}}. C'est la valeur de l'attribut {{htmlattrxref("type","input")}} qui définit le type de bouton affiché :

- -

submit

- -
    <button type="submit">
-        Ceci est un <br><strong>bouton d'envoi</strong>
-    </button>
-
-    <input type="submit" value="Ceci est un bouton d'envoi">
- -

reset

- -
    <button type="reset">
-        Ceci est un <br><strong>bouton de réinitialisation</strong>
-    </button>
-
-    <input type="reset" value="Ceci est un bouton de réinitialisation">
- -

anonymous

- -
    <button type="button">
-        Ceci est un <br><strong>bouton lambda</strong>
-    </button>
-
-    <input type="button" value="Ceci est un bouton lambda">
- -

Les boutons se comportent de la même manière que vous utilisiez l'élément {{HTMLElement("button")}} ou l'élément {{HTMLElement("input")}}. Il existe toutefois quelques différences à noter :

- - - -

Screenshots of buttons on several platforms.

- -

Techniquement parlant, il n'y a pratiquement pas de différence entre un bouton défini avec l'élément {{HTMLElement("button")}} ou l'élément {{HTMLElement("input")}}. La seule différence à noter réside dans l'étiquette du bouton lui-même. Dans un élément {{HTMLElement("input")}}, l'étiquette ne peut être constituée que de données de type caractère, alors que dans un élément {{HTMLElement("button")}}, l'étiquette peut être mise sous HTML, de sorte qu'elle peut être mise en forme en conséquence.

- -

Widgets de formulaires avancés

- -

Ces widgets sont des contrôles permettant l'utilisateur de saisir des données plus complexes ou moins habituelles, comme des nombres exacts ou approchés, des dates et heures ainsi que des couleurs.

- -

Nombres

- -

On crée un widget pour nombres avec un élément {{HTMLElement("input")}} dont l'attribut {{htmlattrxref("type","input")}} a pour valeur number. Ce contrôle ressemble à un champ texte mais il n'accepte que des chiffres en virgule flottante, et propose habituellement des boutons pour augmenter ou réduire la valeur dans le widget.

- -

Il est aussi possible de :

- - - -

Exemple

- -
    <input type="number" name="age" id="age" min="1" max="10" step="2">
- -

Ceci créé un widget pour un nombre dont la valeur est comprise entre 1 et 10 et dont les boutons d'incrémentation/décrémentation modifient la valeur par pas de 2.

- -

Curseurs

- -

Le curseur est une autre manière de sélectionner un nombre. Comme, visuellement parlant, les curseurs sont moins précis qu'un champ textuel, ils sont utilisés pour retenir un nombre dont la précision de valeur n'est pas primordiale.

- -

Un curseur se crée avec l'élément {{HTMLElement("input")}} dont l'attribut {{htmlattrxref("type","input")}} a pour valeur range. Il est important de configurer convenablement le curseur. À cet effet, il est fortement recommandé de définir les attributs {{htmlattrxref("min","input")}}, {{htmlattrxref("max","input")}} et {{htmlattrxref("step","input")}}.

- -

Exemple

- -
    <input type="range" name="beans" id="beans" min="0" max="500" step="10">
-
- -

Cet exemple créé un curseur dont les valeurs varient entre 0 et 500, et dont les bouton d'incrément/décrément font varier la valeur de ±10.

- -

Un problème avec les curseurs est qu'il n'offrent aucun moyen visue de savoir quelle est leur valeur courante. Il est nécessaire d'ajouter cela vous‑même à l'aide de JavaScript, mais c'est assez facile. Dans cet exemple nous ajoutons un élément {{htmlelement("span")}} dans lequel nous écrivons la valeur courante du curseur et la mettons à jour quand elle est modifiée.

- -
<label for="beans">Combien de haricots pouvez‑vous manger ?</label>
-<input type="range" name="beans" id="beans" min="0" max="500" step="10">
-<span class="beancount"></span>
- -

et en  JavaScript :

- -
var beans = document.querySelector('#beans');
-var count = document.querySelector('.beancount');
-
-count.textContent = beans.value;
-
-beans.oninput = function() {
-  count.textContent = beans.value;
-}
- -

Ici nous stockons dans deux variables les références du curseur et celle de span, puis nous réglons immédiatement le textContent  de span à la valeur courante value de l'entrée. Enfin, nous avons mis en place un gestionnaire d'événements oninput de sorte que chaque fois que le curseur de plage est déplacé, le textContent de span est mis à jour avec la nouvelle valeur de l'entrée.

- -

L'attribut range pour input n'est pas pris en charge dans les versions d'Internet Explorer dont le numéro est inférieur à 10.

- -

Sélection de date et heure

- -

Recueillir des données de date et heure a traditionnellement toujours été un cauchemar pour les développeurs web. HTML5 ajoute des améliorations en ajoutant un contrôle qui permet de manipuler ce type de données.

- -

Un contrôle de sélection de date et heure se crée avec l'élément {{HTMLElement("input")}} et une valeur appropriée de l'attribut {{htmlattrxref("type","input")}} selon que vous voulez recueillir des dates, des heures ou les deux.

- -

datetime-local

- -

Cette valeur d'attribut créé un widget pour afficher et sélectionner une date et une heure quelque soit le fuseau horaire.

- -
<input type="datetime-local" name="datetime" id="datetime">
- -

month

- -

Cette valeur d'attribut créé un widget pour afficher et sélectionner un mois dans une année donnée.

- -
<input type="month" name="month" id="month">
- -

time

- -

Cette valeur d'attribut créé un widget pour afficher et sélectionner un horaire.

- -
<input type="time" name="time" id="time">
- -

week

- -

Cette valeur d'attribut crée un widget pour afficher et sélectionner une semaine et l'année correspondante.

- -
<input type="week" name="week" id="week">
- -

Tous les contrôles de sélection de date et heure peuvent être contraints à l'aide des attributs {{htmlattrxref("min","input")}} et {{htmlattrxref("max","input")}}.

- -
    <label for="maDate">Quand êtes vous disponible cet été ?</label>
-    <input type="date" min="2013-06-01" max="2013-08-31" id="maDate">
- -

Attention : Les widgets de date et heure sont encore peu pris en charge. Au moment de la rédaction de cet article, Chrome, Edge et Opera les prennent bien en charge, mais il n'y a pas de prise en charge dans Internet Explorer et Firefox et Safari n'ont qu'une prise en charge lacunaire de ces derniers.

- -

Sélecteur de couleur

- -

Les couleurs sont toujours compliquées à manier. Il existe plusieurs façons de les exprimer : valeurs RGB (décimale ou hexadécimale), valeurs HSL, mots-clés, etc. Les widgets de sélection de couleur permettent aux utilisateurs de sélectionner une couleur dans un contexte textuel et visuel.

- -

Un widget de sélection de couleur se crée avec un élément {{HTMLElement("input")}} dont l'attribut {{htmlattrxref("type","input")}} a pour valeur color.

- -
<input type="color" name="color" id="color">
- -

Attention : la prise en charge du widget color n'est pas très bonne actuellement. Il n'y a aucune prise en charge dans Internet Explorer, ni actuellement dans Safari. Les autres navigateurs majeurs le prennent en charge.

- -

Autres widgets

- -

Il existe d'autres types de widgets qui ne peuvent pas être classés facilement à cause de leur comportement très particulier, mais qui sont toujours très utiles.

- -
-

Note : Vous trouverez les exemples de cette section sur GitHub à l'adresse other-examples.html (à voir aussi directement).

-
- -

Sélection de fichier

- -

Les formulaires HTML permettent d'envoyer des fichiers à un serveur. Cette action spécifique est détaillée dans l'article  « Envoi et extraction des données de formulaire ». Le widget de sélection de fichier permet à l'utilisateur de choisir un ou plusieurs fichiers à envoyer.

- -

Pour créer un widget de sélection de fichier, vous devez utiliser un élément {{HTMLElement("input")}} dont l'attribut {{htmlattrxref("type","input")}} a pour valeur file. Les types de fichiers acceptés peuvent être contraints en utilisant l'attribut {{htmlattrxref("accept","input")}}. De plus, si vous souhaitez permettre à l'utilisateur de choisir plusieurs fichiers, vous pouvez le faire en ajoutant l'attribut {{htmlattrxref("multiple","input")}}.

- -

Exemple

- -

Dans cet exemple, le widget de sélection de fichiers permet de sélectionner des fichiers d'images. L'utilisateur peut sélectionner plusieurs fichiers.

- -
<input type="file" name="file" id="file" accept="image/*" multiple>
- -

Contenu caché

- -

Il est parfois pratique pour des raisons techniques d'avoir des morceaux d'informations qui soient envoyés au serveur sans être montrées à l'utilisateur. Pour ce faire, vous pouvez ajouter un élément invisible dans votre formulaire. Cela est possible en utilisant un élément {{HTMLElement("input")}} dont l'attribut {{htmlattrxref("type","input")}} a pour valeur hidden.

- -

Si vous créez un tel élément, il est obligatoire de définir ses attributs name et value :

- -
    <input type="hidden" id="timestamp" name="timestamp" value="1286705410">
- -

Image-bouton

- -

Le contrôle image-bouton est affiché comme un élément {{HTMLElement("img")}}, à la différence que lorsque l'utilisateur clique dessus, il se comporte comme un bouton d'envoi (voir ci-dessus).

- -

Une image-bouton se crée avec un élément {{HTMLElement("input")}} dont l'attribut {{htmlattrxref("type","input")}} a pour valeur image. Cet élément accepte exactement le même ensemble d'attributs que l'élément {{HTMLElement("img")}}, en plus de tous les attributs valides pour n'importe quel bouton de formulaire.

- -
    <input type="image" alt="Click me!" src="my-img.png" width="80" height="30" />
- -

Si l'image-bouton est utilisée pour envoyer un formulaire, ce widget n'envoie pas sa valeur mais les coordonnées X et Y du clic sur l'image (les coordonnées sont relatives à l'image, ce qui veut dire que le coin supérieur gauche représente les coordonnées 0, 0). Les coordonnées sont envoyées sous la forme de deux paires de clé/valeur :

- - - -

Lorsque vous cliquez sur l'image dans ce formulaire, vous êtes redirigés une URL du type suivant :

- -
    http://foo.com?pos.x=123&pos.y=456
- -

C'est une façon très commode de construire une « hot map » (cartographie des parties d'une page Internet le plus souvent balayées par le regard des lecteurs). La manière d'envoyer et d'extraire ces valeurs est détaillée dans l'article « Envoi des données de formulaire ».

- -

Compteurs et barres de progression

- -

Les compteurs et barres de progressions sont des représentations visuelles de valeurs numériques.

- -

Progress

- -

Une barre de progression représente une valeur qui évolue dans le temps jusqu'à une valeur maximale définie par l'attribut {{htmlattrxref("max","progress")}}. Une telle barre peut être créée grace à un élément {{ HTMLElement("progress")}}.

- -
    <progress max="100" value="75">75/100</progress>
- -

Cela sert à mettre en œuvre visuellement un rapport d'avancement, comme le pourcentage du nombre total de fichiers téléchargés ou le nombre de questions posées dans un questionnaire.

- -

Le contenu dans l'élément {{HTMLElement("progress")}} est un affichage informatif de repli pour les navigateurs ne prenant pas en charge cet élément ;  les technologies d'assistance vocalisent ce contenu.

- -

Meter

- -

Un étalon est une valeur fixe dans une plage délimitée par une valeur minimale {{htmlattrxref("min","meter")}} et une valeur maximale {{htmlattrxref("max","meter")}}. Cette valeur est affichée dans une barre, et pour savoir à quoi cette barre ressemble, nous comparons certaines valeurs :

- - - -

Tous les navigateurs compatibles avec l'élément {{HTMLElement("meter")}} utilisent ces valeurs pour modifier la couleur de la barre :

- - - -

Une telle barre se crée avec un élément {{HTMLElement("meter")}}. Cela permet d'implémenter toute sorte d'étalonnage, par exemple une barre montrant l'espace total utilisé sur un disque, qui devient rouge si le disque commence à être plein.

- -
<meter min="0" max="100" value="75" low="33" high="66" optimum="50">75</meter>
- -

Le contenu de l'élément {{HTMLElement("meter")}} est un affichage informatif de repli pour les navigateurs ne prenant pas en charge cet élément ; les technologies d'assistance vocalisent cet affichage.

- -

La prise en charge de progress et meter est vraiment bonne — il n'y a pas de prise en charge dans Internet Explorer, mais les autres navigateurs l'acceptent bien.

- -

Conclusion

- -

Comme nous venons de le voir, il y a pas mal d'éléments de formulaire différents disponibles  — il n'est pas nécessaire de mémoriser l'ensemble de ces détails dès maintenant, mais vous pourrez revenir à cet article tant que vous le voudrez pour revoir tel ou tel détail.

- -

Voir également

- -

Pour entrer plus en détails des différents widgets de formulaires, voici quelques ressources externes très utiles que vous pouvez visiter :

- - - -

{{PreviousMenuNext("Web/Guide/HTML/Formulaires/Comment_structurer_un_formulaire_HTML", "Web/Guide/HTML/Formulaires/Envoyer_et_extraire_les_données_des_formulaires", "Web/Guide/HTML/Formulaires")}}

- -

Dans ce module

- - diff --git a/files/fr/web/guide/html/formulaires/mon_premier_formulaire_html/exemple/index.html b/files/fr/web/guide/html/formulaires/mon_premier_formulaire_html/exemple/index.html deleted file mode 100644 index 3f25e6d644..0000000000 --- a/files/fr/web/guide/html/formulaires/mon_premier_formulaire_html/exemple/index.html +++ /dev/null @@ -1,104 +0,0 @@ ---- -title: Exemple -slug: Web/Guide/HTML/Formulaires/Mon_premier_formulaire_HTML/Exemple -translation_of: Learn/Forms/Your_first_form/Example ---- -

Ceci est l'exemple pour l'article Mon premier formulaire HTML.

- -

Un formulaire simple

- -

Contenu HTML

- -
<form action="http://www.cs.tut.fi/cgi-bin/run/~jkorpela/echo.cgi" method="post">
-  <div>
-    <label for="nom">Nom :</label>
-    <input type="text" id="nom" name="user_name">
-  </div>
-
-  <div>
-    <label for="courriel">Courriel :</label>
-    <input type="email" id="courriel" name="user_email">
-  </div>
-
-  <div>
-    <label for="message">Message :</label>
-    <textarea id="message" name="user_message"></textarea>
-  </div>
-
-  <div class="button">
-    <button type="submit">Envoyer le message</button>
-  </div>
-</form>
- -

Contenu CSS

- -
form {
-  /* Pour le centrer dans la page */
-  margin: 0 auto;
-  width: 400px;
-
-  /* Pour voir les limites du formulaire */
-  padding: 1em;
-  border: 1px solid #CCC;
-  border-radius: 1em;
-}
-
-div + div {
-  margin-top: 1em;
-}
-
-label {
-  /* Afin de s'assurer que toutes les étiquettes aient la même dimension et soient alignées correctement */
-  display: inline-block;
-  width: 90px;
-  text-align: right;
-}
-
-input, textarea {
-  /* Afin de s'assurer que tous les champs textuels utilisent la même police
-     Par défaut, textarea utilise une police à espacement constant */
-  font: 1em sans-serif;
-
-  /* Pour donner la même dimension à tous les champs textuels */
-  width: 300px;
-
-  -moz-box-sizing: border-box;
-       box-sizing: border-box;
-
-  /* Pour harmoniser l'apparence des bordures des champs textuels */
-  border: 1px solid #999;
-}
-
-input:focus, textarea:focus {
-  /* Afin de réhausser les éléments actifs */
-  border-color: #000;
-}
-
-textarea {
-  /* Pour aligner correctement les champs multilignes et leurs étiquettes */
-  vertical-align: top;
-
-  /* Pour donner assez d'espace pour entrer du texte */
-  height: 5em;
-
-  /* Pour permettre aux utilisateurs de redimensionner un champ textuel horizontalement
-     Cela ne marche pas avec tous les navigateurs  */
-  resize: vertical;
-}
-
-.button {
-  /* Pour positionner les boutons de la même manière que les champs textuels */
-  padding-left: 90px; /* même dimension que les étiquettes */
-}
-
-button {
-  /* Cette marge représente approximativement le même espace
-     que celui entre les étiquettes et les champs textuels */
-  margin-left: .5em;
-}
- -

Résultat

- -

{{ EmbedLiveSample('Un_formulaire_simple', '100%', '280') }}

- -

 

diff --git a/files/fr/web/guide/html/formulaires/mon_premier_formulaire_html/index.html b/files/fr/web/guide/html/formulaires/mon_premier_formulaire_html/index.html deleted file mode 100644 index 8f082f6d81..0000000000 --- a/files/fr/web/guide/html/formulaires/mon_premier_formulaire_html/index.html +++ /dev/null @@ -1,281 +0,0 @@ ---- -title: Mon premier formulaire HTML -slug: Web/Guide/HTML/Formulaires/Mon_premier_formulaire_HTML -tags: - - Apprentissage - - Codage - - Débutant - - Exemple - - Formulaires - - Guide - - HTML - - Web -translation_of: Learn/Forms/Your_first_form ---- -

{{LearnSidebar}}{{NextMenu("Web/Guide/HTML/Formulaires/Comment_structurer_un_formulaire_HTML", "Web/Guide/HTML/Formulaires")}}

- -

Le premier article de notre série vous offre une toute première expérience de création de formulaire en HTML, y compris sa conception, sa mise en œuvre en utilisant les bons éléments HTML, l'ajout de quelques très simples décorations avec les CSS et la façon dont les données sont envoyées à un serveur.

- - - - - - - - - - - - -
Prérequis :Notions concernant les ordinateurs et les connaissances de base du HTML.
Objectif :Comprendre ce que sont les formulaires HTML, à quoi ils servent, comment les concevoir et quels sont les éléments de base HTML nécessaires dans les cas simples.
- -

Un formulaire HTML, qu'est-ce ?

- -

Les formulaires HTML sont un des vecteurs principaux d'interaction entre un utilisateur et un site web ou une application. Ils permettent à l'utilisateur d'envoyer des données au site web. La plupart du temps, ces données sont envoyées à des serveurs web mais la page peut aussi les intercepter et les utiliser elle-même.

- -

Un formulaire HTML est composé d'un ou plusieurs widgets. Ceux-ci peuvent être des zones de texte (sur une seule ligne ou plusieurs lignes), des boîtes à sélection, des boutons, des cases à cocher ou des boutons radio. La plupart du temps, ces items sont associés à un libellé qui décrit leur rôle — des étiquettes correctement implémentées sont susceptibles d'informer clairement l'utilisateur normal ou mal‑voyant sur ce qu'il convient d'entrer dans le formulaire.

- -

La principale différence entre un formulaire HTML et un document HTML habituel réside dans le fait que, généralement, les données collectées par le formulaire sont envoyées vers un serveur web. Dans ce cas, vous avez besoin de mettre en place un serveur web pour récupérer ces données et les traiter. La mise en place d'un tel serveur ne fait pas partie des sujets abordés dans ce guide. Si vous souhaitez toutefois en savoir plus, voyez « Envoi des données de formulaire » plus loin dans ce module.

- -

Concevoir le formulaire

- -

Avant de passer au code, il est souhaitable de prendre un peu de recul et accorder quelques instants de réflexion à votre formulaire. Dessiner un rapide croquis vous permettra de définir les informations que vous souhaitez demander à l'utilisateur. Du point de vue de l'expérience utilisateur, il est important de garder à l'esprit que plus vous demandez d'informations, plus vous risquez que votre utilisateur s'en aille. Restez simple et ne perdez pas votre objectif de vue : ne demandez que ce dont vous avez absolument besoin. La conception de formulaires est une phase importante de la construction d'un site internet ou d'une application. L'approche de l'expérience utilisateur de ces formulaires ne fait pas partie des objectifs de ce guide, mais si vous souhaitez approfondir ce sujet, vous pouvez lire les articles suivants :

- - - -

Dans ce guide, nous allons concevoir un formulaire de contact simple. Posons les premières pierres.

- -

Le croquis du formulaire que l'on veut créer

- -

Notre formulaire contiendra trois champs de texte et un bouton. Nous demandons simplement à notre utilisateur son nom, son adresse électronique et le message qu'il souhaite envoyer. En appuyant sur le bouton, le message sera envoyé au serveur web.

- -

 Apprentissage actif : mise en œuvre de notre formulaire HTML

- -

Très bien, nous sommes maintenant prêts à passer au HTML et à coder notre formulaire. Pour construire notre formulaire, nous aurons besoin des éléments HTML suivants : {{HTMLElement("form")}}, {{HTMLElement("label")}}, {{HTMLElement("input")}}, {{HTMLElement("textarea")}} et {{HTMLElement("button")}}.

- -

Avant de poursuivre, faites une copie locale de notre simple modèle HTML — vous y incorporerez votre formulaire.

- -

L'élément {{HTMLElement("form")}}

- -

Tous les formulaires HTML débutent par un élément {{HTMLElement("form")}} comme celui-ci :

- -
<form action="/my-handling-form-page" method="post">
-
-</form>
- -

Cet élément définit un formulaire. C'est un élément conteneur au même titre que les éléments {{HTMLElement("div")}} ou {{HTMLElement("p")}}, mais il accepte aussi quelques attributs spécifiques afin de contrôler la manière dont il se comporte. Tous ses attributs sont optionnels mais définir au moins les attributs action et method est considéré comme de bonne pratique.

- - - -
-

Note : Si vous souhaitez en savoir plus sur le fonctionnement de ces attributs, cela est détaillé dans l'article « Envoi des données de formulaire ».

-
- -

Pour le moment, ajoutez l'élément {{htmlelement("form")}} ci dessus dans le corps de votre HTML.

- -

Les éléments {{HTMLElement("label")}}, {{HTMLElement("input")}} et {{HTMLElement("textarea")}}

- -

Notre formulaire de contact est très simple et ne contient que trois champs de texte, chacun ayant une étiquette. Le champ d'entrée pour le nom est un champ de texte sur une seule ligne, le champ pour l'adresse électronique est un champ de texte sur une ligne qui n'accepte que des adresses électroniques et enfin le champ pour le message est un champ de texte sur plusieurs lignes.

- -

En terme de code HTML, nous avons besoin de quelque chose qui ressemble à ceci pour mettre en œuvre nos widgets de formulaire.

- -
<form action="/ma-page-de-traitement" method="post">
-    <div>
-        <label for="name">Nom :</label>
-        <input type="text" id="name" name="user_name">
-    </div>
-    <div>
-        <label for="mail">e-mail :</label>
-        <input type="email" id="mail" name="user_mail">
-    </div>
-    <div>
-        <label for="msg">Message :</label>
-        <textarea id="msg" name="user_message"></textarea>
-    </div>
-</form>
- -

Les éléments {{HTMLElement("div")}} sont ici pour structurer notre code et rendre la mise en page plus facile (voir ci-dessous). Veuillez noter l'utilisation de l'attribut for sur tous les éléments {{HTMLElement("label")}}. C'est une manière formelle de lier un libellé à un élément du formulaire. Cet attribut fait référence à l'id de l'élément correspondant. Il y a plusieurs avantages à faire ainsi. Le plus évident de permettre à l'utilisateur de cliquer sur l'étiquette pour activer le bloc correspondant. Si vous souhaitez mieux comprendre les bénéfices de cet attribut, tout est détaillé dans cet article : Comment structurer un formulaire HTML.

- -

Concernant l'élément {{HTMLElement("input")}}, l'attribut le plus important est l'attribut type. Ce dernier est extrêmement important puisqu'il définit le comportement de l'élément {{HTMLElement("input")}}. Il peut radicalement changer le sens de l'élément, faites-y attention. Si vous voulez en savoir plus à ce propos, vous pouvez lire l'article au sujet des widgets natifs pour formulaire.

- - - -

Last but not least, remarquez la syntaxe de <input> vs <textarea></textarea>. C'est une des bizarreries du HTML. La balise <input> est un élément vide, ce qui signifie qu'il n'a pas besoin de balise fermante. Au contraire, {{HTMLElement("textarea")}} n'est pas un élément vide, il faut donc le fermer avec la balise fermante appropriée. Cela a un effet sur une caractéristique spécifique des formulaires HTML : la manière dont vous définissez la valeur par défaut. Pour définir une valeur par défaut d'un élément {{HTMLElement("input")}} vous devez utiliser l'attribut value de la manière suivante :

- -
<input type="text" value="par défaut cet élément sera renseigné avec ce texte">
- -

A contrario, si vous souhaitez définir la valeur par défaut d'un élément {{HTMLElement("textarea")}}, il suffit simplement de mettre la valeur par défaut entre les balises ouvrantes et fermantes de l'élément {{HTMLElement("textarea")}} de la manière suivante :

- -
<textarea>par défaut cet élément sera renseigné avec ce texte</textarea>
- -

L'élément {{HTMLElement("button")}}

- -

Notre formulaire est presque terminé. Il nous suffit seulement d'ajouter un bouton pour permettre à l'utilisateur de nous envoyer les données renseignées dans le formulaire. Ceci se fait simplement en ajoutant d'un élément {{HTMLElement("button")}} ; ajoutez‑le juste avant la balise fermante </form> :

- -
    <div class="button">
-        <button type="submit">Envoyer le message</button>
-    </div>
-
- -

Comme vous le voyez l'élément {{htmlelement("button")}} accepte aussi un attribut de type — il peut prendre une des trois valeurs : submit, reset ou button.

- - - -
-

Note : Vous pouvez aussi utiliser l'élément {{HTMLElement("input")}} avec le type approprié pour produire un bouton, par exemple <input type="submit">. Le principal avantage de {{HTMLElement("button")}} par rapport à l'élément {{HTMLElement("input")}} est que ce dernier ne permet d'utiliser que du texte comme étiquette tandis que l'élément {{HTMLElement("button")}} permet d'utiliser n'importe quel contenu HTML, autorisant ainsi des textes de bouton plus complexes et créatifs.

-
- -

Mise en page élémentaire du formulaire

- -

Nous avons désormais notre formulaire HTML, et si vous le regardez dans votre navigateur préféré, vous verrez qu'il est plutôt laid.

- -

- -
-

Note : Si vous pensez que vous n'avez pas écrit un code HTML correct, faites la comparaison avec celui de notre exemple terminé — voyez  first-form.html ( ou également directement).

-
- -

Les formulaires sont notoirement embêtants à présenter joliment. Apprendre la mise en page ou la décoration des formulaires sort du cadre de cet article, donc pour le moment nous allons simplement ajouter quelques indications au CSS pour lui donner un air convenable.

- -

Tout d'abord, ajoutons un élément {{htmlelement("style")}} à notre page, dans l'en‑tête HTML. Comme ceci :

- -
<style>
-
-</style>
- -

Entre les balises style, ajoutons le CSS suivant, juste comme indiqué :

- -
form {
-  /* Uniquement centrer le formulaire sur la page */
-  margin: 0 auto;
-  width: 400px;
-  /* Encadré pour voir les limites du formulaire */
-  padding: 1em;
-  border: 1px solid #CCC;
-  border-radius: 1em;
-}
-
-form div + div {
-  margin-top: 1em;
-}
-
-label {
-  /* Pour être sûrs que toutes les étiquettes ont même taille et sont correctement alignées */
-  display: inline-block;
-  width: 90px;
-  text-align: right;
-}
-
-input, textarea {
-  /* Pour s'assurer que tous les champs texte ont la même police.
-     Par défaut, les textarea ont une police monospace */
-  font: 1em sans-serif;
-
-  /* Pour que tous les champs texte aient la même dimension */
-  width: 300px;
-  box-sizing: border-box;
-
-  /* Pour harmoniser le look & feel des bordures des champs texte */
-  border: 1px solid #999;
-}
-
-input:focus, textarea:focus {
-  /* Pour souligner légèrement les éléments actifs */
-  border-color: #000;
-}
-
-textarea {
-  /* Pour aligner les champs texte multi‑ligne avec leur étiquette */
-  vertical-align: top;
-
-  /* Pour donner assez de place pour écrire du texte */
-  height: 5em;
-}
-
-.button {
-  /* Pour placer le bouton à la même position que les champs texte */
-  padding-left: 90px; /* même taille que les étiquettes */
-}
-
-button {
-  /* Cette marge supplémentaire représente grosso modo le même espace que celui
-     entre les étiquettes et les champs texte */
-  margin-left: .5em;
-}
- -

Désormais notre formulaire a une bien meilleure allure.

- -

- -
-

Note : Il est sur GitHub dans first-form-styled.html (à voir aussi directement).

-
- -

Envoyer les données au serveur Web

- -

Finalement, gérer les données du formulaire côté serveur web est peut être le plus compliqué. Comme dit auparavant, un formulaire HTML est une manière pratique de demander de l'information à un utilisateur et de les adresser à un serveur web.

- -

L'élément {{HTMLElement("form")}} définit où et comment les données sont envoyées, merci aux attributs action et method.

- -

Mais ce n'est pas tout. Nous avons aussi besoin de donner un nom à nos données. Ces noms sont importants pour deux raisons. Du côté du navigateur, cela sert à définir le nom de chaque élément de donnée. Du côté du serveur, chaque information doit avoir un nom pour être manipulée correctement.

- -

Pour nommer vos données vous devez utiliser l'attribut name pour identifier bien précisément l'élément d'information collecté par chacun des widgets. Regardons à nouveau le code de notre formulaire :

- -
form action="/my-handling-form-page" method="post">
-  <div>
-    <label for="name">Nom :</label>
-    <input type="text" id="name" name="user_name" />
-  <div>
-  <div>
-    <label for="mail">E-mail :</label>
-    <input type="email" id="mail" name="user_email" />
-  </div>
-  <div>
-    <label for="msg">Message:</label>
-    <textarea id="msg" name="user_message"></textarea>
-  </div>
-
-  ...
- -

Dans notre exemple, le formulaire enverra trois informations nommées respectivement « user_name », « user_email » et « user_message ». Ces informations seront envoyées à l'URL « /my-handling-form-page » avec la méthode HTTP POST.

- -

Du côté du serveur, le script à l'URL « /my-handling-form-page » recevra les données sous forme d'une liste de trois éléments clé/valeur intégrés à la requête HTTP. À vous de définir comment ce script va manipuler les données. Chacun des langages serveurs (PHP, Python, Ruby, Java, C#, etc.) a son propre mécanisme pour traiter ces données. Il n'appartient pas à ce guide d'approfondir ce sujet, mais si vous souhaitez en savoir plus, nous avons mis quelques exemples dans l'article Envoi des données de formulaire.

- -

Résumé

- -

Félicitations ! Vous avez construit votre premier formulaire HTML. Il ressemble à ceci :

- -

{{EmbedLiveSample("Un_formulaire_simple", "100%", "240", "", "Web/Guide/HTML/Formulaires/Mon_premier_formulaire_HTML/Exemple")}}

- -

Toutefois, ce n'est qu'un début — il est désormais temps de regarder plus en détail. Les formulaires HTML sont bien plus puissants que ce que vous avez pu voir ici et les autres articles de ce guide vous aiderons à maîtriser le reste.

- -

{{NextMenu("Web/Guide/HTML/Formulaires/Comment_structurer_un_formulaire_HTML", "Web/Guide/HTML/Formulaires")}}

- -

Dans ce module

- - diff --git a/files/fr/web/guide/html/formulaires/property_compatibility_table_for_form_widgets/index.html b/files/fr/web/guide/html/formulaires/property_compatibility_table_for_form_widgets/index.html deleted file mode 100644 index eacb5640ef..0000000000 --- a/files/fr/web/guide/html/formulaires/property_compatibility_table_for_form_widgets/index.html +++ /dev/null @@ -1,1991 +0,0 @@ ---- -title: Table de compatibilité des propriétés pour les widgets de formulaire -slug: Web/Guide/HTML/Formulaires/Property_compatibility_table_for_form_widgets -tags: - - Avancé - - CSS - - Formulaires - - Guide - - HTML - - Indésirables - - Mises à jour - - Web -translation_of: Learn/Forms/Property_compatibility_table_for_form_controls ---- -
{{learnsidebar}}{{PreviousMenu("Web/Guide/HTML/Formulaires/Advanced_styling_for_HTML_forms", "Web/Guide/HTML/Formulaires")}}
- -

Les tables de compatibilité suivantes tentent de résumer l'état de la prise en charge des CSS par les formulaires HTML. Eu égard à la complexité des CSS et des formulaires HTML, ces tables ne peuvent pas être considérées comme un élément de référence parfait. Toutefois, elles vous donneront un bon aperçu de ce qui peut et de ce qui ne peut pas être fait, ce qui vous aidera à apprendre comment faire les choses.

- -

Comment lire les tables

- -

Valeurs

- -

Pour chaque propriété, il y a quatre valeurs possibles :

- -
-
OUI
-
La prise en charge de la propriété est raisonnablement cohérente d'un navigateur à l'autre. Il se peut que vous soyez encore confronté à des effets collatéraux étranges dans certains cas limites.
-
PARTIEL
-
Bien que la propriété soit acceptée, vous pouvez fréquemment être confronté à des effets collatéraux bizarres ou à des incohérences. Vous devriez probablement éviter ces propriétés si vous n'avez pas d'abord maîtrisé ces effets secondaires.
-
NON
-
La propriété ne fonctionne tout simplement pas ou est si incohérente qu'elle n'est pas fiable.
-
N.A.
-
La propriété n'a aucune signification pour ce type de widget.
-
- -

Rendu

- -

Pour chaque propriété il y a deux rendus possibles :

- -
-
N (Normal)
-
Indique que la propriété est appliquée telle quelle.
-
A (Altéré)
-
Indique que la propriété est appliquée avec la règle supplémentaire ci-dessous :
-
- -
* {
-/* Ceci désactive l'aspect et le comportement natif des navigateurs basés sur WebKit. */
-  -webkit-appearance: none;
-
-/* Ceci désactive l'aspect et le comportement natif des navigateurs basés sur Gecko. */
-  -moz-appearance: none;
-
-/* Ceci désactive l'aspect et le comportement natif sur plusieurs divers navigateurs
-   y compris Opera, Internet Explorer et Firefox */
-  background: none;
-}
- -

Tables de compatibilité

- -

Comportements globaux

- -

Certains comportements sont communs à de nombreux navigateurs au niveau global :

- -
-
{{cssxref("border")}}, {{cssxref("background")}}, {{cssxref("border-radius")}}, {{cssxref("height")}}
-
L'utilisation de l'une de ces propriétés peut désactiver partiellement ou totalement l'aspect natif des widgets sur certains navigateurs. Prudence lorsque vous les utilisez.
-
{{cssxref("line-height")}}
-
Cette propriété est prise en charge de manière non cohérente d'un navigateur à l'autre et vous devriez l'éviter.
-
{{cssxref("text-decoration")}}
-
Cette propriété n'est pas prise en charge par Opera sur les widgets de formulaire.
-
{{cssxref("text-overflow")}}
-
Opera, Safari et IE9 ne prennent pas en charge cette propriété sur les widgets de formulaire.
-
{{cssxref("text-shadow")}}
-
Opera ne prend pas en charge {{cssxref("text-shadow")}} sur les widgets de formulaire et IE9 ne le prend pas du tout en charge.
-
- -

Champs texte

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropriétéNANote
Modèle de boîte CSS
{{cssxref("width")}}OuiOui 
{{cssxref("height")}}Partiel[1][2]Oui -
    -
  1. Les navigateurs WebKit (principalement sur Mac OSX et iOS) utilisent apparence et comportement natifs pour les champs de recherche. Par conséquent, il est nécessaire d'utiliser -webkit-appearance:none pour pouvoir appliquer cette propriété aux champs de recherche.
  2. -
  3. Sous Windows 7, Internet Explorer 9 n'applique pas la bordure à moins que background:none ne soit utilisé.
  4. -
-
{{cssxref("border")}}Partiel[1][2]Oui -
    -
  1. Les navigateurs WebKit (principalement sur Mac OSX et iOS) utilisent apparence et comportement natifs pour les champs de recherche. Par conséquent, il est nécessaire d'utiliser -webkit-appearance:none pour pouvoir appliquer cette propriété aux champs de recherche.
  2. -
  3. Sous Windows 7, Internet Explorer 9 n'applique pas la bordure à moins que background:none ne soit utilisé.
  4. -
-
{{cssxref("margin")}}OuiOui 
{{cssxref("padding")}}Partiel[1][2]Oui -
    -
  1. Les navigateurs WebKit (principalement sur Mac OSX et iOS) utilisent apparence et comportement natifs pour les champs de recherche. Par conséquent, il est nécessaire d'utiliser -webkit-appearance:none pour pouvoir appliquer cette propriété aux champs de recherche.
  2. -
  3. Sous Windows 7, Internet Explorer 9 n'applique pas la bordure à moins que background:none ne soit utilisé.
  4. -
-
Texte et polices
{{cssxref("color")}}[1]OuiOui -
    -
  1. Si la propriété {{cssxref("border-color")}} n'est pas mentionnée, certains navigateurs fondés sur WebKit appliqueront la propriété {{cssxref("color")}} aussi bien à la bordure qu'à la police avec l'élément {{HTMLElement("textarea")}}.
  2. -
-
{{cssxref("font")}}OuiOuiVoir la note à propos de {{cssxref("line-height")}}
{{cssxref("letter-spacing")}}OuiOui 
{{cssxref("text-align")}}OuiOui 
{{cssxref("text-decoration")}}PartielPartielVoir la note à propos de Opera
{{cssxref("text-indent")}}Partiel[1]Partiel[1] -
    -
  1. IE9 prend en charge cette propriété uniquement sur les éléments {{HTMLElement("textarea")}}, alors que Opera ne la prend en charge que sur les champs texte sur une ligne.
  2. -
-
{{cssxref("text-overflow")}}PartielPartiel 
{{cssxref("text-shadow")}}PartielPartiel 
{{cssxref("text-transform")}}OuiOui 
Bordure et arrière-plan
{{cssxref("background")}}Partiel[1]Oui -
    -
  1. Les navigateurs WebKit (principalement sur Mac OSX et iOS) utilisent apparence et comportement natifs pour les champs de recherche. Par conséquent, il est nécessaire d'utiliser -webkit-appearance:none pour pouvoir appliquer cette propriété aux champs de recherche. Sous Windows 7, Internet Explorer 9 n'applique pas la bordure à moins que background:none ne soit utilisé.
  2. -
-
{{cssxref("border-radius")}}Partiel[1][2]Oui -
    -
  1. Les navigateurs WebKit (principalement sur Mac OSX et iOS) utilisent apparence et comportement natifs pour les champs de recherche. Par conséquent, il est nécessaire d'utiliser -webkit-appearance:none pour pouvoir appliquer cette propriété aux champs de recherche. Sous Windows 7, Internet Explorer 9 n'applique pas la bordure à moins que background:none ne soit utilisé.
  2. -
  3. Sur Opera la propriété {{cssxref("border-radius")}} n'est appliquée que si une bordure est explicitement définie.
  4. -
-
{{cssxref("box-shadow")}}NonPartiel[1] -
    -
  1. IE9 ne prend pas en charge cette propriété.
  2. -
-
- -

Boutons

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropriétéNANote
Modèle de boîte CSS
{{cssxref("width")}}OuiOui 
{{cssxref("height")}}Partiel[1]Oui -
    -
  1. Cette propriété n'est pas appliquée sur les navigateurs fondés sur WebKit sur Mac OSX ou iOS.
  2. -
-
{{cssxref("border")}}PartielOui 
{{cssxref("margin")}}OuiOui 
{{cssxref("padding")}}Partiel[1]Oui -
    -
  1. Cette propriété n'est pas appliquée sur les navigateurs fondés sur WebKit sur Mac OSX ou iOS.
  2. -
-
Texte et polices
{{cssxref("color")}}OuiOui 
{{cssxref("font")}}OuiOuiVoir la note à propos de {{cssxref("line-height")}}.
{{cssxref("letter-spacing")}}OuiOui 
{{cssxref("text-align")}}NonNon 
{{cssxref("text-decoration")}}PartielOui 
{{cssxref("text-indent")}}OuiOui 
{{cssxref("text-overflow")}}NonNon 
{{cssxref("text-shadow")}}PartielPartiel 
{{cssxref("text-transform")}}OuiOui 
Bordure et arrière-plan
{{cssxref("background")}}OuiOui 
{{cssxref("border-radius")}}Yes[1]Yes[1] -
    -
  1. Sur Opera la propriété {{cssxref("border-radius")}} n'est appliquée que si une bordure est explicitement définie.
  2. -
-
{{cssxref("box-shadow")}}NonPartiel[1] -
    -
  1. IE9 ne prend pas en charge cette propriété.
  2. -
-
- -

Widget number

- -

Sur les navigateurs qui implémentent le widget number, il n'y a pas de méthode standard pour changer le style des roulettes utilisées pour changer la valeur du champ. Il est à noter que les roulettes de Safari sont en dehors du champ.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropriétéNANote
Modèle de boîte CSS
{{cssxref("width")}}OuiOui 
{{cssxref("height")}}Partiel[1]Partiel[1] -
    -
  1. Sur Opera, les roulettes sont zoomés, ce qui peut masquer le contenu du champ.
  2. -
-
{{cssxref("border")}}OuiOui 
{{cssxref("margin")}}OuiOui 
{{cssxref("padding")}}Partiel[1]Partiel[1] -
    -
  1. Sur Opera, les roulettes sont zoomés, ce qui peut masquer le contenu du champ.
  2. -
-
Texte et polices
{{cssxref("color")}}OuiOui 
{{cssxref("font")}}OuiOuiVoir la note à propos de {{cssxref("line-height")}}.
{{cssxref("letter-spacing")}}OuiOui 
{{cssxref("text-align")}}OuiOui 
{{cssxref("text-decoration")}}PartielPartiel 
{{cssxref("text-indent")}}OuiOui 
{{cssxref("text-overflow")}}NonNon 
{{cssxref("text-shadow")}}PartielPartiel 
{{cssxref("text-transform")}}N.A.N.A. 
Bordure et arrière‑plan
{{cssxref("background")}}NonNon -

Pris en charge mais il y a trop d'incohérence entre les navigateurs pour que ce soit fiable.

-
{{cssxref("border-radius")}}NonNon
{{cssxref("box-shadow")}}NonNon
- -

Cases à cocher et boutons radio

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropriétéNANote
Modèle de boîte CSS
{{cssxref("width")}}Non[1]Non[1] -
    -
  1. Certains navigateurs ajoutent des marges supplémentaires et d'autres étirent le widget.
  2. -
-
{{cssxref("height")}}Non[1]Non[1] -
    -
  1. Certains navigateurs ajoutent des marges supplémentaires et d'autres étirent le widget.
  2. -
-
{{cssxref("border")}}NonNon 
{{cssxref("margin")}}OuiOui 
{{cssxref("padding")}}NonNon 
Texte et polices
{{cssxref("color")}}N.A.N.A. 
{{cssxref("font")}}N.A.N.A. 
{{cssxref("letter-spacing")}}N.A.N.A. 
{{cssxref("text-align")}}N.A.N.A. 
{{cssxref("text-decoration")}}N.A.N.A. 
{{cssxref("text-indent")}}N.A.N.A. 
{{cssxref("text-overflow")}}N.A.N.A. 
{{cssxref("text-shadow")}}N.A.N.A. 
{{cssxref("text-transform")}}N.A.N.A. 
Bordure et arrière-plan
{{cssxref("background")}}NonNon 
{{cssxref("border-radius")}}NonNon 
{{cssxref("box-shadow")}}NonNon 
- -

Boîtes à sélection (ligne unique)

- -

Firefox ne fournit aucun moyen de changer la flèche vers le bas sur l'élément {{HTMLElement("select")}}.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropriétéNANote
Modèle de boîte CSS
{{cssxref("width")}}Partiel[1]Partiel[1] -
    -
  1. Cette propriété est correcte sur l'élément {{HTMLElement("select")}}, mais cela peut ne pas être le cas sur les éléments {{HTMLElement("option")}} ou {{HTMLElement("optgroup")}}.
  2. -
-
{{cssxref("height")}}NonOui 
{{cssxref("border")}}PartielOui 
{{cssxref("margin")}}OuiOui 
{{cssxref("padding")}}Non[1]Partiel[2] -
    -
  1. La propriété est appliquée, mais de manière incohérente entre navigateurs sous Mac OSX.
  2. -
  3. La propriété est bien appliquée sur l'élément {{HTMLElement("select")}}, mais est traitée de manière incohérente sur les éléments {{HTMLElement("option")}} et {{HTMLElement("optgroup")}}.
  4. -
-
Texte et polices
{{cssxref("color")}}Partiel[1]Partiel[1] -
    -
  1. Sur Mac OSX, les navigateurs fondés sur WebKit ne prennent pas en charge cette propriété sur les widgets natifs et, avec Opera, ils ne la prennent pas du tout en charge sur les éléments {{HTMLElement("option")}} et {{HTMLElement("optgroup")}}.
  2. -
-
{{cssxref("font")}}Partiel[1]Partiel[1] -
    -
  1. Sur Mac OSX, les navigateurs fondés sur WebKit ne prennent pas en charge cette propriété sur les widgets natifs et, avec Opera, ils ne la prennent pas du tout en charge sur les éléments {{HTMLElement("option")}} et {{HTMLElement("optgroup")}}.
  2. -
-
{{cssxref("letter-spacing")}}Partiel[1]Partiel[1] -
    -
  1. IE9 ne prend pas en charge cette propriété sur les éléments {{HTMLElement("select")}}, {{HTMLElement("option")}}, et {{HTMLElement("optgroup")}} ; les navigateurs fondés sur WebKit sur Mac OSX ne prennent pas en charge cette propriété sur les éléments {{HTMLElement("option")}} et {{HTMLElement("optgroup")}}.
  2. -
-
{{cssxref("text-align")}}No[1]No[1] -
    -
  1. IE9 sous Windows 7 et les navigateurs fondés sur WebKit sous Mac OSX ne prennent pas en charge cette propriété pour ce widget.
  2. -
-
{{cssxref("text-decoration")}}Partiel[1]Partiel[1] -
    -
  1. Seul Firefox fournit une prise en charge totale de cette propriété. Opera ne la prend pas du tout en charge et d'autres navigateur ne le font que pour l'élément  {{HTMLElement("select")}}.
  2. -
-
{{cssxref("text-indent")}}Partiel[1][2]Partiel[1][2] -
    -
  1. La plupart des navigateurs ne prennent en charge cette propriété que pour l'élément {{HTMLElement("select")}}.
  2. -
  3. IE9 ne prend pas en charge cette propriété.
  4. -
-
{{cssxref("text-overflow")}}NonNon 
{{cssxref("text-shadow")}}Partiel[1][2]Partiel[1][2] -
    -
  1. La plupart des navigateurs ne prennent en charge cette propriété que pour l'élément {{HTMLElement("select")}}.
  2. -
  3. IE9 ne prend pas en charge cette propriété.
  4. -
-
{{cssxref("text-transform")}}Partiel[1]Partiel[1] -
    -
  1. La plupart des navigateurs ne prennent en charge cette propriété que pour l'élément {{HTMLElement("select")}}.
  2. -
-
Bordure et arrière-plan
{{cssxref("background")}}Partiel[1]Partiel[1] -
    -
  1. La plupart des navigateurs ne prennent en charge cette propriété que pour l'élément {{HTMLElement("select")}}.
  2. -
-
{{cssxref("border-radius")}}Partiel[1]Partiel[1]
{{cssxref("box-shadow")}}NonPartiel[1]
- -

Boîtes à sélection (multilignes)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropriétéNANote
Modèle de boîte CSS
{{cssxref("width")}}OuiOui 
{{cssxref("height")}}OuiOui 
{{cssxref("border")}}OuiOui 
{{cssxref("margin")}}OuiOui 
{{cssxref("padding")}}Partiel[1]Partiel[1] -
    -
  1. Opera ne prend pas en charge {{cssxref("padding-top")}} et {{cssxref("padding-bottom")}} sur l'élément {{HTMLElement("select")}}.
  2. -
-
Texte et polices
{{cssxref("color")}}OuiOui 
{{cssxref("font")}}OuiOuiVoir la note à propos de {{cssxref("line-height")}}.
{{cssxref("letter-spacing")}}Partiel[1]Partiel[1] -
    -
  1. IE9 ne prend pas en charge cette propriété sur les éléments {{HTMLElement("select")}}, {{HTMLElement("option")}}, et {{HTMLElement("optgroup")}} ; les navigateurs fondés sur WebKit sur Mac OSX ne prennent pas en charge cette propriété sur les éléments {{HTMLElement("option")}} et {{HTMLElement("optgroup")}}.
  2. -
-
{{cssxref("text-align")}}No[1]No[1] -
    -
  1. IE9 sous Windows 7 et les navigateurs fondés sur WebKit sous Mac OSX ne prennent pas en charge cette propriété sur ce widget.
  2. -
-
{{cssxref("text-decoration")}}No[1]No[1] -
    -
  1. Uniquement pris en charge par Firefox et IE9+.
  2. -
-
{{cssxref("text-indent")}}NonNon 
{{cssxref("text-overflow")}}NonNon 
{{cssxref("text-shadow")}}NonNon 
{{cssxref("text-transform")}}Partiel[1]Partiel[1] -
    -
  1. La plupart des navigateurs ne prennent en charge cette propriété que pour l'élément {{HTMLElement("select")}}.
  2. -
-
Bordure et arrière-plan
{{cssxref("background")}}OuiOui 
{{cssxref("border-radius")}}Yes[1]Yes[1] -
    -
  1. Sur Opera la propriété {{cssxref("border-radius")}} n'est appliquée que si une bordure est explicitement définie.
  2. -
-
{{cssxref("box-shadow")}}NonPartiel[1] -
    -
  1. IE9 ne prend pas en charge cette propriété.
  2. -
-
- -

Datalist

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropriétéNANote
Modèle de boîte CSS
{{cssxref("width")}}NonNon 
{{cssxref("height")}}NonNon 
{{cssxref("border")}}NonNon 
{{cssxref("margin")}}NonNon 
{{cssxref("padding")}}NonNon 
Texte et polices
{{cssxref("color")}}NonNon 
{{cssxref("font")}}NonNon 
{{cssxref("letter-spacing")}}NonNon 
{{cssxref("text-align")}}NonNon 
{{cssxref("text-decoration")}}NonNon 
{{cssxref("text-indent")}}NonNon 
{{cssxref("text-overflow")}}NonNon 
{{cssxref("text-shadow")}}NonNon 
{{cssxref("text-transform")}}NonNon 
Bordure et arrière-plan
{{cssxref("background")}}NonNon 
{{cssxref("border-radius")}}NonNon 
{{cssxref("box-shadow")}}NonNon 
- -

Sélecteur de fichiers

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropriétéNANote
Modèle de boîte CSS
{{cssxref("width")}}NonNon 
{{cssxref("height")}}NonNon 
{{cssxref("border")}}NonNon 
{{cssxref("margin")}}OuiOui 
{{cssxref("padding")}}NonNon 
Texte et polices
{{cssxref("color")}}OuiOui 
{{cssxref("font")}}No[1]No[1] -
    -
  1. Pris en charge mais il y a trop d'incohérence entre les navigateurs pour que ce soit fiable.
  2. -
-
{{cssxref("letter-spacing")}}Partiel[1]Partiel[1] -
    -
  1. Beaucoup de navigateurs appliquent cette propriété sur le bouton de sélection.
  2. -
-
{{cssxref("text-align")}}NonNon 
{{cssxref("text-decoration")}}NonNon 
{{cssxref("text-indent")}}Partiel[1]Partiel[1] -
    -
  1. Agit plus ou moins comme une marge supplementaire en dehors du widget.
  2. -
-
{{cssxref("text-overflow")}}NonNon 
{{cssxref("text-shadow")}}NonNon 
{{cssxref("text-transform")}}NonNon 
Bordure et arrière-plan
{{cssxref("background")}}No[1]No[1] -
    -
  1. Pris en charge mais il y a trop d'incohérence entre les navigateurs pour que ce soit fiable.
  2. -
-
{{cssxref("border-radius")}}NonNon 
{{cssxref("box-shadow")}}NonPartiel[1] -
    -
  1. IE9 ne prend pas en charge cette propriété.
  2. -
-
- -

Sélecteurs de date

- -

Beaucoup de propriétés sont prises en charge mais il y a trop d'incohérence entre les navigateurs pour que ce soit fiable.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropriétéNANote
Modèle de boîte CSS
{{cssxref("width")}}NonNon 
{{cssxref("height")}}NonNon 
{{cssxref("border")}}NonNon 
{{cssxref("margin")}}OuiOui 
{{cssxref("padding")}}NonNon 
Texte et polices
{{cssxref("color")}}NonNon 
{{cssxref("font")}}NonNon 
{{cssxref("letter-spacing")}}NonNon 
{{cssxref("text-align")}}NonNon 
{{cssxref("text-decoration")}}NonNon 
{{cssxref("text-indent")}}NonNon 
{{cssxref("text-overflow")}}NonNon 
{{cssxref("text-shadow")}}NonNon 
{{cssxref("text-transform")}}NonNon 
Bordure et arrière-plan
{{cssxref("background")}}NonNon 
{{cssxref("border-radius")}}NonNon 
{{cssxref("box-shadow")}}NonNon 
- -

Sélecteurs de couleurs

- -

Il n'y a pas actuellement suffisamment d'implémentation pour obtenir des comportements fiables.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropriétéNANote
Modèle de boîte CSS
{{cssxref("width")}}OuiOui 
{{cssxref("height")}}No[1]Oui -
    -
  1. Opera gère cette propriété comme pour un widget select avec les mêmes restrictions.
  2. -
-
{{cssxref("border")}}OuiOui 
{{cssxref("margin")}}OuiOui 
{{cssxref("padding")}}No[1]Oui -
    -
  1. Opera gère cette propriété comme pour un widget select avec les mêmes restrictions.
  2. -
-
Texte et polices
{{cssxref("color")}}N.A.N.A. 
{{cssxref("font")}}N.A.N.A. 
{{cssxref("letter-spacing")}}N.A.N.A. 
{{cssxref("text-align")}}N.A.N.A. 
{{cssxref("text-decoration")}}N.A.N.A. 
{{cssxref("text-indent")}}N.A.N.A. 
{{cssxref("text-overflow")}}N.A.N.A. 
{{cssxref("text-shadow")}}N.A.N.A. 
{{cssxref("text-transform")}}N.A.N.A. 
Bordure et arrière-plan
{{cssxref("background")}}No[1]No[1] -
    -
  1. Pris en charge mais il y a trop d'incohérence entre les navigateurs pour que ce soit fiable.
  2. -
-
{{cssxref("border-radius")}}No[1]No[1]
{{cssxref("box-shadow")}}No[1]No[1]
- -

Widgets meter et progress

- -

Il n'y a pas actuellement suffisemment d'implémentation pour obtenir des comportements fiables.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropriétéNANote
Modèle de boîte CSS
{{cssxref("width")}}OuiOui 
{{cssxref("height")}}OuiOui 
{{cssxref("border")}}PartielOui 
{{cssxref("margin")}}OuiOui 
{{cssxref("padding")}}OuiPartiel[1] -
    -
  1. Chrome cache les éléments {{HTMLElement("progress")}} et {{HTMLElement("meter")}} quand la propriété {{cssxref("padding")}} est appliquée sur un élément altéré.
  2. -
-
Texte et polices
{{cssxref("color")}}N.A.N.A. 
{{cssxref("font")}}N.A.N.A. 
{{cssxref("letter-spacing")}}N.A.N.A. 
{{cssxref("text-align")}}N.A.N.A. 
{{cssxref("text-decoration")}}N.A.N.A. 
{{cssxref("text-indent")}}N.A.N.A. 
{{cssxref("text-overflow")}}N.A.N.A. 
{{cssxref("text-shadow")}}N.A.N.A. 
{{cssxref("text-transform")}}N.A.N.A. 
Bordure et arrière-plan
{{cssxref("background")}}No[1]No[1] -
    -
  1. Pris en charge mais il y a trop d'incohérence entre les navigateurs pour que ce soit fiable.
  2. -
-
{{cssxref("border-radius")}}No[1]No[1]
{{cssxref("box-shadow")}}No[1]No[1]
- -

Widget range

- -

Il n'y a pas de méthode standard pour changer le style de la poignée de range et Opera n'a aucun moyen de modifier le rendu par défaut du widget range.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropriétéNANote
Modèle de boîte CSS
{{cssxref("width")}}OuiOui 
{{cssxref("height")}}Partiel[1]Partiel[1] -
    -
  1. Chrome et Opera ajoutent quelque espace supplémentaire autour du widget, alors que Opera sous Windows 7 réduit la poignée de range.
  2. -
-
{{cssxref("border")}}NonOui 
{{cssxref("margin")}}OuiOui 
{{cssxref("padding")}}Partiel[1]Oui -
    -
  1. La propriété {{cssxref("padding")}} est appliquée, mais elle n'a aucun effet visible.
  2. -
-
Texte et polices
{{cssxref("color")}}N.A.N.A. 
{{cssxref("font")}}N.A.N.A. 
{{cssxref("letter-spacing")}}N.A.N.A. 
{{cssxref("text-align")}}N.A.N.A. 
{{cssxref("text-decoration")}}N.A.N.A. 
{{cssxref("text-indent")}}N.A.N.A. 
{{cssxref("text-overflow")}}N.A.N.A. 
{{cssxref("text-shadow")}}N.A.N.A. 
{{cssxref("text-transform")}}N.A.N.A. 
Bordure et arrière-plan
{{cssxref("background")}}No[1]No[1] -
    -
  1. Pris en charge mais il y a trop d'incohérence entre les navigateurs pour que ce soit fiable.
  2. -
-
{{cssxref("border-radius")}}No[1]No[1]
{{cssxref("box-shadow")}}No[1]No[1]
- -

Boutons image

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropriétéNANote
Modèle de boîte CSS
{{cssxref("width")}}OuiOui 
{{cssxref("height")}}OuiOui 
{{cssxref("border")}}OuiOui 
{{cssxref("margin")}}OuiOui 
{{cssxref("padding")}}OuiOui 
Texte et polices
{{cssxref("color")}}N.A.N.A. 
{{cssxref("font")}}N.A.N.A. 
{{cssxref("letter-spacing")}}N.A.N.A. 
{{cssxref("text-align")}}N.A.N.A. 
{{cssxref("text-decoration")}}N.A.N.A. 
{{cssxref("text-indent")}}N.A.N.A. 
{{cssxref("text-overflow")}}N.A.N.A. 
{{cssxref("text-shadow")}}N.A.N.A. 
{{cssxref("text-transform")}}N.A.N.A. 
Bordure et arrière-plan
{{cssxref("background")}}OuiOui 
{{cssxref("border-radius")}}Partiel[1]Partiel[1] -
    -
  1. IE9 ne prend pas en charge cette propriété.
  2. -
-
{{cssxref("box-shadow")}}Partiel[1]Partiel[1] -
    -
  1. IE9 ne prend pas en charge cette propriété.
  2. -
-
- -

{{PreviousMenu("Web/Guide/HTML/Formulaires/Advanced_styling_for_HTML_forms", "Web/Guide/HTML/Formulaires")}}

- -

Dans ce module

- - diff --git a/files/fr/web/guide/html/formulaires/sending_forms_through_javascript/index.html b/files/fr/web/guide/html/formulaires/sending_forms_through_javascript/index.html deleted file mode 100644 index 922bfb2aaf..0000000000 --- a/files/fr/web/guide/html/formulaires/sending_forms_through_javascript/index.html +++ /dev/null @@ -1,440 +0,0 @@ ---- -title: Envoi de formulaires avec JavaScript -slug: Web/Guide/HTML/Formulaires/Sending_forms_through_JavaScript -translation_of: Learn/Forms/Sending_forms_through_JavaScript ---- -
{{LearnSidebar}}{{PreviousMenuNext("Web/Guide/HTML/Formulaires/Comment_construire_des_widgets_de_formulaires_personnalisés", "Web/Guide/HTML/Formulaires/HTML_forms_in_legacy_browsers", "Web/Guide/HTML/Formulaires")}}
- -

Comme dans le précédent article, les formulaires HTML peuvent envoyer une requête HTTP par déclaration. Mais des formulaires peuvent aussi préparer une requête HTTP à adresser via JavaScript. Cet article explore comment faire cela.

- -

Un formulaire n'est pas toujours un <form>

- -

Avec les applications Web ouvertes, il est de plus en plus courant d'utiliser des formulaires HTML autres que des formulaires à remplir par des personnes — de plus en plus de développeurs prennent le contrôle sur la transmission des données.

- -

Obtenir le contrôle sur la totalité de l'interface

- -

La soumission d'un formulaire HTML standard charge l'URL où les données sont envoyées, car la fenêtre du navigateur manipule une pleine page. Éviter de charger une pleine page peut amener plus de fluidité en masquant des clignotements et des lenteurs de réseau.

- -

De nombreuses UI modernes n'utilisent les formulaires HTML que pour recueillir des données utilisateur. Lorsque l'utilisateur veut envoyer les données, l'application prend la main et transmet les données de manière asynchrone en arrière-plan, mettant à jour uniquement les parties de l'interface utilisateur nécessitant des modifications.

- -

L'envoi asynchrone de données arbitraires est connu sous le nom AJAX, qui signifie "Asynchronous JavaScript And XML" (XML et JavaScript asynchrones).

- -

Comment est-ce différent ?

- -

AJAX utilise l'objet DOM {{domxref("XMLHttpRequest")}} (XHR).Il peut construire des requêtes HTTP, les envoyer et retrouver leur résultats.

- -
-

Note : Les techniques AJAX anciennes ne se fondaient pas forcément sur {{domxref("XMLHttpRequest")}}. Par exemple, JSONP combiné à la fonction eval(). Cela fonctionne, mais n'est pas recommandé en raison de sérieux problèmes de sécurité. La seule raison d'en poursuivre l'utilisation est l'utilisation de navigateurs anciens qui ne prennent pas en charge {{domxref("XMLHttpRequest")}} ou JSON, mais ce sont vraiment des navigateurs anciens ! Évitez ces techniques.

-
- -

 

- -

Historiquement, {{domxref("XMLHttpRequest")}} a été conçu pour récupérer et envoyer du XML comme format d'échange. Cependant, JSON a remplacé XML et est de plus en plus courant aujourd'hui.

- -

Mais ni XML ni JSON ne s'adaptent à l'encodage des demandes de données de formulaire. Les données de formulaire (application/x-www-form-urlencoded) sont constituées de listes de paires clé/valeur codées par URL. Pour la transmission de données binaires, la requête HTTP est transformée en données multipart/form‑data.

- -

Si vous contrôlez le frontal (le code exécuté dans le navigateur) et l'arrière‑plan (le code exécuté sur le serveur), vous pouvez envoyer JSON/XML et les traiter comme vous le souhaitez.

- -

Mais si vous voulez utiliser un service tiers, ce n'est pas si facile. Certains services n'acceptent que les données de formulaire. Il y a aussi des cas où il est plus simple d'utiliser les données du formulaire. Si les données sont des paires clé/valeur ou des données binaires brutes, des outils d'arrière‑plan existants peuvent les traiter sans code supplémentaire.

- -

Comment envoyer de telles données ?

- -

Envoi des données de formulaire

- -

Il y a 3 façons d'envoyer des données de formulaire, allant des techniques existantes jusqu'à l'objet {{domxref("XMLHttpRequest/FormData", "FormData")}} plus récent. Examinons-les en détail.

- -

Construire manuellement un XMLHttpRequest

- -

{{domxref("XMLHttpRequest")}} est la manière la plus sûre et la plus fiable de faire des requêtes HTTP. Pour envoyer des données de formulaire avec {{domxref("XMLHttpRequest")}}, préparez les données par encodage URL et suivez les spécificités des requêtes de données de formulaire.

- -
-

Note : Pour en savoir plus sur XMLHttpRequest, ces articles pourraient vous intéresser : un article d'introduction à AJAX et un didacticiel plus fouillé à ce propos utilisant XMLHttpRequest.

-
- -

Reconstruisons l'exemple précédent :

- -
<button type="button" onclick="sendData({test:'ok'})">Cliquez ici !</button>
- -

Comme vous pouvez le voir, le HTML n'a pas réellement changé. Mais, le JavaScript est totalement différent :

- -
function sendData(data) {
-  var XHR = new XMLHttpRequest();
-  var urlEncodedData = "";
-  var urlEncodedDataPairs = [];
-  var name;
-
-  // Transformez l'objet data en un tableau de paires clé/valeur codées URL.
-  for(name in data) {
-    urlEncodedDataPairs.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));
-  }
-
-  // Combinez les paires en une seule chaîne de caractères et remplacez tous
-  // les espaces codés en % par le caractère'+' ; cela correspond au comportement
-  // des soumissions de formulaires de navigateur.
-  urlEncodedData = urlEncodedDataPairs.join('&').replace(/%20/g, '+');
-
-  // Définissez ce qui se passe en cas de succès de soumission de données
-  XHR.addEventListener('load', function(event) {
-    alert('Ouais ! Données envoyées et réponse chargée.');
-  });
-
-  // Définissez ce qui arrive en cas d'erreur
-  XHR.addEventListener('error', function(event) {
-    alert('Oups! Quelque chose s\'est mal passé.');
-  });
-
-  // Configurez la requête
-  XHR.open('POST', 'https://example.com/cors.php');
-
-  // Ajoutez l'en-tête HTTP requise pour requêtes POST de données de formulaire
-  XHR.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
-
-  // Finalement, envoyez les données.
-  XHR.send(urlEncodedData);
-}
- -

Voici le résultat en direct :

- -

{{EmbedLiveSample("Construire_manuellement_un_XMLHttpRequest", "100%", 50)}}

- -
-

Note : Cette utilisation de {{domxref("XMLHttpRequest")}} est assujettie à la politique « même origine » si vous voulez envoyer des données à un site web tiers. Pour les demandes d'origine croisée, vous aurez besoin d'un contrôle d'accès CORS et HTTP.

-
- -

Utilisation de XMLHttpRequest et de l'objet FormData

- -

Construire manuellement une requête HTTP peut devenir fastidieux. Heureusement, une spécification XMLHttpRequest récente fournit un moyen pratique et plus simple pour traiter les demandes de données de formulaire avec l'objet {{domxref("XMLHttpRequest/FormData", "FormData")}}.

- -

L'objet {{domxref("XMLHttpRequest/FormData", "FormData")}} peut s'utiliser pour construire des données de formulaire pour la transmission ou pour obtenir les données des élément de formulaire de façon à gérer leur mode d'envoi. Notez que les objets {{domxref("XMLHttpRequest/FormData", "FormData")}} sont en écriture seule (« write only »), ce qui signifie que vous pouvez les modifier, mais pas récupérer leur contenu.

- -

L'utilisation de cet objet est détaillée dans Utiliser les objets FormData, mais voici deux exemples :

- -

Utiliser un objet FormData autonome

- -
<button type="button" onclick="sendData({test:'ok'})">Cliquez ici !</button>
- -

Vous devriez être familier de cet exemple HTML.

- -
function sendData(data) {
-  var XHR = new XMLHttpRequest();
-  var FD  = new FormData();
-
-  // Mettez les données dans l'objet FormData
-  for(name in data) {
-    FD.append(name, data[name]);
-  }
-
-  // Définissez ce qui se passe si la soumission s'est opérée avec succès
-  XHR.addEventListener('load', function(event) {
-    alert('Ouais ! Données envoyées et réponse chargée.');
-  });
-
-  // Definissez ce qui se passe en cas d'erreur
-  XHR.addEventListener('error', function(event) {
-    alert('Oups! Quelque chose s\'est mal passé.');
-  });
-
-  // Configurez la requête
-  XHR.open('POST', 'https://example.com/cors.php');
-
-  // Expédiez l'objet FormData ; les en-têtes HTTP sont automatiquement définies
-  XHR.send(FD);
-}
- -

Voici le résultat directement :

- -

{{EmbedLiveSample("Utiliser_un_objet_FormData_autonome", "100%", 60)}}

- -

Utiliser un objet FormData lié à un élément form

- -

Vous pouvez également lier un objet FormData à un élément {{HTMLElement("form")}} et  créer ainsi un FormData représentant les données contenues dans le formulaire.

- -

Le HTML est classique :

- -
<form id="myForm">
-  <label for="myName">Dites-moi votre nom :</label>
-  <input id="myName" name="name" value="John">
-  <input type="submit" value="Envoyer !">
-</form>
- -

Mais JavaScript sera de la forme :

- -
window.addEventListener("load", function () {
-  function sendData() {
-    var XHR = new XMLHttpRequest();
-
-    // Liez l'objet FormData et l'élément form
-    var FD = new FormData(form);
-
-    // Définissez ce qui se passe si la soumission s'est opérée avec succès
-    XHR.addEventListener("load", function(event) {
-      alert(event.target.responseText);
-    });
-
-    // Definissez ce qui se passe en cas d'erreur
-    XHR.addEventListener("error", function(event) {
-      alert('Oups! Quelque chose s\'est mal passé.');
-    });
-
-    // Configurez la requête
-    XHR.open("POST", "https://example.com/cors.php");
-
-    // Les données envoyées sont ce que l'utilisateur a mis dans le formulaire
-    XHR.send(FD);
-  }
-
-  // Accédez à l'élément form …
-  var form = document.getElementById("myForm");
-
-  // … et prenez en charge l'événement submit.
-  form.addEventListener("submit", function (event) {
-    event.preventDefault();
-
-    sendData();
-  });
-});
- -

Voici le résultat en direct :

- -

{{EmbedLiveSample("Utiliser_un_objet_FormData_lié_à_un_élément_form", "100%", 70)}}

- -

Vous pouvez même intervenir davantage dans le processus en utilisant la propriété {{domxref("HTMLFormElement.elements", "elements")}} du formulaire pour obtenir une liste de tous les éléments de données du formulaire et les gérer chacun individuellement dans le programme. Pour en savoir plus, voir l'exemple dans la {{SectionOnPage("/en-US/docs/Web/API/HTMLFormElement.elements", "Accessing the element list's contents")}}.

- -

Construire un DOM dans un iframe caché

- -

La plus ancienne façon d'expédier des données de formulaire de manière asynchrone consiste à construire un formulaire avec l'API DOM, puis d'envoyer ses données dans un {{HTMLElement("iframe")}} caché. Pour accéder au résultat de votre envoi, il suffit de récupérer le contenu de l'élément {{HTMLElement("iframe")}}.

- -
-

Avertissement : Évitez d'employer cette technique. Il y a des risques concernant la sécurité avec des services tierce-partie car vous laissez ouverte la possibilité d'une attaque par injection de script. Si vous utilisez HTTPS, il reste possible de perturber la politique de la même origine, ce qui peut rendre le contenu de l'élément {{HTMLElement("iframe")}} inatteignable. Toutefois, cette méthode peut être votre seule possibilité si vous devez prendre en charge des navigateurs très anciens.

-
- -

Voici un exemple :

- -
<button onclick="sendData({test:'ok'})">Cliquez ici !</button>
- -
// Créer l'iFrame servant à envoyer les données
-var iframe = document.createElement("iframe");
-iframe.name = "myTarget";
-
-// Puis, attachez l'iFrame au document principal
-window.addEventListener("load", function () {
-  iframe.style.display = "none";
-  document.body.appendChild(iframe);
-});
-
-// Voici la fonction réellement utilisée pour expédier les données
-// Elle prend un paramètre, qui est un objet chargé des paires clé/valeurs.
-function sendData(data) {
-  var name,
-      form = document.createElement("form"),
-      node = document.createElement("input");
-
-  // Définir ce qui se passe quand la réponse est chargée
-  iframe.addEventListener("load", function () {
-    alert("Ouais ! Données envoyés.");
-  });
-
-  form.action = "http://www.cs.tut.fi/cgi-bin/run/~jkorpela/echo.cgi";
-  form.target = iframe.name;
-
-  for(name in data) {
-    node.name  = name;
-    node.value = data[name].toString();
-    form.appendChild(node.cloneNode());
-  }
-
-  // Pour être envoyé, le formulaire nécessite d'être attaché au document principal.
-  form.style.display = "none";
-  document.body.appendChild(form);
-
-  form.submit();
-
-  // Une fois le formulaire envoyé, le supprimer.
-  document.body.removeChild(form);
-}
- -

Voici le résultat en direct :

- -

{{EmbedLiveSample('Construire_un_DOM_dans_un_iframe_caché', "100%", 50)}}

- -

 

- -

Gestion des données binaires

- -

Si vous utilisez un objet {{domxref("XMLHttpRequest/FormData", "FormData")}} avec un formulaire qui inclut des widgets <input type="file">, les données seront traitées automatiquement. Mais pour envoyer des données binaires à la main, il y a un travail supplémentaire à faire.

- -

Il existe de nombreuses sources de données binaires sur le Web moderne : {{domxref("FileReader")}}, {{domxref("HTMLCanvasElement", "Canvas")}} et WebRTC, par exemple. Malheureusement, certains anciens navigateurs ne peuvent pas accéder aux données binaires ou nécessitent des solutions de contournement compliquées. Ces cas hérités sont hors du champ d'application de cet article. Si vous voulez en savoir plus sur l'API FileReader, lisez Utiliser les fichiers des applications Web.

- -

Envoyer des données binaires avec le support de {{domxref("XMLHttpRequest/FormData", "FormData")}} est direct. Utilisez la méthode append() et vous avez terminé. Si vous devez le faire à la main, c'est plus délicat.

- -

Dans l'exemple suivant, nous utilisons l'API {{domxref("FileReader")}} pour accéder aux données binaires et ensuite nous construisons à la main la demande de données du formulaire en plusieurs parties :

- -
<form id="myForm">
-  <p>
-    <label for="i1">Données textuelles :</label>
-    <input id="i1" name="myText" value="Quelques données textuelles">
-  </p>
-  <p>
-    <label for="i2">Fichier de données :</label>
-    <input id="i2" name="myFile" type="file">
-  </p>
-  <button>Envoyer !</button>
-</form>
- -

Comme vous pouvez le voir, le HTML est un <form>standard. Il n'y a rien de magique là‑dedans. La « magie » est dans le JavaScript :

- -
// Comme nous voulons avoir accès à un nœud DOM,
-// nous initialisons le script au chargement de la page.
-window.addEventListener('load', function () {
-
-  // Ces variables s'utilisent pour stocker les données du formulaire
-  var text = document.getElementById("i1");
-  var file = {
-        dom    : document.getElementById("i2"),
-        binary : null
-      };
-
-  // Nous utilisons l'API de FileReader pour accéder au contenu du fichier
-  var reader = new FileReader();
-
-  // Comme FileReader est asynchrone, stockons son résulata
-  // quand il a fini de lire le fichier
-  reader.addEventListener("load", function () {
-    file.binary = reader.result;
-  });
-
-  // Au chargement de la page, si un fichier est déjà choisi, lisons‑le
-  if(file.dom.files[0]) {
-    reader.readAsBinaryString(file.dom.files[0]);
-  }
-
-  // Sinon, lisons le fichier une fois que l'utilisateur l'a sélectionné
-  file.dom.addEventListener("change", function () {
-    if(reader.readyState === FileReader.LOADING) {
-      reader.abort();
-    }
-
-    reader.readAsBinaryString(file.dom.files[0]);
-  });
-
-  // sendData est notre fonction principale
-  function sendData() {
-    // S'il y a un fichier sélectionné, attendre sa lecture
-    // Sinon, retarder l'exécution de la fonction
-    if(!file.binary && file.dom.files.length > 0) {
-      setTimeout(sendData, 10);
-      return;
-    }
-
-    // Pour construire notre requête de données de formulaire en plusieurs parties
-    // nous avons besoin d'une instance de XMLHttpRequest
-    var XHR = new XMLHttpRequest();
-
-    // Nous avons besoin d'un séparateur pour définir chaque partie de la requête
-    var boundary = "blob";
-
-    // Stockons le corps de la requête dans une chaîne littérale
-    var data = "";
-
-    // Ainsi, si l'utilisateur a sélectionné un fichier
-    if (file.dom.files[0]) {
-      // Lancer une nouvelle partie de la requête du corps
-      data += "--" + boundary + "\r\n";
-
-      // Décrivons là comme étant des données du formulaire
-      data += 'content-disposition: form-data; '
-      // Définissons le nom des données du formulaire
-            + 'name="'         + file.dom.name          + '"; '
-      // Fournissons le vrai nom du fichier
-            + 'filename="'     + file.dom.files[0].name + '"\r\n';
-      // et le type MIME du fichier
-      data += 'Content-Type: ' + file.dom.files[0].type + '\r\n';
-
-      // Il y a une ligne vide entre les métadonnées et les données
-      data += '\r\n';
-
-      // Ajoutons les données binaires à la requête du corps
-      data += file.binary + '\r\n';
-    }
-
-    // C'est plus simple pour les données textuelles
-    // Démarrons une nouvelle partie dans notre requête du corps
-    data += "--" + boundary + "\r\n";
-
-    // Disons que ce sont des données de formulaire et nommons les
-    data += 'content-disposition: form-data; name="' + text.name + '"\r\n';
-    // Il y a une ligne vide entre les métadonnées et les données
-    data += '\r\n';
-
-    // Ajoutons les données textuelles à la requête du corps
-    data += text.value + "\r\n";
-
-    // Ceci fait, "fermons" la requête du corps
-    data += "--" + boundary + "--";
-
-    // Définissons ce qui arrive en cas de succès pour la soumission des données
-    XHR.addEventListener('load', function(event) {
-      alert('Ouais ! Données expédiées et réponse chargée.');
-    });
-
-    // Définissons ce qui se passe en cas d'eerreur
-    XHR.addEventListener('error', function(event) {
-      alert('Oups! Quelque chose s\'est mal passé.');
-    });
-
-    // Configurons la requête
-    XHR.open('POST', 'https://example.com/cors.php');
-
-    // Ajoutons l'en-tête requise pour gèrer la requête POST des données
-    // de formulaire en plusieurs parties
-    XHR.setRequestHeader('Content-Type','multipart/form-data; boundary=' + boundary);
-
-    // et finalement, expédions les données.
-    XHR.send(data);
-  }
-
-  // Accéder au formulaire …
-  var form = document.getElementById("myForm");
-
-  // … pour prendre en charge l'événement soumission
-  form.addEventListener('submit', function (event) {
-    event.preventDefault();
-    sendData();
-  });
-});
- -

Voici le résultat en direct :

- -

{{EmbedLiveSample('Gestion_des_données_binaires', "100%", 150)}}

- -

Conclusion

- -

Selon le navigateur, l'envoi de données de formulaire par JavaScript peut être facile ou difficile. L'objet {{domxref("XMLHttpRequest/FormData", "FormData")}} en est généralement la cause et n'hésitez pas à utiliser un « polyfill » (prothèse d'émulation) pour cela sur les navigateurs anciens :

- - - -

 

- -
{{PreviousMenuNext("Web/Guide/HTML/Formulaires/Comment_construire_des_widgets_de_formulaires_personnalisés", "Web/Guide/HTML/Formulaires/HTML_forms_in_legacy_browsers", "Web/Guide/HTML/Formulaires")}}
- -

 

- -

Dans ce module

- - diff --git a/files/fr/web/guide/html/formulaires/validation_donnees_formulaire/index.html b/files/fr/web/guide/html/formulaires/validation_donnees_formulaire/index.html deleted file mode 100644 index ccbac0ef15..0000000000 --- a/files/fr/web/guide/html/formulaires/validation_donnees_formulaire/index.html +++ /dev/null @@ -1,874 +0,0 @@ ---- -title: Validation des données de formulaires -slug: Web/Guide/HTML/Formulaires/Validation_donnees_formulaire -tags: - - Exemple - - Formulaires - - Guide - - HTML - - Intermédiaire - - JavaScript - - Web -translation_of: Learn/Forms/Form_validation ---- -
{{LearnSidebar}}{{PreviousMenuNext("Web/Guide/HTML/Formulaires/Envoyer_et_extraire_les_données_des_formulaires", "Web/Guide/HTML/Formulaires/Comment_construire_des_widgets_de_formulaires_personnalisés", "Web/Guide/HTML/Formulaires")}}
- -

Ce n'est pas tout d'envoyer des données — il faut aussi s'assurer que les données mises dans un formulaire par un utilisateur sont dans un format correct pour pouvoir être traitées correctement et qu'elles ne vont pas casser nos applications. Nous voulons également aider les utilisateurs à compléter les formulaires correctement et à ne pas ressentir de frustration en essayant d'utiliser les applications. La validation des données de formulaire vous aide à remplir ces objectifs — cet article indique ce qu'il est nécessaire de savoir.

- - - - - - - - - - - - -
Prérequis :Notions concernant les ordinateurs, une bonne compréhension du HTML, des CSS et de JavaScript.
Objectif :Comprendre ce qu'est la validation d'un formulaire, pourquoi c'est important et comment la mettre en œuvre.
- -

Qu'est‑ce qu'une validation de formulaire?

- -

Allez sur n'importe quel site à la mode avec un formulaire d'inscription et vous remarquerez des retours si vous n'entrez pas les données dans le format attendu. Vous aurez des messages comme :

- - - -

C'est ce qu'on appelle la validation de formulaire —  lorsque vous saisissez des données, l'application Web vérifie si elles sont correctes. Si elles sont correctes, l'application permet que les données soient soumises au serveur et (généralement) sauvegardées dans une base de données ; si ce n'est pas le cas, elle émet des messages d'erreur pour expliquer ce que vous avez fait de mal (pour autant que vous l'ayez fait). La validation des formulaires peut être mise en œuvre de différentes manières.

- -

La vérité est qu'aucun d'entre nous n'aime remplir des formulaires — les formulaires ennuient les utilisateurs, tout le prouve : cela les incite à partir et à aller voir ailleurs s'ils sont mal faits. Bref, les formulaires, c'est nullissime.

- -

Remplir des formulaires web doit être aussi facile que possible. Alors pourquoi être tatillons et bloquer les utilisateurs à chaque fois ? Il y a trois raisons principales :

- - - -

Les divers types de validation de formulaire

- -

Vous rencontrerez différents types de validation de formulaires sur le Web :

- - - -
-
- - - -

Dans le monde réel, les développeurs ont tendance à utiliser une combinaison de validations côté client et côté serveur, pour être du côté sûr.

- -

Utiliser la validation intégrée au formulaire

- -

Une des caractéristiques de HTML5 est la possibilité de valider la plupart des données utilisateur sans avoir recours à des scripts. Ceci se fait en utilisant des attributs de validation sur les éléments de formulaire ; ils vous permettent de spécifier des règles pour une entrée de formulaire comme : une valeur doit‑elle être remplie ? y a-t-il une longueur minimale et/ou maximale des données ? doit‑elle être un nombre, une adresse e-mail ou autre chose ? doit‑elle correspondre à un modèle ? Si les données saisies suivent toutes ces règles, elles sont considérées comme valides ; si ce n'est pas le cas, elles sont considérées comme non valides.
- Quand un élément est valide :

- - - -

Quand un élément est invalide :

- - - -

Contraintes de validation sur les éléments d'entrée — simple début

- - - -

Dans cette section, nous examinerons quelques unes des diverses fonctionnalités HTML5 peuvant être utilisées pour valider des éléments d'{{HTMLElement("input")}}.

- -

Commençons par un exemple simple — une entrée ouvrant un choix, selon votre préférence, entre banane ou cerise. Il faut un texte {{HTMLElement("input")}} simple avec une étiquette correspondante et un {{htmlelement("button")}} de soumission. Le code source est sur GitHub à l'adresse fruit-start.html et un exemple « live » ci-dessous :

- - - -

{{EmbedLiveSample("Hidden_code", "100%", 55)}}

- -

Pour commencer, faites une copie de fruit-start.html dans un nouveau répertoire sur votre disque dur.

- -

L'attribut required

- -

La fonctionnalité de validation HTML5 la plus simple à utiliser est l'attribut {{htmlattrxref("required", "input")}}} — si vous voulez rendre une entrée obligatoire, vous pouvez marquer l'élément en utilisant cet attribut. Lorsque cet attribut est mis, le formulaire ne sera pas soumis (et affichera un message d'erreur) si l'entrée est vide (l'entrée sera également considérée comme invalide).

- -

Ajoutez un attribut required à votre saisie, comme montré ci‑dessous :

- -
<form>
-  <label for="choose">Préférez-vous la banane ou la cerise ?</label>
-  <input id="choose" name="i_like" required>
-  <button>Soumettre</button>
-</form>
- -

Notez aussi le CSS incorporé dans le fichier exemple :

- -
input:invalid {
-  border: 2px dashed red;
-}
-
-input:valid {
-  border: 1px solid black;
-}
- -

L'entrée a une bordure en pointillés rouge vif lorsqu'elle n'est pas valide, et une bordure noire plus subtile lorsqu'elle est valide. Essayez le nouveau comportement dans l'exemple ci-dessous :

- -

{{EmbedLiveSample("L'attribut_required", "100%", 55)}}

- -

Validation selon une expression régulière

- -

Une autre fonctionnalité de validation très courante est l'attribut {{htmlattrxref("pattern", "input")}}, qui attend une expression régulière comme valeur. Une expression régulière (regex) est un modèle qui peut être utilisé pour faire correspondre des combinaisons de caractères dans des chaînes de texte, de sorte qu'elles sont idéales pour la validation de formulaires (ainsi que diverses autres utilisations en JavaScript). Les Regex sont assez complexes et nous n'avons pas l'intention de vous les enseigner de manière exhaustive dans cet article.

- -

Vous trouverez ci-dessous quelques exemples pour vous donner une idée de base de leur fonctionnement :

- - - -

Vous pouvez utiliser des nombres ou d'autres caractères dans ces expressions, comme :

- - - -

Vous pouvez combiner cela pratiquement comme vous l'entendez en précisant les différentes parties les unes après les autres :

- - - -

Voyons un exemple — mettons à jour notre HTML en y ajoutant un attribut pattern, ainsi :

- -
<form>
-  <label for="choose">Préférez‑vous la banane ou la cerise ?</label>
-  <input id="choose" name="i_like" required pattern="banane|cerise">
-  <button>Soumettre</button>
-</form>
- - - -

{{EmbedLiveSample("Validation_selon_une_expression_régulière", "100%", 55)}}

- -

Dans cet exemple, l'élément {{HTMLElement("input")}}} accepte l'une des deux valeurs possibles : la chaîne « banane » ou la chaîne « cerise ».

- -

Maintenant, essayez de changer la valeur à l'intérieur de l'attribut pattern suivant certains exemples vus plus haut et regardez comment les valeurs entrées en sont affectées pour rester valides. Écrivez vos propres textes et voyez comment vous vous en sortez ! Restez dans le domaine des fruits dans la mesure du possible, afin que vos exemples aient du sens !

- -
-

Note : Certains types d'éléments {{HTMLElement("input")}} n'ont pas besoin d'un attribut {{htmlattrxref("pattern", "input")}} pour être validés. Spécifier le type email, par exemple, valide la valeur saisie par rapport à une expression régulière correspondant à une adresse e‑mail bien formée (ou une liste d'adresses e‑mail séparées par des virgules si elle possède l'attribut {{htmlattrxref("multiple", "input")}}. Comme autre exemple, les champs de type url vont automatiquement nécessiter une URL correctement formée.

-
- -
-

Note : L'élément {{HTMLElement("textarea")}} ne prend pas en charge l'attribut {{htmlattrxref("pattern", "input")}}.

-
- -

Limitation de la taille des entrées

- -

Tous les champs de texte créés avec ({{HTMLElement("input")}} ou {{HTMLElement("textarea")}}) peuvent être limités en taille avec les attributs {{htmlattrxref("minlength", "input")}} et {{htmlattrxref("maxlength", "input")}}. Le champ sera invalide si sa taille est inférieure à la valeur {{htmlattrxref("minlength", "input")}} ou supérieure la valeur {{htmlattrxref("maxlength", "input")}}. Souvent, les navigateurs ne permettent pas aux utilisateurs de saisir des textes de grande longueur dans les champs texte, mais il peut être utile de disposer d'un contrôle plus fin.

- -

Pour les champs numériques (c'est à dire, <type d'entrée="nombre">), les attributs {{htmlattrxref("min", "input")}} et {{htmlattrxref("max", "input")}} permettent également des contraintes de validité. Si la valeur du champ est inférieure à l'attribut {{htmlattrxref("min", "input")}} ou supérieure à l'attribut {{htmlattrxref("max", "input")}}, le champ ne sera pas valide.

- -

Prenons un autre exemple. Créez une nouvelle copie du fichier fruit-start.html.

- -

Supprimez maintenant le contenu de l'élément <body> et remplacez-le par le suivant :

- -
<form>
-  <div>
-    <label for="choose">Préférez‑vous la banane ou la cerise ?</label>
-    <input id="choose" name="i_like" required minlength="6" maxlength="6">
-  </div>
-  <div>
-    <label for="number">Combien en voulez‑vous ?</label>
-    <input type="number" id="number" name="amount" value="1" min="1" max="10">
-  </div>
-  <div>
-    <button>Soumettre</button>
-  </div>
-</form>
- - - - - -

Voici cet exemple s'exécutant en « live » :

- -

{{EmbedLiveSample('Limitation_de_la_taille_des_entrées', "100%", 100)}}

- -
-

Note: <input type="number"> (et d'autres types, comme range) acceptent aussi un attribut {{htmlattrxref("step", "input")}} qui spécifie l'incrément en plus ou en moins de la valeur quand les contrôles d'entrée sont utilisés (comme les boutons ^ et v).

-
- -

Exemple complet

- -

Voici un exemple complet montrant l'utilisation des fonctionnalités HTML intégrées pour la validation :

- -
<form>
-  <p>
-    <fieldset>
-      <legend>Qualité<abbr title="Ce champ est obligatoire">*</abbr></legend>
-      <input type="radio" required name="title" id="r1" value="Mr"><label for="r1">M.</label>
-      <input type="radio" required name="title" id="r2" value="Ms"><label for="r2">Mme.</label>
-    </fieldset>
-  </p>
-  <p>
-    <label for="n1">Quel est votre âge ?</label>
-    <!-- L'attribut pattern peut servir de recours pour les navigateurs dont le type number n'est
-         pas implémenté pour input mais qui prennent en charge l'attribut pattern. Veuillez noter
-         que les navigateurs prenant en charge l'attribut pattern ne signalent pas d'erreur quand
-         il est utilisé avec un champ number. Seule son utilisation ici agit en tant que recours. -->
-    <input type="number" min="12" max="120" step="1" id="n1" name="age"
-           pattern="\d+">
-  </p>
-  <p>
-    <label for="t1">Quel est votre fruit favori ?<abbr title="Ce champ est obligatoire">*</abbr></label>
-    <input type="text" id="t1" name="fruit" list="l1" required
-           pattern="[Bb]anane|[Cc]erise|[Cc]itron|[Ff]raise|[Oo]range|[Pp]omme">
-    <datalist id="l1">
-      <option>Banane</option>
-      <option>Cerise</option>
-      <option>Citron</option>
-      <option>Fraise</option>
-      <option>Orange</option>
-      <option>Pomme</option>
-    </datalist>
-  </p>
-  <p>
-    <label for="t2">Quelle est votre adresse électronique ?</label>
-    <input type="email" id="t2" name="email">
-  </p>
-  <p>
-    <label for="t3">Laissez un court message</label>
-    <textarea id="t3" name="msg" maxlength="140" rows="5"></textarea>
-  </p>
-  <p>
-    <button>Soumettre</button>
-  </p>
-</form>
- -
body {
-  font: 1em sans-serif;
-  padding: 0;
-  margin : 0;
-}
-
-form {
-  max-width: 300px;
-  margin: 0;
-  padding: 0 5px;
-}
-
-p > label {
-  display: block;
-}
-
-input[type=text],
-input[type=email],
-input[type=number],
-textarea,
-fieldset {
-/* requis pour composer de manière appropriée les éléments
-   de formulaire sur les navigateurs fondés sur WebKit */
-  -webkit-appearance: none;
-
-  width : 100%;
-  border: 1px solid #333;
-  margin: 0;
-
-  font-family: inherit;
-  font-size: 90%;
-
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
-}
-
-input:invalid {
-  box-shadow: 0 0 5px 1px red;
-}
-
-input:focus:invalid {
-  outline: none;
-}
- -

{{EmbedLiveSample("Exemple_complet", "100%", 450)}}

- - - -

Messages d'erreur personnalisés

- -

Comme nous avons vu dans les exemples précédents, à chaque fois qu'un utilisateur tente d'envoyer un formulaire invalide, le navigateur affiche un message d'erreur. La manière dont le message est affiché dépend du navigateur.

- -

Ces messages automatiques présentent deux inconvénients:

- - - - - - - - - - - - - - - - - - - - - - - - - -
Versions françaises des navigateurs sur une page en anglais
NavigateurAffichage
Firefox 17 (Windows 7)Example of an error message with Firefox in French on an English page
Chrome 22 (Windows 7)Example of an error message with Chrome in French on an English page
Opera 12.10 (Mac OSX)Example of an error message with Opera in French on an English page
- -

Pour personnaliser l'apparence et le texte de ces messages, vous devez utiliser JavaScript ; il n'est pas possible de l'implémenter en utilisant uniquement HTML et CSS.

- -

HMTL5 fournit une API de contraintes de validation pour vérifier et personnaliser l'état des élément d'un formulaire. Il est possible, entre autres, de changer le texte des messages d'erreur. Voici un court exemple :

- -
<form>
-  <label for="mail">Pourriez-vous nous fournir une adresse mail ?</label>
-  <input type="email" id="mail" name="mail">
-  <button>Envoyer</button>
-</form>
- -

En JavaScript, il faut appeler la méthode setCustomValidity():

- -
var email = document.getElementById("mail");
-
-email.addEventListener("keyup", function (event) {
-  if(email.validity.typeMismatch) {
-    email.setCustomValidity("J'attend un e-mail, mon cher !");
-  } else {
-    email.setCustomValidity("");
-  }
-});
- -

{{EmbedLiveSample("Messages_d'erreur_personnalisés", "100%", 50)}}

- -

Validation de formulaires avec JavaScript

- -

Si vous souhaitez avoir le contrôle de l'apparence des messages d'erreur, ou si vous voulez gérer le comportement des navigateurs n'ayant pas implémenté la validation de formulaire HTML5, vous n'avez pas d'autre choix que d'utiliser JavaScript.

- -

API de contraintes de validation HTML5

- -

De plus en plus de navigateurs prennent maintenant en charge l'API de validation des contraintes, et elle devient fiable. Cette API se compose d'un ensemble de méthodes et de propriétés disponibles sur chaque élément de formulaire.

- -

Propriétés de l'API de validation des contraintes

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropriétésDescription
validationMessageUn message (dans la langue locale) décrivant les contraintes de validation que le contrôle ne satisfait pas (si c'est le cas), ou une chaîne vide si le contrôle n'est pas soumis à validation (willValidate est alors false), ou bien la valeur de l'élément satisfait ses contraintes.
validityUn objet {{domxref("ValidityState")}} qui décrit l'état de validité de l'élément.
validity.customErrorRenvoie true si l'élément à une erreur personnalisée, false a contrario.
validity.patternMismatchRenvoie true si la valeur de l'élément ne correspond pas au motif fourni, false dans le cas contraire. Si la méthode renvoie true, l'élément fera partie de la pseudo-classe CSS {{cssxref(":invalid")}}.
validity.rangeOverflowRenvoie true si la valeur de l'élément est supérieure au maximum défini, false dans le cas contraire. Si le retour est true, l'élément fera partie des  pseudo-classes CSS {{cssxref(":invalid")}} et {{cssxref(":out-of-range")}}.
validity.rangeUnderflowRenvoie true si la valeur de l'élément est plus petite que le minimum défini, false dans le cas contraire. Si le retour est true, l'élément fera partie des pseudo-classes CSS {{cssxref(":invalid")}} et {{cssxref(":out-of-range")}}.
validity.stepMismatchRenvoie true si la valeur de l'élément ne correspond pas aux règles définies par l'attribut step,false a contrario. Si le retour est true, l'élément fera partie des pseudo-classes CSS {{cssxref(":invalid")}} et {{cssxref(":out-of-range")}}.
validity.tooLongRenvoie true si la taille de l'élément est supérieure à la longueur maximum définie, false dans le cas contraire. Si le retour est true, l'élément fera partie des pseudo-classes CSS {{cssxref(":invalid")}} et {{cssxref(":out-of-range")}}.
validity.typeMismatchRenvoie true si la syntaxe de la valeur de l'élément n'est pas correcte ; false dans le cas contraire. Si le retour est true, l'élément sera de la pseudo-classe CSS {{cssxref(":invalid")}}.
validity.validRenvoie true si la valeur de l'élément n'a pas de problème de validité, sinon false. L'élément sera de la pseudo-classe CSS {{cssxref(":valid")}} si le retour est true ; de la pseudo-classe CSS {{cssxref(":invalid")}} si le retour est false.
validity.valueMissingRenvoie true si l'élément n'a pas de valeur alors que le champ est requis, sinonfalse. L'élément sera de la pseudo-classe CSS {{cssxref(":invalid")}} si le retour est true.
willValidateRetourne true si l'élément est validé lorsque le formulaire est soumis, false dans le cas contraire.
- -

Méthodes de l'API de validation des contraintes

- - - - - - - - - - - - - - - - - - -
MéthodesDescription
checkValidity()Renvoie true si la valeur de l'élément n'a pas de problème de validation, false autrement. Si l'élément est invalide, cette méthode déclenche aussi un événement {{event("invalid")}} sur cet élément.
setCustomValidity(message)Ajoute un message d'erreur personnalisé à l'élément ; si vous définissez un message d'erreur personnalisé, l'élément est considéré comme invalide, et le message spécifié est affiché. Cela vous permet d'utiliser du code JavaScript pour établir une erreur de validation autre que celles offertes par l'API standard des contraintes de validation. Le message est affiché à l'utilisateur lorsque le problème est rapporté. Si l'argument est une chaîne de caractères vide, l'erreur personnalisée est considérée comme effacée.
- -

Pour les anciens navigateurs, il existe une prothèse d'émulation (polyfill) comme Hyperform, pour compenser le défaut de prise en charge de cette API. Comme vous utilisez déjà JavaScript, l'utilisation d'une prethèse d'émulation n'est pas un souci supplémentaire pour la conception ou l'implémentation de votre site ou application Web.

- -

Exemple d'utilisation de l'API de validation des contraintes

- -

Voyons comment utiliser l'API pour créer des messages d'erreur personnalisés. Tout d'abord, le HTML :

- -
<form novalidate>
-  <p>
-    <label for="mail">
-      <span>Veuillez saisir une adresse e-mail :</span>
-      <input type="email" id="mail" name="mail">
-      <span class="error" aria-live="polite"></span>
-    </label>
-  <p>
-  <button>Envoyer</button>
-</form>
- -

Ce formulaire simple utilise l'attribut {{htmlattrxref("novalidate","form")}} pour désactiver la validation automatique par le navigateur ; cela permet donc à notre script d'avoir le contrôle sur la validation. Toutefois, cela ne désactive la prise en charge par l'API de validation des contraintes, ni l'application des pseudo-classes CSS  {{cssxref(":valid")}}, {{cssxref(":invalid")}}, {{cssxref(":in-range")}} et {{cssxref(":out-of-range")}}. Cela signifie que, même si le navigateur ne vérifie pas automatiquement la validité du formulaire avant l'envoi des données, vous pouvez toujours effectuer cette validation et définir l'apparence du formulaire par vous-même.

- -

L'attribut aria-live garantit que nos messages d'erreur personnalisés seront affichés à tout le monde, y compris les personnes utilisant des techniques d'assistance comme des lecteurs d'écran.

- -
CSS
- -

Ce CSS compose le formulaire et les messages d'erreur pour les rendre plus attrayants.

- -
/* Juste pour que notre exemple soit plus joli */
-body {
-  font: 1em sans-serif;
-  padding: 0;
-  margin : 0;
-}
-
-form {
-  max-width: 200px;
-}
-
-p * {
-  display: block;
-}
-
-input[type=email]{
-  -webkit-appearance: none;
-
-  width: 100%;
-  border: 1px solid #333;
-  margin: 0;
-
-  font-family: inherit;
-  font-size: 90%;
-
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
-}
-
-/* Voici notre composition pour les champs invalides */
-input:invalid{
-  border-color: #900;
-  background-color: #FDD;
-}
-
-input:focus:invalid {
-  outline: none;
-}
-
-/* Voici la mise en forme pour les erreurs */
-.error {
-  width  : 100%;
-  padding: 0;
-
-  font-size: 80%;
-  color: white;
-  background-color: #900;
-  border-radius: 0 0 5px 5px;
-
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
-}
-
-.error.active {
-  padding: 0.3em;
-}
- -
JavaScript
- -

Le code JavaScript suivant gère la validation personnalisée des erreurs.

- -
// Il y a plusieurs façon de sélectionner un nœud DOM ; ici on récupère
-// le formulaire et le champ d'e-mail ainsi que l'élément span
-// dans lequel on placera le message d'erreur
-
-var form  = document.getElementsByTagName('form')[0];
-var email = document.getElementById('mail');
-var error = document.querySelector('.error');
-
-email.addEventListener("input", function (event) {
-  // Chaque fois que l'utilisateur saisit quelque chose
-  // on vérifie la validité du champ e-mail.
-  if (email.validity.valid) {
-    // S'il y a un message d'erreur affiché et que le champ
-    // est valide, on retire l'erreur
-    error.innerHTML = ""; // On réinitialise le contenu
-    error.className = "error"; // On réinitialise l'état visuel du message
-  }
-}, false);
-form.addEventListener("submit", function (event) {
-  // Chaque fois que l'utilisateur tente d'envoyer les données
-  // on vérifie que le champ email est valide.
-  if (!email.validity.valid) {
-
-    // S'il est invalide, on affiche un message d'erreur personnalisé
-    error.innerHTML = "J'attends une adresse e-mail correcte, mon cher !";
-    error.className = "error active";
-    // Et on empêche l'envoi des données du formulaire
-    event.preventDefault();
-  }
-}, false);
- -

Voici le résultat:

- -

{{EmbedLiveSample("Exemple_d'utilisation_de_l'API_de_validation_des_contraintes", "100%", 130)}}

- -

L'API de validation des contraintes fournit un outil puissant pour gérer la validation des formulaires, en vous laissant un contrôle sur l'interface utilisateur bien supérieur à ce que vous auriez pu avoir avec uniquement HTML et CSS. 

- -

Valider des formulaires sans API intégrée

- -

Il arrive parfois, comme c'est le cas avec des navigateurs anciens ou de widgets personnalisés, de ne pas pouvoir (ou vouloir) utiliser l'API de validation des contraintes. Dans ce cas, vous pourrez toujours utiliser JavaScript pour valider votre formulaire. Valider un formulaire est plus une question d'interface utilisateur que de réelle validation des données.

- -

Pour valider un formulaire, vous devez vous poser un certain nombre de questions:

- -
-
Quel type de validation dois-je réaliser ?
-
Vous devez déterminer comment valider vos données : opération sur des chaînes de caractères, conversion de type, expressions rationnelles, etc. C'est comme vous voulez. Mais retenez simplement que les données de formulaire sont toujours du texte et sont toujours fournies à vos scripts sous forme de chaînes de caractères.
-
Que dois-je faire si le formulaire n'est pas valide ?
-
C'est clairement une affaire d'interface utilisateur. Vous devez décider comment le formulaire doit se comporter : enverra-t-il quand même les données ? Devriez-vous mettre en évidence les champs qui sont en erreur ? Devriez-vous afficher des messages d'erreur ?
-
Comment puis-je aider l'utilisateur à corriger ses données invalides?
-
Pour limiter la frustration de l'utilisateur, il est très important de fournir autant d'information d'aide que nécessaire pour le guider dans la correction de sa saisie. Vous devriez afficher des suggestions en amont pour que l'utilisateur sache ce qui est attendu, ainsi que des messages d'erreur clairs. Si vous souhaitez vous plonger dans les exigences d'interface utilsateur pour la validation de formulaires, voici quelques articles (en anglais) utiles que vous devriez lire :
-
- -
-
- -

Exemple qui n'utilise pas l'API de validation des contraintes

- -

Afin d'illustrer le propos, réécrivons le précédent exemple afin qu'il fonctionne avec d'anciens navigateurs:

- -
<form>
-  <p>
-    <label for="mail">
-        <span>Veuillez saisir une adresse e-mail :</span>
-        <input type="text" class="mail" id="mail" name="mail">
-        <span class="error" aria-live="polite"></span>
-    </label>
-  <p>
-  <!-- Certains navigateurs historiques ont besoin de l'attribut
-       `type` avec la valeur `submit` sur l'élément `button` -->
-  <button type="submit">Envoyer</button>
-</form>
- -

Comme vous pouvez voir, le HTML est quasiment identique; nous avons juste enlevé les fonctionnalités de validation HTML. Notez que ARIA est une spécification indépendante qui n'est pas spécifiquement liée à HTML5.

- -
CSS
- -

De même, nous n'avons pas eu à changer radicalement les CSS ; nous avons simplement transformé la pseudo-classe {{cssxref(":invalid")}} en une vraie classe et évité d'utiliser le sélecteur d'attribut, qui ne fonctionne pas avec Internet Explorer 6.

- -
/* On améliore l'aspect de l'exemple avec ces quelques règles */
-body {
-  font: 1em sans-serif;
-  padding: 0;
-  margin : 0;
-}
-
-form {
-  max-width: 200px;
-}
-
-p * {
-  display: block;
-}
-
-input.mail {
-  -webkit-appearance: none;
-
-  width: 100%;
-  border: 1px solid #333;
-  margin: 0;
-
-  font-family: inherit;
-  font-size: 90%;
-
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
-}
-
-/* Voici les règles de mise en forme pour les champs invalides */
-input.invalid{
-  border-color: #900;
-  background-color: #FDD;
-}
-
-input:focus.invalid {
-  outline: none;
-}
-
-/* Voici les règles utilisées pour les messages d'erreur */
-.error {
-  width  : 100%;
-  padding: 0;
-
-  font-size: 80%;
-  color: white;
-  background-color: #900;
-  border-radius: 0 0 5px 5px;
-
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
-}
-
-.error.active {
-  padding: 0.3em;
-}
- -
JavaScript
- -

Les changements les plus importants sont dans le code JavaScript, qui nécessite bien plus que de simples retouches.

- -
// Il existe moins de méthode pour sélectionner un nœud DOM
-// avec les navigateurs historiques
-var form  = document.getElementsByTagName('form')[0];
-var email = document.getElementById('mail');
-
-// Ce qui suit est une bidouille pour atteindre le prochain nœud Element dans le DOM
-// Attention à cette méthode, elle peut permettre de construire une boucle
-// infinie. Pour les navigateurs plus récents, on utilisera element.nextElementSibling
-var error = email;
-while ((error = error.nextSibling).nodeType != 1);
-
-// Pour respecter la spécification HTML5
-var emailRegExp = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
-
-// De nombreux navigateurs historiques ne supportent pas la méthode
-// addEventListener. Voici une méthode simple (il en existe d'autres)
-function addEvent(element, event, callback) {
-  var previousEventCallBack = element["on"+event];
-  element["on"+event] = function (e) {
-    var output = callback(e);
-
-    // Une fonction de rappel (callback) qui renvoie `false`
-    // pour arrêter la chaîne des callback
-    // et interrompre l'exécution du callback d'événement.
-    if (output === false) return false;
-
-    if (typeof previousEventCallBack === 'function') {
-      output = previousEventCallBack(e);
-      if(output === false) return false;
-    }
-  }
-};
-
-// On peut désormais reconstruire notre validation de contrainte
-// Étant donné qu'on n'utilise pas la pseudo-classe CSS, il faut
-// explicitement gérer la classe valid/invalid du champ e-mail
-addEvent(window, "load", function () {
-  // Ici, on teste si le champ est vide (rappel : le champ n'est pas obligatoire)
-  // S'il ne l'est pas, on vérifie que son contenu est une adresse e-mail valide.
-  var test = email.value.length === 0 || emailRegExp.test(email.value);
-
-  email.className = test ? "valid" : "invalid";
-});
-
-// Ici, on définit ce qui se passe lorsque l'utilisateur
-// saisit quelque chose dans le champ
-addEvent(email, "keyup", function () {
-  var test = email.value.length === 0 || emailRegExp.test(email.value);
-  if (test) {
-    email.className = "valid";
-    error.innerHTML = "";
-    error.className = "error";
-  } else {
-    email.className = "invalid";
-  }
-});
-
-// Ici, on définit ce qui se passe lorsque l'utilisateur
-// tente d'envoyer les données du formulaire
-addEvent(form, "submit", function () {
-  var test = email.value.length === 0 || emailRegExp.test(email.value);
-
-  if (!test) {
-    email.className = "invalid";
-    error.innerHTML = "Merci d'écrire une adresse e-mail valide.";
-    error.className = "error active";
-
-    // Certains navigateurs historiques ne supportent pas
-    // la méthode event.reventDefault()
-    return false;
-  } else {
-    email.className = "valid";
-    error.innerHTML = "";
-    error.className = "error";
-  }
-});
- -

Voici le résultat:

- -

{{EmbedLiveSample("Exemple_qui_n'utilise_pas_l'API_de_validation_des_contraintes", "100%", 130)}}

- -

Comme vous avez pu le voir, il n'est pas si difficile de créer par soi-même un système de validation. La difficulté consiste à rendre le tout assez générique pour l'utiliser à la fois sur toutes les plateformes et pour chaque formulaire que vous pourriez créer. Il existe de nombreuses bibliothèques permettant ce genre de validation de formulaire ; n'hésitez pas à les utiliser. En voici quelques exemples :

- - - -

Validation à distance

- -

Il peut être utile, dans certains cas, d'effectuer une validation à distance. Ce genre de validation est nécessaire lorsque les données saisies par l'utilisateur sont liées à des données supplémentaires stockées sur le serveur hébergeant votre application. Prenons par exemple les formulaires d'inscription, pour lesquels on vous demande un nom d'utilisateur. Pour éviter toute duplication d'un nom d'utilisateur, il est plus judicieux d'effectuer une requête AJAX pour vérifier la disponibilté du nom d'utilisateur que de demander à envoyer les données saisies et de renvoyer le formulaire avec une erreur.

- -

Pour réaliser une telle validation, plusieurs précautions doivent être prises :

- - - -

Conclusion

- -

La validation d'un formulaire ne requiert pas de code JavaScript complexe, mais il est nécessaire de penser tout particulièrement à l'utilisateur. Rappelez-vous de toujours aider l'utilisateur à corriger les données qu'il saisit. Pour ce faire, assurez-vous de toujours :

- - - -

{{PreviousMenuNext("Web/Guide/HTML/Formulaires/Envoyer_et_extraire_les_données_des_formulaires", "Web/Guide/HTML/Formulaires/Comment_construire_des_widgets_de_formulaires_personnalisés", "Web/Guide/HTML/Formulaires")}}

- -

Dans ce module

- - diff --git a/files/fr/web/guide/html/html5/introduction_to_html5/index.html b/files/fr/web/guide/html/html5/introduction_to_html5/index.html new file mode 100644 index 0000000000..51eaf4850e --- /dev/null +++ b/files/fr/web/guide/html/html5/introduction_to_html5/index.html @@ -0,0 +1,40 @@ +--- +title: Introduction à HTML5 +slug: Web/HTML/Introduction_to_HTML5 +tags: + - HTML + - HTML5 +translation_of: Web/Guide/HTML/HTML5/Introduction_to_HTML5 +--- +

HTML5 est la nouvelle version du standard HTML. Il apporte non seulement l'utilisation de média riches (vidéo, audio, SVG, etc.) mais aussi des fonctionnalités permettant le développement d'applications web bien plus attractives et interactives.

+ +

Étant donné que HTML5 est encore en cours d'évolution, certains navigateurs ne supportent pas encore toutes les fonctionnalités offertes par ce nouveau standard. Ceci dit Gecko (et donc Firefox) supporte déjà dans sa version 1.8.1 une majorité des possibilités de HTML5. Vous trouverez ce que Gecko supporte déjà en visitant cette page : HTML5. Pour obtenir davantage d'informations sur le support de HTML5 par de multiples navigateurs, jetez un coup d'œil sur le site CanIUse .

+ +

Indiquer que le document contient du HTML5 grâce au doctype HTML5

+ +

La doctype HTML5 est très simple, il s'agit simplement de ceci :

+ +
<!DOCTYPE html>
+
+ +

Cela permet au navigateur ne supportant pas encore le HTML5 de passer en mode standard et ainsi d'ignorer les balises inconnues.

+ +

Il est beaucoup plus simple que les précédents doctypes, et plus court. Il est ainsi plus facile à retenir et réduit le nombre d'octets devant être téléchargés.

+ +

Déclarer l'encodage de caractères avec <meta charset>

+ +

La première chose que l'on fait d'habitude sur une page web c'est déclarer l'encodage de caractère utilisé. Dans les versions précédentes de HTML, ceci était fait en utilisant le très complexe élément {{HTMLElement("meta")}}. Avec HTML5, c'est beaucoup plus simple :

+ +
<meta charset="UTF-8">
+ +

Placez ceci au tout début de votre élément {{HTMLElement("head") }}, car certains navigateurs recommencent leur interprétation des documents HTML, si l'encodage de caractère déclaré est différent de ce qu'ils avaient anticipé. De plus, il est recommandé d'utiliser UTF-8, car il simplifie la gestion des caractères dans les documents utilisant plusieurs graphies.

+ +

Notez que HTML5 limite les encodages autorisés à ceux qui sont compatibles avec ASCII et utilisant au moins 8 bits. Ceci pour améliorer la sécurité et éviter certains types d'attaques.

+ +

Utiliser le nouveau parser HTML5

+ +

Les nouvelles règles d'analyse du HTML5, celles qui s'occupent de la sémantique du code, ont été renforcées. Jusqu'à l'arrivée du HTML5, seules les règles pour un code valide avaient été définies. À la moindre erreur dans le code (la plupart des sites Web en comportent au moins une), le comportement à adopter était laissé à la libre interprétation des navigateurs, qui ne choisissaient pas toujours le même. Maintenant, lorsque des erreurs sont rencontrées dans le code, tous les navigateurs implémentant HTML5 doivent se comporter de la même façon.

+ +

Cette obligation aide les développeurs Web. Bien que tous les nouveaux navigateurs utilisent maintenant les règles d'analyse d'HTML5, des navigateurs ne respectant pas HTML5 sont encore utilisés. Il est toujours fortement recommandé d'écrire un code valide, car il est plus facile à lire et à maintenir, et diminue les risques d'incompatibilité avec les vieux navigateurs.

+ +

Ne vous inquiétez pas, vous n'avez rien à changer sur votre site Web, les développeurs des navigateurs ont déjà fait le nécessaire !

diff --git "a/files/fr/web/guide/html/html5/liste_des_\303\251l\303\251ments_html5/index.html" "b/files/fr/web/guide/html/html5/liste_des_\303\251l\303\251ments_html5/index.html" deleted file mode 100644 index 42f2df0c51..0000000000 --- "a/files/fr/web/guide/html/html5/liste_des_\303\251l\303\251ments_html5/index.html" +++ /dev/null @@ -1,580 +0,0 @@ ---- -title: Liste des éléments HTML5 -slug: Web/Guide/HTML/HTML5/Liste_des_éléments_HTML5 -tags: - - Débutant - - Guide - - HTML - - HTML5 - - Web -translation_of: Web/HTML/Element -translation_of_original: Web/Guide/HTML/HTML5/HTML5_element_list ---- -

Cette Page n'est pas encore complète.

- -

Travail progressif basé sur document de travail en court à http://www.whatwg.org/specs/web-apps/current-work/multipage/.

- -

Élément racine

- -

Les éléments racines définissent la structure d'un document HTML. Ils sont présents dans chacune des pages web et se situent à la suite de la déclaration doctype à la première ligne du document HTML. Les éléments de page sont placés à l'intérieur des balises ouvrante <html> et fermante </html>.

- - - - - - - - - - - - - - -
BaliseDescription
{{ HTMLElement("html") }}L'élément HTML racine (<html>) représente la racine du document HTML. Tout autre élément est un descendant de cet élément racine.
- -

Métadonnées du document

- -

Les méta-données contiennent les informations liées à la page telles que les styles de présentation et les scripts. Les méta-données de style et de scripts peuvent être définies au sein de la page web ou via un lien pointant vers un fichier.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BaliseDescription
{{ HTMLElement("head") }} 
{{ HTMLElement("title") }} 
{{ HTMLElement("base") }} 
{{ HTMLElement("link") }} 
{{ HTMLElement("meta") }} 
{{ HTMLElement("style") }} 
- -

Gestion des scripts

- - - - - - - - - - - - - - - - - - -
BaliseDescription
{{ HTMLElement("script") }} 
{{ HTMLElement("noscript") }} 
- -

Sections

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BaliseDescription
{{ HTMLElement("body") }} 
{{ HTMLElement("section") }} 
{{ HTMLElement("nav") }} 
{{ HTMLElement("article") }} 
{{ HTMLElement("aside") }} 
<h1>,<h2>,<h3>,<h4>,<h5>,<h6> 
{{ HTMLElement("hgroup") }} 
{{ HTMLElement("header") }} 
{{ HTMLElement("footer") }} 
{{ HTMLElement("address") }} 
- -

Contenu de type bloc

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BaliseDescription
{{ HTMLElement("p") }} 
{{ HTMLElement("hr") }} 
{{ HTMLElement("pre") }} 
{{ HTMLElement("blockquote") }} 
{{ HTMLElement("ol") }} 
{{ HTMLElement("ul") }} 
{{ HTMLElement("li") }} 
{{ HTMLElement("dl") }} 
{{ HTMLElement("dt") }} 
{{ HTMLElement("dd") }} 
{{ HTMLElement("figure") }} 
{{ HTMLElement("figcaption") }} 
{{ HTMLElement("div") }} 
- -

Les sémantiques à un niveau textuel

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BaliseDescription
{{ HTMLElement("a") }} 
{{ HTMLElement("em") }} 
{{ HTMLElement("strong") }} 
{{ HTMLElement("small") }} 
{{ HTMLElement("s") }} 
{{ HTMLElement("cite") }} 
{{ HTMLElement("q") }} 
{{ HTMLElement("dfn") }} 
{{ HTMLElement("abbr") }} 
{{ HTMLElement("data") }} 
{{ HTMLElement("time") }} 
{{ HTMLElement("code") }} 
{{ HTMLElement("var") }} 
{{ HTMLElement("samp") }} 
{{ HTMLElement("kbd") }} 
{{ HTMLElement("sub") }},{{ HTMLElement("sup") }} 
{{ HTMLElement("i") }} 
{{ HTMLElement("b") }} 
{{ HTMLElement("u") }} 
{{ HTMLElement("mark") }} 
{{ HTMLElement("ruby") }} 
{{ HTMLElement("rt") }} 
{{ HTMLElement("rp") }} 
{{ HTMLElement("bdi") }} 
{{ HTMLElement("bdo") }} 
{{ HTMLElement("span") }} 
{{ HTMLElement("br") }} 
{{ HTMLElement("wbr") }} 
- -

Les éléments d'édition

- - - - - - - - - - - - - - - - - - -
Balise 
{{ HTMLElement("ins") }} 
{{ HTMLElement("del") }} 
- -

Le contenu inclus

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Balise 
{{ HTMLElement("img") }} 
{{ HTMLElement("iframe") }} 
{{ HTMLElement("object") }} 
{{ HTMLElement("param") }} 
{{ HTMLElement("video") }} 
{{ HTMLElement("audio") }} 
{{ HTMLElement("source") }} 
{{ HTMLElement("track") }} 
{{ HTMLElement("canvas") }} 
{{ HTMLElement("map") }} 
{{ HTMLElement("area") }} 
{{ HTMLElement("svg") }} 
{{ HTMLElement("math") }} 
- -

Les données tabulaire

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Balise 
{{ HTMLElement("table") }} 
{{ HTMLElement("caption") }} 
{{ HTMLElement("colgroup") }} 
{{ HTMLElement("col") }} 
{{ HTMLElement("tbody") }} 
{{ HTMLElement("thead") }} 
{{ HTMLElement("tfoot") }} 
{{ HTMLElement("tr") }} 
{{ HTMLElement("td") }} 
{{ HTMLElement("th") }} 
- -

Les formulaires

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Balise 
{{ HTMLElement("form") }} 
{{ HTMLElement("fieldset") }} 
{{ HTMLElement("legend") }} 
{{ HTMLElement("label") }} 
{{ HTMLElement("input") }} 
{{ HTMLElement("button") }} 
{{ HTMLElement("select") }} 
{{ HTMLElement("datalist") }} 
{{ HTMLElement("optgroup") }} 
{{ HTMLElement("option") }} 
{{ HTMLElement("textarea") }} 
{{ HTMLElement("keygen") }} 
{{ HTMLElement("output") }} 
{{ HTMLElement("progress") }} 
{{ HTMLElement("meter") }} 
- -

Les éléments pour l'interactivité

- - - - - - - - - - - - - - - - - - - - - - - - - - -
Balise 
{{ HTMLElement("details") }} 
{{ HTMLElement("summary") }} 
{{ HTMLElement("command") }} 
{{ HTMLElement("menu") }} 
- -

 

diff --git a/files/fr/web/guide/html/liens_email/index.html b/files/fr/web/guide/html/liens_email/index.html deleted file mode 100644 index 77e52eafb4..0000000000 --- a/files/fr/web/guide/html/liens_email/index.html +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: Liens email -slug: Web/Guide/HTML/Liens_email -tags: - - Beginner - - Exemple - - Guide - - HTML - - Web -translation_of: Learn/HTML/Introduction_to_HTML/Creating_hyperlinks#E-mail_links -translation_of_original: Web/Guide/HTML/Email_links ---- -

Il est parfois utile de créer des liens ou des boutons qui nous permettent d'écrire un nouvel e-mail. Par exemple, on peut les utiliser pour créer un bouton « contactez-nous ». Ceci est possible grâce à l'élement HTML {{HTMLElement("a")}} et au format d'URL mailto.

- -

Bases de mailto

- -

Dans sa forme la plus basique et la plus utilisée, un lien mailto indique simplement l'adresse e-mail du destinataire. Par exemple :

- -
<a href="mailto:nullepart@mozilla.org">Envoyer l'email nulle part</a>
- -

Le résultat s'affiche comme ceci : Envoyer l'email nulle part.

- -

En réalité, l'adresse e-mail est optionelle. Si on ne l'ajoute pas (le {{htmlattrxref("href", "a")}} contiendra simplement « mailto: »), une nouvelle fenêtre du client de messagerie de l'utilisateur s'ouvrira, sans destinataire spécifié. Cela peut être utile dans le cas d'un bouton « Partager » où l'utilisateur sélectionnera les personnes auxquelles il veut envoyer un e-mail.

- -

Précisions

- -

En plus de l'adresse e-mail, on peut fournir d'autres informations. En effet, n'importe quel champ d'en-tête d'un e-mail standard peut être ajoutée à l'URL mailto. Les plus communément utilisés sont « subject », « cc » et « body » (qui n'est pas réellement un champ d'entête mais qui permet de spécifier un message court pour le nouvel email). Chaque champ et sa valeur sont indiqués comme un terme de requête.

- -
-

Note : Les valeurs de chaque champ doivent être codées au format URL.

-
- -

Échantillons d'URL mailto

- -

Voici quelques échantillons d'URL mailto:

- - - -

Notez l'utilisation de l'esperluette (&) pour séparer les champs de l'URL mailto. C'est le format standard d'écriture des URL.

- -

Exemple

- -

Si vous voulez créer un lien qui permettrait de s'inscrire à une newsletter, vous pouvez utiliser un lien mailto comme ceci :

- -
<a href="mailto:nullepart@mozilla.org?subject=Demande%20inscription%20newsletter&body=Inscrivez-moi%20%C3%A0%20votre%20newsletter%20%21%0D%0A%0D%0ANom%20complet%20%3A%0D%0A%0D%0AO%C3%B9%20avez-vous%20entendu%20parler%20de%20nous%20%3F">
-Inscrivez-vous à notre newsletter
-</a>
- -

Le résultat s'affiche comme ceci : Inscrivez-vous à notre newsletter.

- - diff --git a/files/fr/web/guide/html/using_html_sections_and_outlines/index.html b/files/fr/web/guide/html/using_html_sections_and_outlines/index.html new file mode 100644 index 0000000000..319d98e927 --- /dev/null +++ b/files/fr/web/guide/html/using_html_sections_and_outlines/index.html @@ -0,0 +1,375 @@ +--- +title: Structures et sections d'un document HTML5 +slug: Web/HTML/Sections_and_Outlines_of_an_HTML5_document +tags: + - Avancé + - Exemple + - Guide + - HTML + - HTML5 + - Section + - Structure + - Web +translation_of: Web/Guide/HTML/Using_HTML_sections_and_outlines +--- +

Cette page présente la manière dont les navigateurs définissent la structure d'un document à partir de son fichier HTML.

+ +

Structure et document outline

+ +

Le terme anglais "document outline" ou "document outlines" désigne la structure d'un document générée à partir de ses titres. Cette structure permet de fournir aux usagers une vision simplifiée du document, tel un sommaire ou une table des matières.

+ +

Les technologies d'assistances telles que les lecteurs d'écran peuvent proposer à leurs usagers de parcourir le document par ce moyen. Cela leur permet d'avoir rapidement une idée du contenu de la page ou d'aller directement à la section qui les intéresse.

+ +

Depuis HTML4, cette structure est générée à partir de la valeur absolue des différents titres. Un <h2> sera considéré comme un niveau hiérarchique plus bas qu'un <h1> et un niveau plus haut qu'un <h3>.

+ +

L'algorithme Outline HTML5, proposait quand à lui de générer cette même structure non pas à partir des titres, mais à partir de l'imbrication des <section> entre elles. Cet algorithme n'est à l'heure actuelle implémenté par aucun navigateur ou technologie d'assistance. La partie du document le concernant est donc purement indicative.

+ +

Structure d'un document depuis HTML4

+ +

La structure d'un document, à savoir la structure sémantique de ce qui est entre <body> et </body>, est fondamentale pour la présentation de la page à l'utilisateur. HTML4 utilise la notion de sections et sous-sections d'un document pour décrire sa structure. Une section est définie par un élément de division HTML ({{HTMLElement ("div")}}) contenant des éléments de titre ({{HTMLElement ("h1")}}, {{HTMLElement ("h2")}}, {{ HTMLElement ("h3")}}, {{HTMLElement ("h4")}}, {{HTMLElement ("h5")}} ou {{HTMLElement ("h6")}}), définissant son titre. Les relations entre ces éléments HTML et la division HTML conduit à la structure du document et son schéma.

+ +

Ainsi, le code suivant :

+ +

+<div class="section" id="foret-elephants">
+  <h1>Les éléphants de forêt</h1>
+  <p>Dans cet article, nous discutons des éléphants de forêt moins connus.
+     … cette section continue…
+  <div class="subsection" id="foret-habitat">
+    <h2>Habitat</h2>
+    <p>Les éléphants de forêt ne vivent pas dans les arbres mais parmi eux.
+       … ce paragraphe continue…
+  </div>
+</div>
+ +

conduit au schéma suivant :

+ +
1. Les éléphants de forêt
+  1.1 Habitat
+
+ +

Les éléments {{HTMLElement ("div")}} ne sont pas obligatoires pour définir une nouvelle section. La simple présence d'un élément de titre est suffisante pour impliquer une nouvelle section. Par conséquent :

+ +
<h1>Les éléphants de forêt</h1>
+  <p>Dans cette section, nous discutons des éléphants de forêt moins connus.
+    … cette section continue…
+
+  <h2>Habitat</h2>
+  <p>Les éléphants de forêt ne vivent pas dans les arbres mais parmi eux.
+    … ce paragraphe continue…
+
+  <h2>Régime</h2>
+
+<h1>Gerbilles de Mongolie</h1>
+
+ +

conduit au schéma suivant :

+ +
1. Les éléphants de forêt
+  1.1 Habitat
+  1.2 Régime
+2. Gerbilles de Mongolie
+ +

Problèmes résolus par HTML5

+ +

Le code HTML4 définit la structure d'un document, cependant son algorithme schématique implicite est très strict et conduit à de nombreux problèmes :

+ +
    +
  1. L'utilisation de {{HTMLElement ("div")}} pour définir les sections sémantiques, sans définir de valeurs spécifiques pour l'attribut class, rend impossible l'automatisation de l'algorithme (« {{HTMLElement ("div")}} fait-il partie de l'aperçu de la page ? Définit-il une section ou un paragraphe ? » ou « Ce {{HTMLElement ("div")}} est-il là uniquement pour le style ? »). En d'autres termes, la spécification HTML4 est très imprécise sur ce qui est une section et quel est son champ d'application. La génération automatique du schéma est importante, surtout pour les technologies d'assistance (en) qui sont susceptibles d'adapter leur façon de présenter l'information aux utilisateurs en fonction de la structure du document. HTML5 supprime la nécessité d'éléments {{HTMLElement ("div")}} dans l'algorithme par l'introduction d'un nouvel élément, {{HTMLElement ("section")}}, l'élément HTML Section.
  2. +
  3. La fusion de plusieurs documents est compliquée : l'inclusion d'un sous-document dans un document principal conduit à modifier le niveau des éléments de titres HTML afin de conserver le plan du document. Ce problème est résolu dans HTML5, les éléments de section nouvellement introduits ({{HTMLElement ("article")}}, {{HTMLElement ("section")}}, {{HTMLElement ("nav")}} et {{HTMLElement ("aside")}}) sont toujours sous-sections de la plus proche section ascendante, indépendamment des sections créées par les en-têtes internes.
  4. +
  5. En HTML4, chaque section fait partie de la structure du document. Mais les documents ne sont pas souvent linéaires. Un document peut avoir des sections spéciales contenant des informations qui n'en font pas partie, même si elles sont liées au flux principal, comme un bloc de publicité ou une boîte explication. HTML5 introduit l'élément {{HTMLElement ("aside")}} permettant à ces sections de ne pas faire partie du plan principal.
  6. +
  7. Encore une fois, en HTML4, parce que chaque section fait partie de la structure du document, il n'est pas possible d'avoir des sections contenant des informations relatives non pas au document mais au site tout entier, comme des logos, des menus, une table des matières, ou des mentions légales. À cet effet, HTML5 introduit trois éléments de section spécifiques : {{HTMLElement ("nav")}} pour des collections de liens, comme une table des matières, {{HTMLElement ("footer")}} et {{HTMLElement ("header")}} pour les informations relatives au site.
  8. +
+ +

Plus généralement HTML5 apporte la précision des caractéristiques de sectionnement et de position, permettant aux contours de documents à être prévisibles et utilisés par le navigateur afin d'améliorer l'expérience utilisateur.

+ +

L'algorithme Outline HTML5

+ +
+

Important : Aucune implémentation de cet algorithme Outline HTML5 n'existe ni dans les navigateurs web ni dans les technologies d'assistance. Elle n'a jamais fait partie de la spécification finale W3C. L'algorithme Outline ne devrait donc pas être utilisé pour transmettre la structure d'un document aux utilisateurs. Il est recommandé aux auteurs d'utiliser le rang des titres (h1-h6) pour transmettre la structure d'un document.

+
+ +

Cet algorithme propose de générer la structure du document à partir de l'imbrication des sections entre elles.

+ +

Définir des sections en HTML5

+ +

Tout le contenu se trouvant à l'intérieur de l'élément {{HTMLElement ("body")}} est une partie d'une section. Les articles en HTML5 peuvent être imbriqués. À côté de la section principale, définie par l'élément {{HTMLElement ("body")}}, les limites de la section sont définies explicitement ou implicitement. Sections explicitement définies sont le contenu dans {{HTMLElement ("body")}}, {{HTMLElement ("section")}}, {{HTMLElement ("article")}}, {{HTMLElement ("aside")}}, {{HTMLElement ("footer")}}, {{HTMLElement ("header")}} et {{HTMLElement ("nav")}} balises.

+ +
+

Remarque : Chaque section peut avoir sa propre hiérarchie rubrique. Par conséquent, même une section imbriquée peut avoir un {{HTMLElement ("h1")}}. Voir Définition des sections en HTML5

+
+ +

Prenons un exemple - ici nous avons un document avec une section de haut niveau et un pied de page défini. Dans la section de haut niveau, nous avons trois sous-sections, définies par deux éléments {{htmlelement ('section')}} et un élément {{htmlelement ('aside')}} :

+ +
<section>
+
+  <h1>éléphants de forêt</h1>
+
+  <section>
+    <h1>Introduction</h1>
+    <p>Dans cette section, nous discutons des éléphants de forêt moins connus.</p>
+  </section>
+
+  <section>
+    <h1>Habitat</h1>
+    <p>Les éléphants de forêt ne vivent pas dans les arbres mais parmi eux.</p>
+  </section>
+
+  <aside>
+    <p>bloc publicitaire</p>
+  </aside>
+
+</section>
+
+<footer>
+  <p>(c) 2010 La société Exemple</p>
+</footer>
+
+ +

Cela conduit à la structure suivante :

+ +
1. Les éléphants de forêt
+  1.1 Introduction
+  1.2 Habitat
+  1.3 Section (aside)
+ +

Définition des en-têtes en HTML5

+ +

Bien que les éléments de sectionnement HTML définissent la structure du document, un plan a également besoin de titres pour être utile. La règle de base est simple : le premier élément de titre HTML (l'un des {{HTMLElement ("h1")}}, {{HTMLElement ("h2")}}, {{HTMLElement ("h3")}}, {{HTMLElement ("h4")}}, {{HTMLElement ("h5")}}, {{HTMLElement ("h6")}}) définit le titre de la section courante.

+ +

Les éléments de titre ont un rang donné par le nombre dans le nom de l'élément, où {{HTMLElement ("h1")}} a le rang le plus élevé et {{HTMLElement ("h6")}} a le rang le plus bas. Le classement relatif ne compte que dans une section ; la structure des sections détermine le plan, et non pas le rang des titres de sections. Par exemple, ce code :

+ +
<section>
+  <h1>éléphants de forêt</h1>
+
+  <p>Dans cette section, nous discutons des éléphants de forêt moins connus.
+     Cette section continue…</p>
+
+  <section>
+    <h2>Habitat</h2>
+
+    <p>Les éléphants de forêt ne vivent pas dans les arbres mais parmi eux.
+       Ce paragraphe continue…</p>
+  </section>
+</section>
+
+<section>
+  <h3>Gerbilles de Mongolie</h3>
+
+  <p>Dans cet article, nous discutons des célèbres gerbilles mongoles.
+     Cette section continue…
+</section>
+ +

conduit à la structure suivante :

+ +
1. Les éléphants de forêt
+  1.1 Habitat
+2. Gerbilles de Mongolie
+ +

Notez que le rang de l'élément titre (dans l'exemple {{HTMLElement ("h1")}} pour la première section de niveau supérieur, {{HTMLElement ("h2")}} pour la sous-section et {{HTMLElement ("h3")}} pour la seconde section de haut niveau) n'est pas important. Tout rang peut être utilisé comme en-tête d'une section explicitement définie, bien que cette pratique ne soit pas recommandée.

+ +

Découpage implicite

+ +

Parce que les éléments de sectionnement HTML5 ne sont pas obligatoires pour définir la structure, pour conserver la compatibilité avec le Web existant dominé par HTML4, il existe un moyen de définir des sections sans eux. C'est ce qu'on appelle le découpage implicite.

+ +

Les éléments de titre HTML ({{HTMLElement ("h1")}} à {{HTMLElement ("h6")}}) définissent une nouvelle section, implicite, quand ils ne sont pas le premier en-tête de leurs sections ascendantes, explicites. La façon dont cette section implicite est positionnée dans la structure est définie par son rang par rapport au titre précédent dans leur section ascendante. Si elle est d'un rang inférieur à l'en-tête précédent, il ouvre une sous-section implicite de la section. Ce code :

+ +
<section>
+  <h1>éléphants de forêt</h1>
+
+  <p>Dans cette section, nous discutons des éléphants de forêt moins connus.
+     Cette section continue…
+
+  <h3 class="implicit subsection">Habitat</h3>
+
+  <p>Les éléphants de forêt <p> ne vivent pas dans les arbres mais parmi eux.
+     Ce paragraphe continue…
+</section>
+ +

conduit à la structure suivante :

+ +
1. Les éléphants de forêt
+  1.1 Habitat (implicitement défini par l'élément h3)
+ +

Si elle est de même rang que le titre précédent, elle ferme la section précédente (qui peut avoir été explicite !) et en ouvre une nouvelle implicite de même niveau :

+ +
<section>
+  <h1>Éléphants de forêt</h1>
+
+  <p>Dans cette section, nous discutons des éléphants de forêt moins connus.
+     Cette section continue…
+
+  <h1 class="implicit section">Gerbilles de Mongolie</h1>
+
+  <p>Les gerbilles de Mongolie sont mignons petits mammifères.
+     Cette section continue…
+</section>
+ +

conduit à la structure suivante :

+ +
1. Les éléphants de forêt
+2. Gerbilles de Mongolie (implicitement défini par l'élément h1, qui a fermé la section précédente dans le même temps)
+ +

Si elle est d'un rang supérieur au titre précédent, elle ferme la section précédente et en ouvre une nouvelle implicite de niveau supérieur :

+ +
<body>
+  <h1>Mammifères</h1>
+
+  <h2>Baleines</h2>
+
+  <p>Dans cette section, nous discutons de baleines géantes.
+     Cette section continue…
+
+  <section>
+    <h3>Éléphants de forêt</h3>
+
+    <p>Dans cet article, nous discutons des éléphants de forêt moins connus.
+       Cette section continue…
+
+    <h3>Gerbilles de Mongolie</h3>
+
+    <p>Hordes de gerbilles ont étalé leur gamme bien au-delà Mongolie.
+       Ce paragraphe continue…
+
+    <h2>Reptiles</h2>
+
+    <p>Reptiles sont des animaux à sang froid.
+       Ce paragraphe continue…
+  </section>
+</body>
+ +

conduit à la structure suivante :

+ +
1. Mammifères
+  1.1 Baleines (défini implicitement par l'élément h2)
+  1.2 éléphants de forêt (défini explicitement par l'élément section)
+  1.3 Gerbilles de Mongolie (défini implicitement par l'élément h3 qui ferme la section précédente en même temps)
+2. Reptiles (défini implicitement par l'élément h2 qui ferme la section précédente en même temps)
+
+ +

Ce n'est pas la structure à laquelle on pourrait s'attendre en jetant un coup d'œil rapide sur le balisage. Pour rendre votre balisage humainement compréhensible, il est bon d'utiliser des balises explicites pour ouvrir et fermer les sections, et de faire correspondre les niveaux des titres avec le niveau d'imbrication désiré de la section. Toutefois, cela n'est pas exigé par la spécification HTML5. Si vous trouvez que les navigateurs rendent de façon inattendue le plan de votre document, vérifiez que vos sections sont implicitement fermées par des éléments d'en-tête.

+ +

Une exception à cette règle générale – qui veut que rang du titre devrait correspondre au niveau d'imbrication de la section – concerne les sections qui peuvent être réutilisées dans d'autres documents. Par exemple, une section peut être stockée dans un système de gestion de contenu et assemblée dans des documents au moment de l'exécution. Dans ce cas, une bonne pratique consiste à commencer par {{HTMLElement ("h1")}} pour le titre de niveau supérieur de la section réutilisable. Le niveau d'imbrication de la section réutilisable sera déterminé par la hiérarchie des sections du document dans lequel elle apparaît. Les balises de section explicites sont toujours utiles dans ce cas.

+ +

Racines de sectionnement

+ +

Une racine de sectionnement est un élément HTML qui peut avoir son propre plan, mais les sections et les titres qu'elle contient ne contribuent pas à la structure de son ascendant. À côté de {{HTMLElement ("body")}}, qui est la racine logique de sectionnement d'un document, il y a souvent des éléments qui introduisent du contenu externe à la page : {{HTMLElement ("blockquote")}}, {{HTMLElement ("details")}}, {{HTMLElement ("fieldset")}}, {{HTMLElement ("figure")}} et {{HTMLElement ("td")}}.

+ +

Exemple

+ +
<section>
+  <h1>Éléphants de forêt</h1>
+  <section>
+    <h2>Introduction</h2>
+    <p>Dans cette section, nous discutons des éléphants de forêt moins connus.</p>
+  </section>
+  <section>
+    <h2>Habitat</h2>
+    <p>Les éléphants de forêt ne vivent pas dans les arbres mais parmi eux. Regardons ce que les scientifiques disent dans «&nbsp;<cite> l'éléphant de forêt à Bornéo </cite>&nbsp;»&nbsp;:
+    <blockquote>
+      <h1>Bornéo</h1>
+      <p>L'éléphant de la forêt vie à Bornéo…</p>
+    </blockquote>
+  </section>
+</section>
+
+ +

Cet exemple se traduit par la structure suivante :

+ +
1. Les éléphants de forêt
+  1.1 Introduction
+  1.2 Habitat
+ +

Cette structure ne contient pas le plan interne à l'élément {{HTMLElement ("blockquote")}}, qui, étant une citation externe, est une racine de sectionnement et isole sa structure interne.

+ +

Les sections externes à la structure

+ +

HTML5 introduit deux nouveaux éléments qui permettent de définir des sections ne faisant pas partie de la structure principale d'un document Web :

+ +
    +
  1. L'élément HTML de section ({{HTMLElement ("aside")}}) définit une section qui, bien que liée à l'élément principal, ne fait pas partie du flux principal, comme une boîte d'information ou une publicité. Il dispose de son propre plan, mais il n'appartient pas au plan principal.
  2. +
  3. L'élément HTML de section ({{HTMLElement ("nav")}}) définit une section qui contient les liens de navigation. Il peut y en avoir plusieurs dans un document, par exemple, un avec des liens internes à la page, comme une table des matières, et un autre avec des liens de navigations dans le site. Ces liens ne font pas partie du flux principal et du plan, et généralement peut ne pas être initialement rendu par le lecteur d'écran et les technologies d'assistance similaires.
  4. +
+ +

Headers and Footers

+ +

HTML5 présente également deux nouveaux éléments qui peuvent être utilisés pour marquer l'en-tête et le pied de page d'une section :

+ +
    +
  1. L'élément HTML de titre de section ({{HTMLElement ("header")}}) définit l'en-tête d'une page, contenant généralement le logo et le nom du site et, éventuellement, un menu horizontal. Malgré son nom, il n'est pas nécessairement placé au début de la page.
  2. +
  3. L'élément HTML de pied de section ({{HTMLElement ("footer")}}) définit un pied-de-page, contenant généralement les mentions légales et parfois quelques liens. Malgré son nom, il n'est pas nécessairement placé dans le bas de la page.
  4. +
+ +

Ceux-ci ne créent pas de nouvelles sections dans la structure, mais ils marquent le contenu dans les sections de la page.

+ +

Adresses dans les éléments de sectionnement

+ +

L'auteur d'un document veut souvent publier des informations de contact, le nom de l'auteur tel et son adresse. HTML4 le permet grâce à cet l'élément {{HTMLElement ("address")}}, qui a été prolongé en HTML5.

+ +

Un document peut être fait de différentes sections de différents auteurs. Une section d'un autre auteur que celui de la page principale est définie en utilisant l'élément {{HTMLElement ("article")}}. Par conséquent, l'élément {{HTMLElement ("address")}} est désormais lié à son {{HTMLElement ("body")}} ou à l'ancêtre {{HTMLElement ("article")}} le plus proche.

+ +

Utilisation des éléments HTML5 dans les navigateurs Non-HTML5

+ +

Les articles et les éléments en-têtes devraient fonctionner dans la plupart des navigateurs non HTML5. Bien que non pris en charge, ils n'ont pas besoin d'une interface spéciale DOM et ils n'ont besoin que d'un style CSS spécifique comme des éléments inconnus sont aménagés comme display: inline par défaut:

+ +
section, article, aside, footer, header, nav, hgroup {
+  display: block;
+}
+ +

Bien sûr, le développeur web peut styliser différemment, mais gardez à l'esprit que dans un navigateur non HTML5, le style par défaut est différent de ce qui est attendu de ces éléments. Notez également que le {{HTMLElement ("time")}} élément n'a pas été inclus, car le style par défaut pour elle dans un navigateur non HTML5 est le même que celui de l'une HTML5 compatible.

+ +

Cette méthode a ses limites si, comme certains navigateurs ne permettent pas de style des éléments non pris en charge. C'est le cas d'Internet Explorer (version 8 et versions antérieures), qui ont besoin d'un script spécifique pour permettre à celle-ci :

+ +
<!--[if lt IE 9]>;
+  <script>
+    document.createElement("header");
+    document.createElement("footer");
+    document.createElement("section");
+    document.createElement("aside");
+    document.createElement("nav");
+    document.createElement("article");
+    document.createElement("hgroup");
+    document.createElement("time");
+  </script>
+<![endif]-->
+ +

Ce script signifie que, dans le cas d'Internet Explorer (8 et antérieures), les scripts doivent être activés pour pouvoir afficher HTML5 et les éléments de sectionnement titres correctement. Sinon, ils ne seront pas affichés, ce qui peut être problématique, car ces éléments sont susceptibles de définir la structure de la page entière. C'est pourquoi un élément {{HTMLElement ("NoScript")}} explicite devrait être ajouté pour ce cas :

+ +
<noscript>
+  <p><strong>Attention, cette page Web nécessite que JavaScript soit activé !</strong></p>
+  <p>JavaScript est un langage de programmation couramment utilisé pour créer des effets intéractifs dans les navigateurs Web.</p>
+  <p>Malheureusement, il est désactivé dans votre navigateur. Veuillez l'activer pour afficher cette page.</p>
+  <p><a href="https://goo.gl/koeeaJ">Comment activer JavaScript ?</a></p>
+</noscript>
+ +

Cela conduit au code ci-dessous pour permettre la prise en charge des éléments de sections et d'en-têtes HTML5 dans les navigateurs non HTML5, même pour Internet Explorer (8 et antérieur), avec un retour correct pour le cas où ce dernier est configuré pour ne pas autoriser les scripts :

+ +
<!--[if lt IE 9]>
+  <script>
+    document.createElement("header");
+    document.createElement("footer");
+    document.createElement("section");
+    document.createElement("aside");
+    document.createElement("nav");
+    document.createElement("article");
+    document.createElement("hgroup");
+    document.createElement ("time");
+  </script>
+<![endif]-->
+  <noscript>
+    <p><strong>Attention, cette page Web nécessite que JavaScript soit activé !</strong></p>
+    <p>JavaScript est un langage de programmation couramment utilisé pour créer des effets interactifs dans les navigateurs Web.</p>
+    <p>Malheureusement, il est désactivé dans votre navigateur. Veuillez l'activer pour afficher cette page.</p>
+    <p><a href="https://goo.gl/koeeaJ">Comment activer JavaScript ?</a></p>
+  </noscript>
+
+ +
+

Cependant, pour des raisons d’accessibilité, un site devrait toujours pouvoir être consultable en l’absence de Javascript.

+
+ +

Conclusion

+ +

Les nouveaux éléments sémantiques introduits en HTML5 apportent la capacité de décrire la structure et le plan d'un document web d'une manière standard. Ils apportent un grand avantage pour les utilisateurs de navigateurs HTML5 et qui ont besoin de la structure pour les aider à comprendre la page, par exemple, les utilisateurs de technologies d'assistance. Ces nouveaux éléments sémantiques sont simples à utiliser et, avec très peu d'efforts, ils peuvent également être mis en œuvre dans les navigateurs ne prenant pas en charge HTML5. Par conséquent, ils devraient être utilisés sans restriction.

+ +
{{HTML5ArticleTOC()}}
-- cgit v1.2.3-54-g00ecf