Pour créer une application web avec un framework (comme Angular ou React) ou nativement (avec les Web Components), vous allez développer des composants : vous allez écrire du JavaScript pour le comportement, mais sans une vue, vos composants ne serviront à rien. Vous aurez donc besoin de HTML et CSS.
Je sais : vous pensez connaître le HTML et le CSS. Malheureusement, systématiquement, 95% de nos élèves n’ont pas des bases suffisantes sur le sujet. Le HTML est pourtant vital pour le référencement, l’ergonomie et l’accessibilité. Et le positionnement CSS, ce n’est pas aussi simple que vous le croyez.
Il est donc impératif de prendre le temps d’apprendre les fondamentaux en HTML5 et CSS3.
Vous trouverez d’autres guides et une explication plus générale ici.
L’essentiel du HTML5
Doctype
Commencez toujours votre page HTML avec ce document type, et uniquement celui-ci. Il a aussi des conséquences pour JavaScript. Pas d’exception.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> |
Encodage
Travaillez toujours en UTF-8. Certains outils modernes, comme le JSON (JavaScript Object Notation, qui remplace le XML dans la plupart des services web), fonctionnent uniquement en UTF-8.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<meta charset="utf-8"> |
Structure
Vous avez besoin de construire une structure solide, pour être capable de positionner sereinement les éléments en CSS et les manipuler en JavaScript. Regroupez les blocs qui vont ensemble autant que possible, notamment les blocs alignés horizontalement (cela sera important pour le CSS). Voyez les comme une encapsulation. Nommez vos blocs avec un id s’ils sont uniques, ou ajoutez leur une classe (un groupe) s’ils se répètent. Oubliez les tableaux.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!– Bad structure –> | |
<div>Logo (on the left)</div> | |
<div>Menu (on the right)</div> | |
<div>Article 1</div> | |
<div>Article 2</div> | |
<div>Sidebar</div> | |
<div>Footer</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!– Good structure –> | |
<div id="wrapper-global"> | |
<div id="header"> | |
<div id="header-logo">Logo (on the left)</div> | |
<div id="header-nav">Menu (on the right)</div> | |
</div> | |
<div id="wrapper-main"> | |
<div id="content"> | |
<div class="story">Article 1</div> | |
<div class="story">Article 2</div> | |
</div> | |
<div id="sidebar">Sidebar</div> | |
</div> | |
<div id="footer">Footer</div> | |
</div> |
De nouveaux blocs sémantiques ont été ajoutés en HTML5, pour améliorer le référencement et l’accessibilité.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div id="wrapper-global"> | |
<header id="header"> | |
<div id="header-logo">Logo (on the left)</div> | |
<nav id="header-nav">Menu (on the right)</nav> | |
</header> | |
<div id="wrapper-main"> | |
<main id="content"> | |
<article class="story">Article 1</article> | |
<article class="story">Article 2</article> | |
</main> | |
<aside id="sidebar">Sidebar</aside> | |
</div> | |
<footer id="footer">Footer</footer> | |
</div> |
Médias
N’oubliez pas un texte alternatif pour les images (pour l’accessibilité), ainsi que les dimensions qui sont l’unique exception d’information graphique dans le HTML (pour des raisons de performance). Privilégiez le SVG quand c’est possible, ou le PNG, et le JPEG uniquement pour des photos en haute qualité, mais en veillant à une bonne compression.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<img src="image.png" alt="Description" width="500" height="300"> |
La barre de lecture pour les vidéos n’est pas automatique, vous devez la demander. Choisissez les codecs appropriés (MPEG H.264 pour la vidéo / MP3 pour l’audio). La balise doit être fermée explicitement.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<video controls src="video.mp4" width="500" height="300"></video> |
Liens
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<a href="https://developer.mozilla.org" target="_blank">Explicit text</a> |
Sémantique
Chaque contenu (texte, images, liens…) doit être hiérarchisé avec l’un des blocs sémantiques suivants. Cela sera important pour le positionnement en CSS.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<h1>Page title</h1> | |
<h2>Sub-title</h2> | |
<h3>Sub-sub-title</h3> | |
<p>Normal text.</p> | |
<figure>Illustrative content (for example, an image)</figure> | |
<ul> | |
<li>List item</li> | |
<li>List item</li> | |
</ul> |
Ensuite, et seulement ensuite, vous pouvez donner de l’importance à certains mots pour le référencement.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<p>Hello ! This post is about this <strong>subject</strong>.</p> | |
<p><em>Introduction emphasis…</em></p> |
Quelques erreurs courantes :
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!– Bad semantics –> | |
<a href="https://developer.mozilla.org">Text</a> | |
<img src="image.png" alt="Description" width="500" height="300"> | |
<div>Text</div> | |
<span>Text</span> | |
<!– Good semantics –> | |
<p><a href="https://developer.mozilla.org">Text</a></p> | |
<figure><img src="image.png" alt="Description" width="500" height="300"></figure> | |
<div><p>Text</p></div> | |
<p>Text</p> |
Soyez vigilants avec 3 caractères spéciaux : <, >, &.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
< | |
> | |
& |
Formulaires
Les formulaires, c’est là que vous demandez à l’utilisateur d’interagir. C’est donc là que l’ergonomie et l’accessibilité doivent être impeccables. Par exemple, chaque champ doit être associé explicitement à un intitulé. Utilisez également les nouveaux types de champs.
Le nom des champs sera utilisé par le serveur, à ne pas confondre avec les id.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<form method="post" action="signup.php"> | |
<label for="signup-email">E-mail (required) :</label> | |
<input type="email" name="email" id="signup-email" required> | |
<label for="signup-password">Password (required) :</label> | |
<input type="password" name="password" id="signup-password" required> | |
<label for="signup-nickname">Nickname :</label> | |
<input type="text" name="nickname" id="signup-nickname" maxlength="250"> | |
<label for="signup-phone">Phone number :</label> | |
<input type="tel" name="phone" id="signup-phone" pattern="[0-9 \+\-\.]+"> | |
<label for="signup-website">Web site :</label> | |
<input type="url" name="website" id="signup-website"> | |
<label for="signup-birthdate">Birthdate :</label> | |
<input type="date" name="birthdate" id="signup-birthdate"> | |
<fieldset> | |
<legend>Gender :</legend> | |
<input type="radio" name="gender" id="signup-gender-n" value="n" checked> | |
<label for="signup-gender-n">Not specified</label> | |
<input type="radio" name="gender" id="signup-gender-w" value="w"> | |
<label for="signup-gender-w">Woman</label> | |
<input type="radio" name="gender" id="signup-gender-m" value="m"> | |
<label for="signup-gender-m">Man</label> | |
</fieldset> | |
<label for="signup-country">Country :</label> | |
<select name="country" id="signup-country"> | |
<option value="ca">Canada</option> | |
<option value="fr" selected>France</option> | |
</select> | |
<label for="signup-description">About you :</label> | |
<textarea name="description" id="signup-description"></textarea> | |
<input type="checkbox" name="conditions" id="signup-conditions" required> | |
<label for="signup-conditions">I accept conditions.</label>. | |
<button type="submit">Signup</button> | |
</form> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<form method="get" action="search.php"> | |
<label for="search-email">Search :</label> | |
<input type="search" name="search" id="search-input" placeholder="some keyword…"> | |
<button type="submit">Search !</button> | |
</form> |
Respectez les méthodes HTTP ou vous aurez des failles de sécurité. Choisissez get
pour des opérations de lecture (recherche, etc.) et post
pour des opérations de modification (inscription, connexion, back-office…).
Ne vous reposez pas sur une quelconque validation en HTML ou JavaScript : nous sommes côté client, cela ne peut pas être sécurisé. Les nouveaux attributs HTML5 servent seulement à l’ergonomie, vous devez impérativement tout revérifier côté serveur.
Validation HTML
Vous ne mettriez pas du code Java ou PHP en production sans avoir fait le moindre test, n’est-ce pas ? Veillez donc à garder aussi une bonne méthodologie pour le HTML. Afficher la page dans un navigateur ne suffit pas : vous verrez seulement les problèmes visuels (c’est à dire principalement des problèmes CSS) mais pas les problèmes HTML (par exemple une arborescence cassée à cause d’une balise fermante manquante). Vous manipulerez cette structure en JavaScript, n’espérez donc pas que cela se passe bien si elle est cassée.
Utilisez donc la validation HTML du W3C avant de poursuivre. Certains frameworks comme Angular vérifieront la structure pour vous.
L’essentiel du CSS3
Sélecteurs
N’importe quel élément peut être nommé avec un id et/ou plusieurs classes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<h1 id="page-title" class="title color-main">Page title</h1> |
Vous pouvez regrouper des blocs avec un <div>
comme nous l’avons déjà vu dans l’étape de structure, et vous pouvez aussi regrouper une partie d’un contenu. Mais comme vu précédemment, un <span>
seul n’a aucun sens.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<p>Some <span class="color-main">content</span>…</p> |
Nous pouvons maintenant sélectionner n’importe quoi dans la page pour le styler en CSS, et vous utiliserez aussi les mêmes sélecteurs en JavaScript pour manipuler les éléments.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* By type */ | |
h1 {} | |
/* By class */ | |
.title {} | |
/* By identifier */ | |
#page-title {} |
Factorisation (sélecteurs multiples).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
h1, | |
h2 {} |
Les sélecteurs basés sur l’arborescence. Comme vous pouvez le voir, un espace a un sens en sélecteur CSS, alors ne mettez pas d’espaces superflus, cela risque d’aboutir à un mauvais sélecteur.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* All descendants (all items of list and sublists) */ | |
#header-nav-list li {} | |
/* Children only (items of this list only) */ | |
#header-nav-list>li {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
input[type="text"] {} |
Pseudo-classes : à comprendre comme des conditions ou des filtres.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
a:hover {} | |
#header-nav-list>li:first-child {} |
Priorité des sélecteurs (piège CSS n°1)
Entre différents sélecteurs, la priorité n’est pas une question d’ordre (que ce soit dans le HTML ou le CSS) mais de spécificité. Ainsi : #id
> .class
> balise
. Si la priorité est la même, le dernier sélecteur gagne (système de cascade).
Si vous faites votre CSS d’une façon intelligente et dans le bon ordre, vous ne devriez pas trop avoir de soucis. Si jamais c’est le cas, utilisez l’outil Inspecteur dans votre navigateur.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 1. General graphics */ | |
body { | |
font-family: 'Arial', sans-serif; | |
} | |
.color-main { | |
color: rgb(255, 0, 0); | |
} | |
/* 2. Positioning */ | |
#header { | |
display: flex; | |
} |
N’utilisez pas !important
. Sauf dans de très rares occasions, c’est une très mauvaise pratique étant donné que cela bloque le système de surcharge.
Ne faites jamais de styles en ligne dans le HTML. Ils seraient impossibles à surcharger, et ils peuvent être interdits par une nouvelle option de sécurité en HTML5, Content Security Policy.
Graphisme
Vous devez connaître font, text-align, list-style, color, background et les unités (em
ou rem
sont recommandés).
Le CSS3 vous permet de faire du graphisme avancé sans avoir d’images lourdes à charger : polices personnalisées, dégradés, ombres pour les textes et les blocs, bordures arrondies…
Animations
Le CSS3 a introduit les transformations (rotation, translation…), les transitions et les animations autonomes. Cela sert seulement pour des animations simples et visuelles, l’interaction est toujours le rôle du JavaScript. Mais les transitions vous aideront particulièrement en JavaScript, pour simplifier le développement d’animations (avant, nous devions coder des décomptes
récursifs complexes).
Une transition ne fait rien par elle-même : dans cet exemple, elle dit simplement : s’il y a une quelconque modification de la marge gauche de l’élément, le faire en 5 secondes plutôt qu’instantanément.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#some-element { | |
transition: margin-left 5s; | |
} |
En JavaScript, vous aurez l’événement transitionend
pour savoir quand la transition est terminée.
Normalisation et box-sizing (piège CSS n°2)
Soyez conscients que par défaut, width
and height
sont les dimensions du contenu et non pas celles du bloc. C’est le principal piège en CSS car totalement contre-intuitif. Heureusement cela peut être modifié en CSS3 avec box-sizing
.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
* { | |
box-sizing: border-box; | |
} |
Cela est fait par la librairie sanitize.css, accompagné d’une normalisation des styles par défaut dans les différents navigateurs (particulièrement pour les nouvelles balises HTML5). Utilisez-la systématiquement.
Positionement (piège CSS n°3)
Vous devez connaître : width, height, max-width (souvent plus approprié pour le responsive design), margin (marges extérieures pour espacer les blocs entre eux), padding (espacement interne pour que le contenu ne soit pas collé aux bords du bloc), border, overflow (que se passe-t-il si le contenu dépasse du bloc ?).
Notez que vous pouvez donner des dimensions seulement à des blocs : <div>, <h1>, <h2>, <h3>, <p>, <figure>, <ul>, <li>, <header>, <nav>, <main>, <article>, <aside>, <footer>
… C’est pourquoi il était important de hiérarchiser chaque contenu en HTML, sinon vous n’aurez pas de bloc avec lequel travailler.
Par défaut, les éléments block
sont affichés verticalement et les éléments de contenu horizontalement (inline
).
Cela est géré automatiquement par la propriété display
. Ne la modifiez pas et n’utilisez jamais l’option inline-block
pour aligner des blocs horizontalement : ce n’est pas le but de cette valeur et cela vous causera des soucis.
Pour aligner des blocs les uns à côté des autres, utilisez seulement le nouveau système de positionnement en CSS3 :
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#header { | |
display: flex; | |
/* Optional : alignment */ | |
justify-content: space-between; | |
align-items: center; | |
} |
Vous pouvez vous initier de façon ludique au positionnement flex avec flexbox froggy.
En JavaScript, vous aurez besoin d’afficher et de masquer les éléments : utilisez seulement display
.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#popup { | |
display: none; /* Yes */ | |
visibility: hidden; /* No */ | |
} |
Une autre solution, souvent plus adéquate si vous voulez masquer un élément via JavaScript, est d’utiliser l’attribut HTML5 hidden.
Responsive design
Comme le traffic sur mobiles est désormais plus important que celui sur bureau, il est désormais obligatoire que votre site web ou votre application s’adapte automatiquement aux différentes tailles d’écran. D’abord, pensez à toujours ajouter cette ligne dans le head de votre HTML pour demander un affichage mobile à une échelle normale :
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<meta name="viewport" content="width=device-width, initial-scale=1"> |
Il ne vous reste plus ensuite qu’à adapter votre CSS (les dimensions, l’axe d’affichage, etc.) avec les media queries. Voici les principaux cas :
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Default styles for classic screens */ | |
@media all { | |
#wrapper-global { | |
max-width: 960px; /* Recommended maximum width for desktop */ | |
margin: 0 auto; /* Center the page */ | |
} | |
} | |
/* Tablets in portrait */ | |
@media all and (min-width: 760px) and (max-width: 959px) {} | |
/* Mini tablets in portrait and expansive mobiles in landscape */ | |
@media all and (min-width: 560px) and (max-width: 759px) {} | |
/* Mobiles in landscape */ | |
@media all and (min-width: 460px) and (max-width: 559px) {} | |
/* Mobiles in portrait (smallest width is 320px) */ | |
@media all and (max-width: 459px) {} |
Tout élément interactif (liens, etc.) doit mesurer au minimum 48x48px avec une marge de 8px minimum.
Vous pouvez optimiser les sources d’images (pour les performances et la qualité) avec le nouvel attribut HTML srcset
, et certaines parties de la page peuvent être adaptées en JavaScript avec les mêmes media queries (par exemple un menu trop large transformé en une boîte de sélection).