📋 À propos de ce document
Ce document rassemble les bonnes pratiques HTML appliquées par l'agence web Alsacreations.fr. Ces guidelines sont destinées à évoluer dans le temps et à s'adapter à chaque nouveau projet, en garantissant la validité, l'accessibilité et les performances.
Table des matières
- Généralités et conventions
- Structure de document
- Sémantique et architecture
- Optimisation des médias
- Formulaires et interactions
- Accessibilité
- SEO et métadonnées
Généralités et conventions
Standards et validation
- ✅ Le code HTML est valide selon les standards WHATWG : https://whatwg.org/validator/
- ✅ Encodage UTF-8 (sans BOM) pour tous les fichiers et bases de données
- ✅ Doctype HTML5 :
<!DOCTYPE html>
Règles syntaxiques
- Casse : Éléments et attributs en minuscules
- Quotes : Toujours utiliser les guillemets doubles
" - Attributs booléens : Pas de valeur redondante (ex.
requiredet nonrequired="required") - Indentation : 2 espaces (configuration EditorConfig + Prettier)
Nommage des fichiers et classes
- Séparateurs : Utiliser des tirets pour les fichiers, classes et IDs
- Fichiers :
styles-extra.css,jquery-3.0.min.css - Classes :
.slide-info,.card-header
- Fichiers :
- Langue : Privilégier l'anglais pour les attributs
classetid - IDs : Limiter leur usage et toujours doubler par une classe CSS
Ressources de référence
- Design System W3C : composants standardisés
- Open UI : spécifications comportements attendus
- Bootstrap Components : nommage de fallback
Structure de document
Modèle-type HTML5
<!DOCTYPE html>
<html lang="fr" class="no-js">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Titre unique de la page - Nom du site</title>
<!-- Styles critiques en priorité -->
<link rel="stylesheet" href="/assets/css/styles.css">
<link rel="stylesheet" href="/assets/css/print.css" media="print">
<!-- Métadonnées SEO et réseaux sociaux -->
<meta name="description" content="Description de la page">
<meta property="og:title" content="Titre unique de la page - Nom du site">
<meta property="og:description" content="Description de la page">
<meta property="og:image" content="https://www.example.com/image.jpg">
<meta property="og:image:alt" content="Description de l'image">
<meta property="og:locale" content="fr_FR">
<meta property="og:type" content="website">
<meta property="og:site_name" content="Nom du site">
<meta name="twitter:card" content="summary_large_image">
<meta property="og:url" content="https://www.example.com/page">
<link rel="canonical" href="https://www.example.com/page">
<!-- Favicon moderne -->
<link rel="icon" href="/favicon.ico" sizes="32x32">
<link rel="icon" href="/icon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="manifest" href="/manifest.json">
</head>
<body>
<!-- Contenu principal -->
<script src="/assets/js/global.js"></script>
</body>
</html>
Éléments critiques du <head>
Viewport responsive
⚠️ Important : Proscrire les syntaxes limitant l'agrandissement (
maximum-scale=1,user-scalable=no)
<meta name="viewport" content="width=device-width, initial-scale=1">
Titre et description
<!-- Max 55 caractères pour le SEO -->
<title>Titre unique de la page - Nom du site</title>
<meta name="description" content="Description concise et pertinente">
Langue et encodage
<html lang="fr">
<meta charset="UTF-8">
<!-- Langues alternatives pour sites multilingues -->
<link rel="alternate" href="https://en.example.com/" hreflang="en">
Favicon moderne
<link rel="icon" href="/favicon.ico" sizes="32x32">
<link rel="icon" href="/icon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="manifest" href="/manifest.json">
📚 Ressource : How to Favicon
Detection JavaScript
<script>
document.documentElement.classList.remove('no-js')
document.documentElement.classList.add('js')
</script>
Sémantique et architecture
Structure globale recommandée
<body>
<header id="header" role="banner">
<!-- En-tête global, navigation -->
</header>
<main id="main" role="main">
<!-- Contenu principal -->
</main>
<aside class="aside" role="complementary">
<!-- Barre latérale (extractible sans impact) -->
</aside>
<footer id="footer" role="contentinfo">
<!-- Pied de page global -->
</footer>
</body>
Éléments sémantiques privilégiés
Préférer les éléments HTML5 sémantiques aux <div> neutres :
| Élément | Usage | Exemple |
|---|---|---|
<header> |
En-tête de section ou page | Navigation principale |
<main> |
Contenu principal unique | Zone centrale |
<article> |
Contenu autonome | Article de blog |
<section> |
Section thématique | Chapitre |
<nav> |
Navigation | Menu principal |
<aside> |
Contenu tangentiel | Barre latérale |
<footer> |
Pied de section ou page | Copyright, liens |
Zones fonctionnelles spécialisées
<nav id="navigation" role="navigation">
<!-- Navigation principale -->
</nav>
<form id="search" role="search">
<!-- Recherche principale -->
</form>
Hiérarchie des titres
🎯 Règle : Une seule balise
<h1>par page, hiérarchie logique h1→h6
<h1>Titre principal de la page</h1>
<h2>Section principale</h2>
<h3>Sous-section</h3>
<h3>Autre sous-section</h3>
<h2>Autre section principale</h2>
Convention des noms de composants
Nommage de base
- Référence prioritaire : Open UI pour les noms standard
- Référence secondaire : Bootstrap Components si non disponible
Groupes de composants
| Pattern | Convention | Exemple |
|---|---|---|
| Conteneur unique | .wrapper |
.modal-wrapper |
| Conteneur multiple | .container |
.cards-container |
| Enfant direct | *-inner |
.sidebar-inner |
| Groupe homogène | .group |
.button-group |
Layouts et états
| Type | Règle | Exemples |
|---|---|---|
| Layouts | Utiliser Bretzel | data-layout="switcher", data-layout="duo" |
| États | is- |
.is-active, .is-loading |
| Capacités | has- |
.has-dropdown, .has-error |
| JavaScript | js- |
.js-toggle, .js-menu |
Traductibilité
<!-- Contenu à ne pas traduire -->
<span translate="no">Jean Dupont</span>
<address translate="no">123 rue de la Paix, Paris</address>
Optimisation des médias
Images : règles essentielles
💡 Règle critique : Toujours ajouter
widthetheight(dimensions réelles) pour éviter les Layout Shifts
<!-- Format moderne optimisé -->
<img src="photo.avif" alt="Description précise"
width="1200" height="800"
loading="lazy" decoding="async">
Formats recommandés
Hiérarchie des formats
| Format | Usage principal | Qualité recommandée |
|---|---|---|
| AVIF | Photos, captures complexes | 60-85 |
| WebP | Schémas précis (lossless) | - |
| SVG | Illustrations vectorielles | Optimisé SVGOMG |
| JPG/PNG | Legacy uniquement | Éviter |
Largeurs suggérées
- 2000px : images pleine largeur
- 1200px : images demi-page
- 800px : cards/vignettes
Code images responsive
<!-- Format unique AVIF -->
<img src="kiwi.avif" alt="Un kiwi en tutu"
width="1200" height="800"
loading="lazy" decoding="async">
<!-- Fallback multi-formats -->
<picture>
<source type="image/avif" srcset="kiwi.avif">
<img src="kiwi.webp" alt="Un kiwi en tutu"
width="1200" height="800"
loading="lazy" decoding="async">
</picture>
Reset CSS pour images
img {
max-width: 100%; /* Largeur fluide */
height: auto; /* Ratio préservé */
background: #f0f0f0; /* Placeholder */
}
Vidéo optimisée
<video width="800" height="450" controls playsinline>
<source src="video.mp4" type="video/mp4">
<p>Votre navigateur ne supporte pas la vidéo HTML5.</p>
</video>
Outils d'optimisation
Images
- Navigateur : Squoosh, Quetsche (by Alsacréations)
- Vite : Vite Image Optimizer
- CLI : Sharp, Avif-CLI
- macOS : Image Optimizer, ImageOptim
Vidéo et audio
Formulaires et interactions
Structure accessible
<form>
<div class="field">
<label for="email">Adresse e-mail *</label>
<input type="email" id="email" name="email"
autocomplete="email" required
aria-describedby="email-help">
<small id="email-help">Format : nom@exemple.com</small>
</div>
<div class="field">
<label for="message">Message</label>
<textarea id="message" name="message"
autocomplete="off"></textarea>
</div>
<button type="submit">Envoyer</button>
</form>
Attributs d'amélioration UX
| Attribut | Fonction | Exemple |
|---|---|---|
autocomplete |
Assistance saisie | email, tel, name |
inputmode |
Clavier mobile | numeric, tel |
pattern |
Validation côté client | [0-9]{5} |
aria-describedby |
Aide contextuelle | Référence ID d'aide |
Liens externes sécurisés
⚠️ Sécurité : Toujours utiliser
rel="noopener"surtarget="_blank"
<!-- Lien externe sécurisé -->
<a href="https://example.com" target="_blank" rel="noopener">
Site externe
</a>
<!-- Encore mieux : éviter target="_blank" -->
<a href="https://example.com">Site externe</a>
Accessibilité
📚 Référence complète : Guidelines Accessibilité
Points critiques
- Contrastes : Respecter WCAG AA (4.5:1 minimum)
- Navigation clavier : Tous les éléments interactifs accessibles
- Alternatives :
altsur images, transcriptions pour vidéos - Structure : Hiérarchie logique des titres
ARIA essentiel
<!-- Landmarks -->
<nav aria-label="Navigation principale">
<main aria-label="Contenu principal">
<!-- États dynamiques -->
<button aria-expanded="false" aria-controls="menu">Menu</button>
<div id="menu" aria-hidden="true">
<!-- Descriptions -->
<input aria-describedby="help-text">
<div id="help-text">Texte d'aide</div>
SEO et métadonnées
OpenGraph (réseaux sociaux)
<meta property="og:title" content="Titre unique - Nom du site">
<meta property="og:url" content="https://www.example.com/page">
<meta property="og:locale" content="fr_FR">
<meta property="og:description" content="Description de la page">
<meta property="og:image" content="https://www.example.com/image.jpg">
<meta property="og:image:alt" content="Description de l'image">
<meta property="og:type" content="website">
<meta property="og:site_name" content="Nom du site">
<meta name="twitter:card" content="summary_large_image">
Données structurées (Schema.org)
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "Titre de l'article",
"author": {
"@type": "Person",
"name": "Nom de l'auteur"
},
"datePublished": "2024-01-15"
}
</script>
Outils de validation
- OpenGraph : OpenGraph.xyz, Meta Tags
- Twitter Cards : Twitter Validator
- Données structurées : Google Rich Results Test
OpenSearch (moteur interne)
<link rel="search" type="application/opensearchdescription+xml"
title="Recherche sur le site" href="/opensearch.xml">
📚 Ressources complémentaires
- HTMLHead.dev : Référence complète pour
<head>- Josh Buchea HEAD : Collection métadonnées