Module 1 : Le Web

Technologies du Web

Maîtrisez HTML5, CSS3, JavaScript, et le rôle crucial des API et des frameworks modernes.

1h
Version Audio
Débutant
🧩

PHASE 1.3 : TECHNOLOGIES DU WEB

Version Ultra-Détaillée - Définitions & Explications Complètes

🏗️ 1. HTML5 (HyperText Markup Language)

1.1 Définition & Histoire

Définition : HTML (HyperText Markup Language) est un langage de balisage utilisé pour structurer et présenter le contenu d'une page web. Il ne s'agit pas d'un langage de programmation (il n'a pas de logique conditionnelle ou de boucles), mais d'un langage de description de contenu.

Termes clés à retenir :

  • Balise (Tag) : Un élément délimité par des chevrons < >. Ex: <p> pour un paragraphe.
  • Élément (Element) : Une balise ouvrante + son contenu + une balise fermante. Ex: <p>Texte</p>.
  • Attribut (Attribute) : Une information supplémentaire sur un élément. Ex: class="titre".
  • DOM (Document Object Model) : La représentation arborescente du document HTML en mémoire, manipulable via JavaScript.
  • Sémantique : L'utilisation de balises qui donnent du sens au contenu (ex: <article> pour un article, <nav> pour la navigation).

Détail méconnu : Le terme "HyperText" fait référence aux liens hypertextes qui permettent de naviguer d'une page à l'autre. HTML a été créé par Tim Berners-Lee en 1991 pour partager des documents scientifiques.

Historique des Versions HTML

Version Année Innovations Majeures Impact
HTML 1.0 1991 Balises basiques : titres (h1-h6), paragraphes (p), liens (a), listes (ul/ol). Premier langage de structuration du Web.
HTML 2.0 1995 Standardisation des formulaires (input, select, textarea), tables simples. Permet les interactions utilisateur et la présentation en colonnes.
HTML 3.2 1997 Tables complexes (cellules fusionnées), applets Java, scripts (JavaScript). Apporte les bases de la mise en page moderne.
HTML 4.01 1999 Séparation stricte style/contenu (CSS), frames, support des scripts étendu. Structure plus propre, meilleure accessibilité.
XHTML 1.0 2000 HTML réécrit en XML (syntaxe rigide, auto-fermantes). Meilleure interopérabilité, mais trop strict pour le Web.
HTML5 2014 Balises sémantiques (header, nav, main, article, section, footer), multimédia natif (audio, video), canvas, APIs avancées (Web Storage, Web Workers, Geolocation). Révolution : le Web devient une plateforme d'applications.

Détail méconnu : HTML5 a été développé par le WHATWG (Web Hypertext Application Technology Working Group) après un conflit avec le W3C. Il a fallu 8 ans (2006-2014) pour finaliser la spécification.

1.2 Structure Fondamentale d'une Page HTML5

Une page HTML5 suit une structure bien définie. Chaque élément a un rôle spécifique :

  • ▹
    <!DOCTYPE html> : Déclare que le document utilise HTML5. Obligatoire pour que le navigateur utilise le mode "standards" (et non le mode "quirks").
  • ▹
    <html> : L'élément racine de la page. L'attribut lang indique la langue (ex: fr, en).
  • ▹
    <head> : Contient les métadonnées (non visibles). On y trouve :
  • -
    <meta charset="UTF-8"> : Définit l'encodage des caractères (UTF-8 supporte tous les caractères du monde).
  • -
    <meta name="viewport"> : Rend la page responsive sur mobile (largeur = largeur de l'écran).
  • -
    <title> : Titre affiché dans l'onglet du navigateur et utilisé par les moteurs de recherche.
  • -
    <link> : Lien vers une ressource externe (feuille de style CSS, favicon).
  • -
    <script> : Inclus ou fait référence à du JavaScript.
  • ▹
    <body> : Contient tout le contenu visible de la page (textes, images, vidéos, formulaires, etc.).

<!DOCTYPE html>

<html lang="fr">

<head>

<!-- Métadonnées essentielles -->

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Ma Page Web</title>

<!-- Ressources externes -->

<link rel="stylesheet" href="style.css">

<script src="app.js" defer></script>

</head>

<body>

<!-- Contenu visible -->

<header>

<h1>Bienvenue sur mon site</h1>

</header>

<main>

<section>

<article>

<h2>Mon premier article</h2>

<p>Ceci est le contenu de l'article...</p>

</article>

</section>

</main>

<footer>

<p>&copy; 2026 - Mon Site</p>

</footer>

</body>

</html>

1.3 Balises Sémantiques HTML5

Définition : Les balises sémantiques donnent du sens au contenu, contrairement aux balises génériques comme <div> ou <span>. Elles améliorent le SEO (Search Engine Optimization) et l'accessibilité (lecteurs d'écran).

Balise Rôle Exemple d'utilisation Accessibilité
<header> En-tête de page ou de section. Contient généralement le logo, le titre et la navigation. <header><h1>Mon Site</h1></header> Rôle ARIA : banner.
<nav> Section contenant des liens de navigation principaux. <nav><a href="/">Accueil</a></nav> Rôle ARIA : navigation.
<main> Contenu principal de la page. Doit être unique dans la page. <main><article>...</article></main> Rôle ARIA : main.
<section> Groupe thématique de contenu. Doit avoir un titre (h2-h6). <section><h2>À propos</h2>...</section> Rôle ARIA : region (si nommée).
<article> Contenu indépendant et réutilisable (article de blog, produit, commentaire). <article><h2>Titre</h2>...</article> Rôle ARIA : article.
<aside> Contenu secondaire (sidebar, publicité, liens connexes). <aside><h3>Annonces</h3>...</aside> Rôle ARIA : complementary.
<footer> Pied de page. Contient copyright, liens annexes, informations légales. <footer><p>&copy; 2026</p></footer> Rôle ARIA : contentinfo.
<figure> Illustration avec une légende (image, diagramme, code). <figure><img src="..."/><figcaption>...</figcaption></figure> Regroupe image et légende.
<figcaption> Légende associée à une figure. <figcaption>Légende de l'image</figcaption> Associé à <figure>.
<time> Représente une date ou une heure. <time datetime="2026-07-29">29 juillet 2026</time> Format machine lisible.
<details> Contenu dépliable/pliable. <details><summary>Voir plus</summary>...</details> Accessible nativement.
<summary> Titre du contenu dépliable. <summary>Cliquez pour afficher</summary> Premier enfant de <details>.
<mark> Texte surligné (mis en évidence). <p>Ceci est <mark>important</mark></p> Visuellement distinct.

Détail méconnu : Les balises sémantiques améliorent le SEO car Google les utilise pour comprendre la structure de la page. Une page avec <article>, <section> et <header> sera mieux classée qu'une page avec uniquement des <div>.

<article>

<header>

<h1>HTML5 : Révolution du Web</h1>

<p>Publié le <time datetime="2026-07-29">29 juillet 2026</time> par <span class="author">Jean Dupont</span></p>

</header>

<section>

<h2>Les nouvelles balises sémantiques</h2>

<p>HTML5 a introduit des balises qui donnent du sens au contenu, comme <mark><article></mark>, <mark><section></mark> et <mark><nav></mark>.</p>

<figure>

<img src="html5-structure.png" alt="Structure sémantique d'une page HTML5">

<figcaption>Exemple de structure sémantique avec HTML5</figcaption>

</figure>

</section>

<aside>

<h3>Articles similaires</h3>

<ul>

<li><a href="#">CSS3 : Le style moderne</a></li>

<li><a href="#">JavaScript : Le langage du Web</a></li>

</ul>

</aside>

<footer>

<p>Catégorie : <a href="#">Développement Web</a></p>

<p>Mots-clés : <span class="tag">HTML5</span>, <span class="tag">Sémantique</span></p>

</footer>

</article>

1.4 Éléments Multimédia Natifs

Définition : HTML5 a introduit des balises permettant d'intégrer nativement des médias (images, audio, vidéo) sans nécessiter de plugins externes comme Flash ou Silverlight.

Images (<img>)

Attributs clés :

  • src : Chemin vers l'image. Obligatoire.
  • alt : Texte alternatif (description de l'image). Essentiel pour l'accessibilité et le SEO.
  • width / height : Dimensions de l'image (en pixels).
  • loading : Stratégie de chargement. lazy = chargement différé (performance).
  • decoding : Décodage asynchrone (async) pour améliorer le rendu.
  • srcset : Liste d'images pour différentes résolutions (responsive).
  • sizes : Spécifie la taille d'affichage de l'image pour le responsive.

<!-- Image basique -->

<img src="photo.jpg" alt="Description de l'image" width="300" height="200">

<!-- Figure avec légende -->

<figure>

<img src="photo.jpg" alt="Paysage montagneux" loading="lazy">

<figcaption>Vue sur les Alpes en hiver</figcaption>

</figure>

<!-- Image responsive avec srcset -->

<img src="image.jpg"

srcset="image-small.jpg 480w,

image-medium.jpg 800w,

image-large.jpg 1200w"

sizes="(max-width: 600px) 100vw, 50vw"

alt="Image responsive" loading="lazy">

<!-- Image avec format moderne (WebP) via picture -->

<picture>

<source srcset="image.webp" type="image/webp">

<source srcset="image.jpg" type="image/jpeg">

<img src="image.jpg" alt="Image" loading="lazy">

</picture>

Détail méconnu : L'attribut srcset permet de charger différentes images selon la taille de l'écran, économisant jusqu'à 70% de bande passante sur mobile. Le navigateur choisit l'image la plus adaptée.

Audio (<audio>)

Attributs clés :

  • controls : Affiche les contrôles (play, pause, volume).
  • autoplay : Lecture automatique (déconseillé pour UX).
  • loop : Lecture en boucle.
  • muted : Muet au démarrage.
  • preload : Préchargement (none, metadata, auto).

<!-- Audio basique -->

<audio controls preload="metadata">

<source src="musique.mp3" type="audio/mpeg">

<source src="musique.ogg" type="audio/ogg">

Votre navigateur ne supporte pas l'audio.

</audio>

Détail méconnu : Les navigateurs bloquent l'autoplay sur les pages au chargement pour éviter les sons intempestifs. L'utilisateur doit interagir avec la page pour lancer la lecture.

Vidéo (<video>)

Attributs clés :

  • controls : Affiche les contrôles (play, pause, volume, plein écran).
  • poster : Image d'aperçu avant le chargement.
  • width / height : Dimensions de la vidéo.
  • autoplay : Lecture automatique (déconseillé).
  • loop : Lecture en boucle.
  • muted : Muet au démarrage (nécessaire pour l'autoplay).
  • playsinline : Lecture dans le flux (pas en plein écran sur mobile).

<!-- Vidéo basique -->

<video controls width="640" height="360" poster="apercu.jpg">

<source src="video.mp4" type="video/mp4">

<source src="video.webm" type="video/webm">

Votre navigateur ne supporte pas la vidéo.

</video>

<!-- Vidéo avec sous-titres (WebVTT) -->

<video controls>

<source src="video.mp4" type="video/mp4">

<track src="sous-titres.fr.vtt" kind="subtitles" srclang="fr" label="Français" default>

<track src="sous-titres.en.vtt" kind="subtitles" srclang="en" label="English">

</video>

Canvas (Dessin 2D/3D)

Définition : <canvas> est un élément HTML qui permet de dessiner des graphiques, des animations, des jeux ou des visualisations de données via JavaScript.

Cas d'usage :

  • Graphiques et diagrammes (Chart.js, D3.js).
  • Jeux en 2D (Phaser.js, PixiJS).
  • Édition d'images (Fabric.js, Konva.js).
  • Animations (Three.js pour la 3D).
  • Visualisation de données (heatmaps, cartes).

<canvas id="monCanvas" width="500" height="300"></canvas>

<script>

const canvas = document.getElementById('monCanvas');

const ctx = canvas.getContext('2d');

// Dessiner un rectangle bleu

ctx.fillStyle = '#3498db';

ctx.fillRect(50, 50, 150, 100);

// Dessiner un cercle rouge

ctx.beginPath();

ctx.arc(300, 150, 50, 0, Math.PI * 2);

ctx.fillStyle = '#e74c3c';

ctx.fill();

// Dessiner du texte

ctx.font = '20px Arial';

ctx.fillStyle = '#2c3e50';

ctx.fillText('Texte sur Canvas', 50, 250);

// Dessiner une ligne

ctx.beginPath();

ctx.moveTo(400, 50);

ctx.lineTo(450, 200);

ctx.strokeStyle = '#2ecc71';

ctx.lineWidth = 4;

ctx.stroke();

</script>

1.5 Formulaires & Inputs HTML5

Définition : Les formulaires HTML permettent de collecter des données saisies par l'utilisateur et de les envoyer à un serveur. HTML5 a introduit de nombreux nouveaux types d'inputs et attributs pour améliorer l'expérience utilisateur et faciliter la validation.

Attributs du Formulaire

Attribut Rôle Exemple
action URL où les données sont envoyées. action="/submit"
method Méthode HTTP (GET ou POST). method="POST"
enctype Type d'encodage (pour les fichiers). enctype="multipart/form-data"
novalidate Désactive la validation HTML5. novalidate
autocomplete Active/désactive l'auto-complétion. autocomplete="on"

Types d'Inputs HTML5

Type Rôle Exemple Validation
text Texte libre. <input type="text"> Aucune.
email Adresse email. <input type="email"> Vérifie le format email.
password Mot de passe (masqué). <input type="password"> Aucune.
number Nombre. <input type="number" min="1" max="10"> Valeur numérique, min/max.
tel Numéro de téléphone. <input type="tel" pattern="[0-9]{10}"> Pattern regex.
url URL. <input type="url"> Vérifie le format URL.
date Date (sélecteur calendaire). <input type="date"> Format date valide.
time Heure. <input type="time"> Format heure valide.
datetime-local Date + Heure. <input type="datetime-local"> Format valide.
color Sélecteur de couleur. <input type="color" value="#3498db"> Couleur hexadécimale.
range Curseur (slide). <input type="range" min="0" max="100"> Valeur entre min et max.
file Téléchargement de fichier. <input type="file" accept="image/*" multiple> Type de fichier (accept).
checkbox Case à cocher. <input type="checkbox" checked> Oui/Non.
radio Bouton radio (choix unique). <input type="radio" name="genre" value="H"> Un seul sélectionné par groupe.
search Champ de recherche. <input type="search"> Aucune.
month Mois (YYYY-MM). <input type="month"> Format mois valide.
week Semaine (YYYY-Www). <input type="week"> Format semaine valide.

Attributs de Validation HTML5

Attribut Rôle Exemple
required Champ obligatoire. <input type="email" required>
pattern Validation par expression régulière. pattern="[A-Za-z]{3,}"
min / max Valeurs minimales/maximales. min="18" max="99"
minlength / maxlength Longueur minimale/maximale du texte. minlength="3" maxlength="50"
step Incrément pour les nombres. step="0.5"
placeholder Texte d'exemple (disparaît à la saisie). placeholder="Entrez votre nom"
autocomplete Active l'auto-complétion du navigateur. autocomplete="email"
autofocus Focus automatique au chargement. autofocus
multiple Sélection multiple (fichiers, emails). <input type="file" multiple>
accept Types de fichiers acceptés. accept=".jpg,.png,.pdf"
form Associe l'input à un formulaire externe. <input form="form2">

<form action="/submit" method="POST" enctype="multipart/form-data" novalidate>

<!-- Informations personnelles -->

<fieldset>

<legend>Informations personnelles</legend>

<div>

<label for="nom">Nom * :</label>

<input type="text" id="nom" name="nom" required minlength="2" maxlength="50" placeholder="Jean Dupont" autocomplete="family-name">

</div>

<div>

<label for="email">Email * :</label>

<input type="email" id="email" name="email" required placeholder="jean@example.com" autocomplete="email">

</div>

<div>

<label for="age">Âge :</label>

<input type="number" id="age" name="age" min="18" max="99" step="1">

</div>

</fieldset>

<!-- Date & heure -->

<div>

<label for="rdv">Rendez-vous :</label>

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

</div>

<!-- Couleur -->

<div>

<label for="couleur">Couleur préférée :</label>

<input type="color" id="couleur" name="couleur" value="#3498db">

</div>

<!-- Fichier -->

<div>

<label for="fichier">CV (PDF) :</label>

<input type="file" id="fichier" name="fichier" accept=".pdf">

</div>

<!-- Datalist (auto-complétion) -->

<div>

<label for="ville">Ville :</label>

<input type="text" id="ville" name="ville" list="villes" placeholder="Entrez une ville">

<datalist id="villes">

<option value="Paris">

<option value="Lyon">

<option value="Marseille">

<option value="Bordeaux">

<option value="Lille">

</datalist>

</div>

<!-- Checkbox & Radio -->

<div>

<label>

<input type="checkbox" name="newsletter" value="oui" checked>

S'inscrire à la newsletter

</label>

</div>

<fieldset>

<legend>Civilité :</legend>

<label><input type="radio" name="genre" value="M"> Monsieur</label>

<label><input type="radio" name="genre" value="F"> Madame</label>

<label><input type="radio" name="genre" value="A" checked> Autre</label>

</fieldset>

<!-- Sélecteur -->

<div>

<label for="pays">Pays :</label>

<select id="pays" name="pays" required>

<option value="">-- Choisissez un pays --</option>

<option value="FR">France</option>

<option value="BE">Belgique</option>

<option value="CH">Suisse</option>

<option value="CA">Canada</option>

</select>

</div>

<!-- Message -->

<div>

<label for="message">Message :</label>

<textarea id="message" name="message" rows="5" maxlength="500" placeholder="Votre message... (500 caractères max)"></textarea>

</div>

<!-- Range -->

<div>

<label for="niveau">Niveau (1-10) : <span id="niveauDisplay">5</span></label>

<input type="range" id="niveau" name="niveau" min="1" max="10" step="1" value="5">

</div>

<!-- Boutons -->

<button type="submit">Envoyer</button>

<button type="reset">Effacer</button>

</form>

1.6 APIs HTML5 Avancées

Définition : HTML5 a introduit de nombreuses APIs JavaScript qui permettent de créer des applications web puissantes, rivalisant avec les applications natives.

Web Storage (LocalStorage & SessionStorage)

Définition : Le Web Storage permet de stocker des données clé-valeur dans le navigateur. Il existe deux types :

  • LocalStorage : Persistant (même après la fermeture du navigateur). Limité à ~5-10 MB par domaine.
  • SessionStorage : Limitée à l'onglet. Supprimée à la fermeture de l'onglet.

// LocalStorage (persistant)

localStorage.setItem('user', JSON.stringify({ name: 'Jean', age: 30 }));

const user = JSON.parse(localStorage.getItem('user'));

localStorage.removeItem('user');

localStorage.clear();

// SessionStorage (par onglet)

sessionStorage.setItem('temp', 'Donnée temporaire');

Détail méconnu : Les données stockées dans LocalStorage sont accessibles en JavaScript par n'importe quel script de la page. Ne stockez jamais d'informations sensibles (mots de passe, tokens) sans chiffrement.

IndexedDB (Base de données NoSQL)

Définition : IndexedDB est une base de données NoSQL intégrée au navigateur, permettant de stocker des données structurées en volume (jusqu'à plusieurs gigaoctets).

Caractéristiques :

  • Stockage de données complexes (objets, fichiers).
  • Index pour des requêtes rapides.
  • Transactions ACID.
  • Asynchrone (basé sur des promesses).

// Ouvrir une base de données

const request = indexedDB.open('MaBase', 1);

request.onupgradeneeded = (event) => {

const db = event.target.result;

// Créer un "object store" (table)

const store = db.createObjectStore('utilisateurs', { keyPath: 'id' });

// Créer un index sur le nom

store.createIndex('nom', 'nom', { unique: false });

};

request.onsuccess = (event) => {

const db = event.target.result;

// Ajouter des données

const transaction = db.transaction(['utilisateurs'], 'readwrite');

const store = transaction.objectStore('utilisateurs');

store.add({ id: 1, nom: 'Dupont', age: 30 });

// Lire des données

const getRequest = store.get(1);

getRequest.onsuccess = () => {

console.log(getRequest.result);

};

// Recherche par index

const index = store.index('nom');

const searchRequest = index.get('Dupont');

searchRequest.onsuccess = () => {

console.log(searchRequest.result);

};

};

Web Workers (Multi-threading)

Définition : Les Web Workers permettent d'exécuter du JavaScript en arrière-plan (dans un thread séparé) sans bloquer l'interface utilisateur (UI).

Termes clés :

  • Dedicated Worker : Un worker dédié à un seul script (le plus courant).
  • Shared Worker : Partagé entre plusieurs onglets.
  • Service Worker : Intercepteur réseau (hors-ligne, push notifications).

// main.js - Script principal

const worker = new Worker('worker.js');

// Envoyer des données au worker

worker.postMessage({

action: 'calcul',

data: 1000000

});

// Recevoir le résultat du worker

worker.onmessage = (event) => {

console.log('Résultat du worker :', event.data);

};

// Gérer les erreurs

worker.onerror = (error) => {

console.error('Erreur worker :', error);

};

// worker.js - Script du worker

self.onmessage = (event) => {

// Simuler un calcul lourd

let result = 0;

for (let i = 0; i < event.data.data; i++) {

result += i;

}

// Renvoyer le résultat

self.postMessage(result);

};

Service Workers (Hors-ligne & Notifications)

Définition : Un Service Worker est un proxy réseau qui s'exécute en arrière-plan, permettant de intercepter les requêtes réseau et de gérer le cache pour un fonctionnement hors-ligne.

Cas d'usage :

  • Mode hors-ligne (PWA - Progressive Web Apps).
  • Push notifications.
  • Mises à jour en arrière-plan.
  • Gestion du cache (stratégies de cache).

// Enregistrement du Service Worker

if ('serviceWorker' in navigator) {

window.addEventListener('load', () => {

navigator.serviceWorker.register('/sw.js')

.then(reg => console.log('SW enregistré :', reg))

.catch(err => console.error('Erreur SW :', err));

});

}

// sw.js

// Phase d'installation

self.addEventListener('install', (event) => {

event.waitUntil(

caches.open('v1').then((cache) => {

return cache.addAll([

'/',

'/style.css',

'/app.js',

'/offline.html'

]);

})

);

});

// Phase d'activation

self.addEventListener('activate', (event) => {

event.waitUntil(

caches.keys().then((cacheNames) => {

return Promise.all(

cacheNames.map((cacheName) => {

if (cacheName !== 'v1') {

return caches.delete(cacheName);

}

})

);

})

);

});

// Interception des requêtes

self.addEventListener('fetch', (event) => {

event.respondWith(

caches.match(event.request)

.then((response) => {

// Cache hit - retourner la réponse en cache

if (response) { return response; }

// Cache miss - faire la requête réseau

return fetch(event.request).then((response) => {

// Cloner la réponse pour le cache

const responseClone = response.clone();

caches.open('v1').then((cache) => {

cache.put(event.request, responseClone);

});

return response;

});

})

.catch(() => {

// Hors-ligne - afficher la page offline

return caches.match('/offline.html');

})

);

});

WebSocket (Communication bidirectionnelle)

Définition : WebSocket est un protocole qui permet une communication bidirectionnelle et persistante entre un client et un serveur. Contrairement à HTTP (requête-réponse), WebSocket maintient une connexion ouverte.

Cas d'usage :

  • Chat en temps réel.
  • Jeux multijoueurs.
  • Trading financier (données en temps réel).
  • Notifications push.
  • Collaboration en temps réel (Google Docs).

// Créer une connexion WebSocket

const socket = new WebSocket('wss://api.example.com/ws');

// Connexion établie

socket.onopen = () => {

console.log('Connexion WebSocket établie');

// Envoyer un message

socket.send(JSON.stringify({

type: 'hello',

user: 'Jean'

}));

};

// Réception d'un message

socket.onmessage = (event) => {

const data = JSON.parse(event.data);

console.log('Message reçu :', data);

};

// Gestion des erreurs

socket.onerror = (error) => {

console.error('Erreur WebSocket :', error);

};

// Fermeture de la connexion

socket.onclose = (event) => {

console.log('Connexion fermée :', event.code, event.reason);

};

// Envoyer un message à tout moment

function sendMessage(text) {

if (socket.readyState === WebSocket.OPEN) {

socket.send(JSON.stringify({ type: 'message', content: text }));

}

}

WebRTC (Communication Audio/Vidéo)

Définition : WebRTC (Web Real-Time Communication) est une technologie qui permet une communication peer-to-peer (pair-à-pair) en temps réel pour l'audio, la vidéo et le partage de données.

Termes clés :

  • getUserMedia : API pour accéder à la caméra et au microphone.
  • RTCPeerConnection : Gère la connexion peer-to-peer.
  • RTCDataChannel : Canal pour échanger des données arbitraires.
  • STUN/TURN : Serveurs pour la traversée des NAT (Network Address Translation).

// Accéder à la caméra et au microphone

navigator.mediaDevices.getUserMedia({

video: {

width: { ideal: 1280 },

height: { ideal: 720 }

},

audio: true

})

.then((stream) => {

// Afficher le flux local

const videoElement = document.getElementById('localVideo');

videoElement.srcObject = stream;

// Stocker le flux pour la connexion

localStream = stream;

})

.catch((error) => {

console.error('Erreur média :', error);

});

// Créer une connexion peer-to-peer

const peerConnection = new RTCPeerConnection({

iceServers: [

{ urls: 'stun:stun.l.google.com:19302' },

{ urls: 'turn:turn.example.com', username: 'user', credential: 'pass' }

]

});

// Ajouter le flux local

localStream.getTracks().forEach(track => {

peerConnection.addTrack(track, localStream);

});

// Recevoir le flux distant

peerConnection.ontrack = (event) => {

const remoteVideo = document.getElementById('remoteVideo');

remoteVideo.srcObject = event.streams[0];

};

// Créer une offre (caller)

async function createOffer() {

const offer = await peerConnection.createOffer();

await peerConnection.setLocalDescription(offer);

// Envoyer l'offre au pair via un canal (WebSocket)

sendOffer(offer);

}

// Accepter une offre (callee)

async function acceptOffer(offer) {

await peerConnection.setRemoteDescription(offer);

const answer = await peerConnection.createAnswer();

await peerConnection.setLocalDescription(answer);

// Envoyer la réponse au pair

sendAnswer(answer);

}

Geolocation API

Définition : L'API Geolocation permet d'obtenir la position géographique de l'utilisateur (latitude, longitude, altitude, précision). Elle nécessite la permission de l'utilisateur.

// Obtenir la position une fois

navigator.geolocation.getCurrentPosition(

(position) => {

console.log('Latitude :', position.coords.latitude);

console.log('Longitude :', position.coords.longitude);

console.log('Précision :', position.coords.accuracy, 'mètres');

console.log('Altitude :', position.coords.altitude);

console.log('Vitesse :', position.coords.speed);

},

(error) => {

switch (error.code) {

case error.PERMISSION_DENIED:

console.error('Permission refusée');

break;

case error.POSITION_UNAVAILABLE:

console.error('Position indisponible');

break;

case error.TIMEOUT:

console.error('Délai d\'attente dépassé');

break;

}

},

// Options

{ enableHighAccuracy: true, timeout: 5000, maximumAge: 0 }

);

// Suivre la position en continu

const watchId = navigator.geolocation.watchPosition(

(position) => {

console.log('Nouvelle position :', position.coords.latitude, position.coords.longitude);

},

(error) => console.error(error),

{ enableHighAccuracy: true, timeout: 10000 }

);

// Arrêter le suivi

navigator.geolocation.clearWatch(watchId);

Intersection Observer (Lazy Loading)

Définition : L'Intersection Observer permet de détecter quand un élément entre ou sort du viewport (zone visible de l'écran). C'est très utile pour le lazy loading (chargement différé) des images.

Cas d'usage :

  • Lazy loading d'images.
  • Infinite scroll (chargement à mesure du scroll).
  • Analytics (détection de visibilité).
  • Animations au scroll.

// Créer un observer

const observer = new IntersectionObserver((entries) => {

entries.forEach(entry => {

if (entry.isIntersecting) {

// L'élément est visible

const img = entry.target;

img.src = img.dataset.src;

observer.unobserve(img); // Arrêter l'observation

}

});

}, {

// Options

root: null, // Viewport par défaut

rootMargin: '0px 0px 200px 0px', // Marges d'anticipation

threshold: 0.1 // 10% de visibilité

});

// Observer les images avec data-src

document.querySelectorAll('img[data-src]').forEach(img => {

observer.observe(img);

});

Fullscreen API

Définition : La Fullscreen API permet de demander à un élément d'occuper tout l'écran (plein écran), idéal pour les vidéos, les jeux ou les applications.

// Demander le plein écran

const element = document.documentElement; // Toute la page

element.requestFullscreen()

.then(() => console.log('Mode plein écran activé'))

.catch(err => console.error('Erreur plein écran :', err));

// Quitter le plein écran

document.exitFullscreen();

// Vérifier l'état

document.fullscreenElement !== null; // true si plein écran

// Événements

document.addEventListener('fullscreenchange', () => {

console.log(document.fullscreenElement ? 'Plein écran' : 'Normal');

});

document.addEventListener('fullscreenerror', (event) => {

console.error('Erreur plein écran :', event);

});

Notification API

Définition : La Notification API permet d'afficher des notifications système à l'utilisateur, même lorsque la page est en arrière-plan.

// Demander la permission

Notification.requestPermission()

.then(permission => {

if (permission === 'granted') {

console.log('Notifications autorisées');

} else if (permission === 'denied') {

console.log('Notifications refusées');

}

});

// Envoyer une notification

function sendNotification(title, body, icon = '/icon.png') {

if (Notification.permission === 'granted') {

new Notification(title, {

body: body,

icon: icon,

tag: 'notification-' + Date.now(),

requireInteraction: true,

silent: false,

actions: [

{ action: 'view', title: 'Voir' },

{ action: 'dismiss', title: 'Ignorer' }

]

});

}

}

// Gérer les clics sur les notifications

navigator.serviceWorker.addEventListener('notificationclick', (event) => {

event.notification.close();

if (event.action === 'view') {

clients.openWindow('/messages');

}

});

1.7 Accessibilité & ARIA

Définition : ARIA (Accessible Rich Internet Applications) est un ensemble d'attributs qui rendent les applications web plus accessibles aux personnes handicapées (notamment les lecteurs d'écran).

Attribut ARIA Rôle Exemple
role Définit le rôle d'un élément (pour les lecteurs d'écran). role="button"
aria-label Étiquette lisible par les lecteurs d'écran. aria-label="Fermer la fenêtre"
aria-labelledby Référence l'ID d'un élément qui sert d'étiquette. aria-labelledby="title-id"
aria-describedby Référence une description supplémentaire. aria-describedby="desc-id"
aria-hidden Cache un élément des lecteurs d'écran. aria-hidden="true"
aria-expanded Indique si un élément est déplié. aria-expanded="false"
aria-checked État d'une case à cocher ou d'un radio. aria-checked="true"
aria-controls Indique quel élément est contrôlé. aria-controls="menu-dropdown"
aria-live Annonce les mises à jour en temps réel. aria-live="polite"
aria-invalid Indique une entrée invalide. aria-invalid="true"

<!-- Bouton accessible -->

<button role="button" aria-label="Fermer le dialogue" aria-expanded="false" id="closeBtn">

<span aria-hidden="true">✕</span>

</button>

<!-- Navigation accessible -->

<nav role="navigation" aria-label="Navigation principale">

<ul>

<li><a href="/" aria-current="page">Accueil</a></li>

<li><a href="/about">À propos</a></li>

</ul>

</nav>

<!-- Formulaire accessible -->

<div role="form" aria-labelledby="form-title">

<h2 id="form-title">Contact</h2>

<label for="email">Email :</label>

<input type="email" id="email" aria-required="true" aria-describedby="email-desc">

<span id="email-desc">Veuillez entrer une adresse email valide</span>

</div>

<!-- Contenu dynamique (aria-live) -->

<div aria-live="polite" aria-atomic="true" id="status">

Le contenu sera annoncé automatiquement quand il change

</div>

🎨 2. CSS3 (Cascading Style Sheets)

2.1 Définition & Histoire

Définition : CSS (Cascading Style Sheets) est un langage de style utilisé pour décrire la présentation d'un document HTML (couleurs, polices, mise en page, animations). Il sépare le contenu (HTML) de son apparence (CSS).

Termes clés :

  • Sélecteur (Selector) : Permet de cibler un ou plusieurs éléments HTML. Ex: .class, #id, div.
  • Propriété (Property) : L'aspect à modifier. Ex: color, font-size.
  • Valeur (Value) : La nouvelle valeur de la propriété. Ex: red, 16px.
  • Règle (Rule) : Un sélecteur + un bloc de déclarations. Ex: p { color: red; }.
  • Cascade : Le mécanisme par lequel le navigateur résout les conflits entre différentes règles CSS.
  • Spécificité : Un score qui détermine quelle règle s'applique en cas de conflit.

Détail méconnu : Le mot "Cascading" (en cascade) fait référence à la manière dont les styles se superposent : plusieurs sources (auteur, utilisateur, navigateur) peuvent définir des styles pour le même élément.

Historique des Versions CSS

Version Année Innovations Majeures Impact
CSS 1 1996 Styles de base : couleurs (color), polices (font-family), marges (margin), padding. Première séparation contenu/style.
CSS 2 1998 Positionnement (position), z-index, media types (print, screen), flottants (float). Permet des mises en page complexes.
CSS 2.1 2004 Corrections, standardisation, support des tableaux (display: table). Version stable de référence.
CSS3 2011+ Approche modulaire : Flexbox, Grid, Animations, Transitions, Border-radius, Box-shadow, Gradients, Media Queries, Variables (Custom Properties). Révolution : fin des hacks, designs complexes et responsives.
CSS4 En développement Container Queries, Nesting, :has() selector, scroll-driven animations. Évolution incrémentale de CSS3.

Détail méconnu : CSS3 n'est pas une version unique, mais un ensemble de 50+ modules indépendants, chacun évoluant à son propre rythme (ex: Flexbox, Grid, Animations, etc.).

2.2 Sélecteurs CSS

Définition : Un sélecteur est un motif qui permet de cibler un ou plusieurs éléments HTML pour leur appliquer des styles.

Sélecteurs Basiques

Sélecteur Syntaxe Exemple Spécificité
Type element p { color: blue; } 0,0,1
Classe .class .important { font-weight: bold; } 0,1,0
ID #id #header { background: #333; } 1,0,0
Universel * * { margin: 0; } 0,0,0
Attribut [attr] input[type="text"] { border: 1px solid #ccc; } 0,1,0
Descendant A B article p { color: red; } 0,0,2
Enfant direct A > B ul > li { list-style: none; } 0,0,2
Adjacent A + B h1 + p { margin-top: 0; } 0,0,2
Frère général A ~ B h1 ~ p { color: gray; } 0,0,2
Groupe A, B h1, h2, h3 { color: #333; } 0,0,1 (chacun)

Sélecteurs Avancés (CSS3)

Sélecteur Syntaxe Exemple Explication
Attribut (début) [attr^=value] a[href^="https"] { color: green; } Cible les liens HTTPS.
Attribut (fin) [attr$=value] a[href$=".pdf"] { color: red; } Cible les liens vers des PDF.
Attribut (contient) [attr*=value] a[href*="google"] { background: yellow; } Cible les liens contenant "google".
:first-child :first-child p:first-child { font-weight: bold; } Premier enfant de son parent.
:last-child :last-child p:last-child { color: blue; } Dernier enfant de son parent.
:nth-child :nth-child(n) li:nth-child(2n+1) { background: #f0f0f0; } Éléments impairs (1,3,5,...).
:nth-of-type :nth-of-type(n) li:nth-of-type(3) { color: red; } 3ème élément de son type.
:first-of-type :first-of-type p:first-of-type { font-weight: bold; } Premier élément de son type.
:only-of-type :only-of-type p:only-of-type { text-transform: uppercase; } Seul élément de son type.
:not :not(selector) div:not(.excluded) { color: green; } Tous sauf ceux avec .excluded.
:is :is(selector1, selector2) :is(header, footer, nav) { background: #eee; } Simplifie les sélecteurs multiples.
:where :where(selector1, selector2) :where(header, footer) { color: blue; } Comme :is mais avec une spécificité nulle.
:has :has(selector) figure:has(img) { border: 1px solid #ccc; } Cible les figures contenant une image.
::placeholder ::placeholder input::placeholder { color: #999; } Style du placeholder d'un input.
::selection ::selection ::selection { background: #ff0; color: #000; } Style du texte sélectionné.
:focus-visible :focus-visible button:focus-visible { outline: 2px solid blue; } Focus uniquement pour les interactions clavier.

Pseudo-classes de Formulaire

Pseudo-classe Exemple Explication
:valid input:valid { border-color: green; } Input valide (validation HTML5).
:invalid input:invalid { border-color: red; } Input invalide.
:required input:required { border-left: 3px solid red; } Input obligatoire.
:optional input:optional { border-left: 3px solid blue; } Input optionnel.
:checked input:checked + label { font-weight: bold; } Checkbox ou radio cochée.
:disabled input:disabled { opacity: 0.5; } Input désactivé.
:enabled input:enabled { cursor: pointer; } Input activé (par défaut).
:in-range input:in-range { background: #e8f5e9; } Valeur dans la plage (min/max).
:out-of-range input:out-of-range { background: #ffebee; } Valeur hors plage.
:focus input:focus { outline: 2px solid #3498db; } Input en focus (clic ou tabulation).

2.3 Le Box Model

Définition : Le Box Model (modèle de boîte) est le concept fondamental qui décrit comment chaque élément HTML est représenté dans le navigateur comme une boîte rectangulaire composée de quatre zones :

  • Content (Contenu) : La zone où le contenu réel (texte, image) est affiché. Dimensions définies par width et height.
  • Padding (Remplissage) : L'espace intérieur entre le contenu et la bordure. Agrandit la taille totale de la boîte.
  • Border (Bordure) : Le contour de la boîte. Peut avoir une épaisseur, un style et une couleur.
  • Margin (Marge) : L'espace extérieur entre la boîte et les éléments voisins. N'affecte pas la taille de la boîte.

┌────────────────────────────────────────────────────┐

│ MARGIN (extérieur) │

│ ┌──────────────────────────────────────────────┐ │

│ │ BORDER │ │

│ │ ┌──────────────────────────────────────────┐ │ │

│ │ │ PADDING │ │ │

│ │ │ ┌──────────────────────────────────────┐ │ │ │

│ │ │ │ CONTENT │ │ │ │

│ │ │ │ (width x height) │ │ │ │

│ │ │ └──────────────────────────────────────┘ │ │ │

│ │ └──────────────────────────────────────────┘ │ │

│ └──────────────────────────────────────────────┘ │

└────────────────────────────────────────────────────┘

/* Box Model avec box-sizing: content-box (par défaut) */

.element-content-box {

width: 200px; /* Largeur du contenu UNIQUEMENT */

height: 100px;

padding: 20px; /* Ajoute 20px de chaque côté */

border: 2px solid #333; /* Ajoute 2px de chaque côté */

margin: 20px;

/* Taille totale = 200 + 40 + 4 = 244px de large */

}

/* Box Model avec box-sizing: border-box (recommandé) */

.element-border-box {

box-sizing: border-box;

width: 200px; /* Largeur TOTALE (content + padding + border) */

height: 100px;

padding: 20px;

border: 2px solid #333;

/* Taille totale = 200px (le contenu est réduit) */

}

/* Appliquer border-box à tous les éléments */

*, *::before, *::after {

box-sizing: border-box;

}

2.4 Positionnement & Display

La propriété display

Valeur Comportement Exemple
block Occupe toute la largeur disponible. Force un saut de ligne. div, p, h1, section
inline Sur la même ligne que les éléments adjacents. Ignore width/height. span, a, strong, em
inline-block Comme inline mais peut avoir width/height et padding. boutons personnalisés
flex Active le modèle Flexbox (disposition flexible). conteneurs flex
grid Active le modèle CSS Grid (disposition en grille). conteneurs grid
none Cache l'élément (il disparaît du flux). cacher des éléments
table Comportement d'un tableau HTML. anciennes mises en page

La propriété position

Valeur Comportement Référence Cas d'usage
static Position normale (par défaut). Flux du document. La plupart des éléments.
relative Se déplace par rapport à sa position normale. Sa position normale. Décaler un élément sans affecter le flux.
absolute Sort du flux. Positionné par rapport au parent positionné le plus proche. Parent positionné (relative/absolute/fixed). Overlays, tooltips, modales.
fixed Sort du flux. Positionné par rapport à la fenêtre. Viewport (fenêtre). Menus fixes, headers collants.
sticky Mix entre relative et fixed. Collant à l'écran au scroll. Viewport (au scroll). Headers de section, tableaux.

/* Exemple de positionnement */

.parent {

position: relative;

width: 400px;

height: 300px;

background: #f0f0f0;

}

.child-absolute {

position: absolute;

top: 20px;

right: 20px;

background: #3498db;

color: white;

padding: 10px;

/* Positionné à 20px du haut et 20px de la droite du parent */

}

.child-sticky {

position: sticky;

top: 10px;

background: #e74c3c;

color: white;

padding: 10px;

/* Reste collé en haut quand on scroll */

}

2.5 Flexbox (Flexible Box Layout)

Définition : Flexbox est un modèle de mise en page qui permet de distribuer et d'aligner les éléments dans un conteneur, même si leurs tailles sont inconnues ou dynamiques. Il est unidimensionnel (une ligne ou une colonne).

Termes clés :

  • Flex Container : L'élément parent avec display: flex.
  • Flex Item : Un enfant direct du flex container.
  • Main Axis (Axe Principal) : La direction principale (par défaut horizontale).
  • Cross Axis (Axe Secondaire) : La direction perpendiculaire (par défaut verticale).

/* Conteneur Flex */

.flex-container {

display: flex;

/* Direction */

flex-direction: row; /* Default : horizontal */

flex-direction: column; /* Vertical */

flex-direction: row-reverse;

flex-direction: column-reverse;

/* Retour à la ligne */

flex-wrap: nowrap; /* Default : pas de retour */

flex-wrap: wrap; /* Retour à la ligne */

flex-wrap: wrap-reverse;

/* Alignement sur l'axe principal (justify-content) */

justify-content: flex-start; /* Default */

justify-content: flex-end;

justify-content: center;

justify-content: space-between; /* Espace entre les éléments */

justify-content: space-around; /* Espace autour des éléments */

justify-content: space-evenly; /* Espace égal */

/* Alignement sur l'axe secondaire (align-items) */

align-items: stretch; /* Default : étirer */

align-items: flex-start;

align-items: flex-end;

align-items: center;

align-items: baseline; /* Aligner sur la ligne de base du texte */

/* Alignement des lignes (multi-lignes) */

align-content: stretch; /* Default */

align-content: flex-start;

align-content: flex-end;

align-content: center;

align-content: space-between;

align-content: space-around;

/* Espacement */

gap: 20px; /* Espace entre les éléments */

gap: 10px 20px; /* row-gap column-gap */

}

/* Éléments Flex */

.flex-item {

/* Ordre visuel */

order: 1; /* Default : 0 */

/* Croissance */

flex-grow: 1; /* 0 = ne grandit pas (default) */

flex-grow: 2; /* Grandit 2x plus que les autres */

/* Rétrécissement */

flex-shrink: 1; /* 1 = rétrécit (default) */

flex-shrink: 0; /* Ne rétrécit pas */

/* Taille de base */

flex-basis: 100px; /* Taille initiale */

flex-basis: auto; /* Basé sur le contenu (default) */

/* Raccourci */

flex: 1; /* flex-grow:1, flex-shrink:1, flex-basis:0% */

flex: 1 0 auto; /* flex-grow, flex-shrink, flex-basis */

/* Auto-alignement individuel */

align-self: flex-start; /* Remplace align-items */

align-self: flex-end;

align-self: center;

align-self: stretch;

}

<!-- Exemple de mise en page Flexbox -->

<div class="flex-container" style="display: flex; gap: 10px; justify-content: center; align-items: center; height: 200px; background: #f0f0f0;">

<div style="background: #3498db; padding: 20px; color: white;">1</div>

<div style="background: #e74c3c; padding: 30px; color: white;">2</div>

<div style="background: #2ecc71; padding: 40px; color: white;">3</div>

</div>

2.6 CSS Grid

Définition : CSS Grid est un modèle de mise en page bidimensionnel (lignes et colonnes) qui permet de créer des mises en page complexes plus facilement qu'avec Flexbox ou les flottants.

Termes clés :

  • Grid Container : L'élément parent avec display: grid.
  • Grid Item : Un enfant direct du grid container.
  • Grid Track : Une ligne ou une colonne.
  • Grid Cell : Une intersection d'une ligne et d'une colonne.
  • Grid Line : Les lignes de séparation entre les cellules.
  • Grid Area : Une zone rectangulaire composée de plusieurs cellules.
  • fr : Unité fractionnaire. Ex: 1fr = une part de l'espace disponible.

/* Conteneur Grid */

.grid-container {

display: grid;

/* Définition des colonnes */

grid-template-columns: 100px 200px 100px; /* 3 colonnes fixes */

grid-template-columns: 1fr 2fr 1fr; /* 3 colonnes proportionnelles */

grid-template-columns: repeat(3, 1fr); /* 3 colonnes égales */

grid-template-columns: auto 1fr auto; /* Auto + 1fr + Auto */

grid-template-columns: minmax(100px, 300px) 1fr; /* Min/Max + 1fr */

grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); /* Responsive */

/* Définition des lignes */

grid-template-rows: 100px 200px; /* 2 lignes fixes */

grid-template-rows: 1fr 2fr; /* 2 lignes proportionnelles */

grid-template-rows: auto 1fr auto; /* Header, Main, Footer */

/* Espacement */

gap: 20px; /* Espace entre les cellules */

gap: 10px 20px; /* row-gap column-gap */

/* Alignement horizontal */

justify-items: stretch; /* Default */

justify-items: start;

justify-items: end;

justify-items: center;

/* Alignement vertical */

align-items: stretch; /* Default */

align-items: start;

align-items: end;

align-items: center;

/* Alignement du conteneur */

justify-content: start; /* Default */

justify-content: end;

justify-content: center;

justify-content: space-between;

justify-content: space-around;

justify-content: space-evenly;

align-content: start; /* Default */

align-content: end;

align-content: center;

align-content: space-between;

align-content: space-around;

/* Zones nommées */

grid-template-areas:

"header header header"

"sidebar main main"

"footer footer footer";

}

/* Éléments Grid */

.grid-item {

/* Placement sur les colonnes */

grid-column: 1 / 3; /* De la colonne 1 à 3 (exclue) */

grid-column: 1 / span 2; /* 1 à 1+2=3 */

grid-column: span 2; /* Prend 2 colonnes */

/* Placement sur les lignes */

grid-row: 1 / 3; /* De la ligne 1 à 3 (exclue) */

/* Placement complet */

grid-area: 1 / 1 / 3 / 4; /* row-start / col-start / row-end / col-end */

grid-area: header; /* Utilise les zones nommées */

/* Alignement individuel */

justify-self: start;

justify-self: end;

justify-self: center;

justify-self: stretch;

align-self: start;

align-self: end;

align-self: center;

align-self: stretch;

}

<!-- Layout complet avec Grid -->

<div class="grid-container" style="display: grid; grid-template-columns: 200px 1fr; grid-template-rows: auto 1fr auto; gap: 10px; min-height: 100vh;">

<header style="grid-column: 1 / 3; background: #3498db; padding: 20px; color: white;">Header</header>

<nav style="grid-row: 2 / 3; background: #2ecc71; padding: 20px;">Sidebar</nav>

<main style="grid-row: 2 / 3; background: #f0f0f0; padding: 20px;">Main Content</main>

<footer style="grid-column: 1 / 3; background: #e74c3c; padding: 20px; color: white;">Footer</footer>

</div>

2.7 Responsive Design

Définition : Le Responsive Design est une approche qui permet à une page web de s'adapter à la taille de l'écran (mobile, tablette, desktop). Il repose sur :

  • Media Queries : Appliquer des styles en fonction des caractéristiques de l'appareil.
  • Unités relatives : em, rem, %, vw, vh, vmin, vmax.
  • Images responsives : srcset, sizes, picture.
  • Approche Mobile-First : Commencer par les styles mobile, puis ajouter des styles pour les écrans plus grands.

Media Queries

/* Types de média */

@media screen { /* Écrans */ }

@media print { /* Impression */ }

@media speech { /* Lecteurs d'écran */ }

@media all { /* Tous (par défaut) */ }

/* Breakpoints classiques */

@media (max-width: 480px) { /* Petits mobiles */ }

@media (max-width: 768px) { /* Mobiles & tablettes */ }

@media (min-width: 769px) and (max-width: 1024px) { /* Tablettes */ }

@media (min-width: 1025px) { /* Desktop */ }

@media (min-width: 1200px) { /* Grands écrans */ }

/* Approche Mobile-First */

/* Styles par défaut (mobile) */

.container { width: 100%; padding: 20px; }

/* Tablette */

@media (min-width: 768px) {

.container { max-width: 750px; margin: 0 auto; }

}

/* Desktop */

@media (min-width: 1025px) {

.container { max-width: 1000px; }

}

/* Caractéristiques de l'écran */

@media (orientation: portrait) { /* Portrait */ }

@media (orientation: landscape) { /* Paysage */ }

@media (aspect-ratio: 16/9) { /* 16/9 */ }

@media (prefers-color-scheme: dark) { /* Mode sombre */ }

@media (prefers-color-scheme: light) { /* Mode clair */ }

@media (prefers-reduced-motion: reduce) { /* Mouvement réduit */ }

@media (hover: hover) { /* Périphérique avec hover */ }

@media (hover: none) { /* Périphérique tactile */ }

Unités Responsives

Unité Description Exemple
px Pixels (absolu). font-size: 16px;
em Relatif à la taille de police du parent. padding: 1.5em;
rem Relatif à la taille de police racine (généralement 16px). font-size: 1.25rem;
% Pourcentage du parent. width: 80%;
vw 1% de la largeur du viewport. font-size: 2vw;
vh 1% de la hauteur du viewport. height: 100vh;
vmin 1% de la plus petite dimension (min(vw, vh)). font-size: 5vmin;
vmax 1% de la plus grande dimension (max(vw, vh)). font-size: 3vmax;
cqw 1% de la largeur du conteneur (Container Queries). font-size: 4cqw;

Container Queries (CSS4)

/* Définir le conteneur */

.card-container {

container-type: inline-size;

container-name: card;

}

/* Utiliser dans l'enfant */

@container card (min-width: 400px) {

.card {

display: flex;

flex-direction: row;

gap: 20px;

}

}

@container card (max-width: 399px) {

.card {

display: flex;

flex-direction: column;

}

}

Détail méconnu : Les Container Queries (CSS4) sont une révolution car elles permettent de styler un élément en fonction de la taille de son conteneur, et non plus seulement du viewport (Media Queries).

2.8 Animations & Transitions

Définition : Les transitions permettent des animations simples entre deux états (ex: hover). Les animations (avec @keyframes) permettent des séquences complexes avec plusieurs étapes.

Transitions

.element {

/* Propriété à animer */

transition-property: all; /* Toutes les propriétés */

transition-property: width, height; /* Propriétés spécifiques */

/* Durée */

transition-duration: 0.3s; /* 300ms */

/* Timing function */

transition-timing-function: ease; /* Default */

transition-timing-function: linear;

transition-timing-function: ease-in;

transition-timing-function: ease-out;

transition-timing-function: ease-in-out;

transition-timing-function: cubic-bezier(0.42, 0, 0.58, 1);

/* Délai */

transition-delay: 0.2s; /* 200ms d'attente */

/* Raccourci */

transition: all 0.3s ease 0.2s;

}

.element:hover {

width: 300px;

height: 200px;

background: #e74c3c;

transform: rotate(45deg);

}

Animations (@keyframes)

/* Définition de l'animation */

@keyframes slideIn {

0% {

transform: translateX(-100%);

opacity: 0;

}

100% {

transform: translateX(0);

opacity: 1;

}

}

@keyframes pulse {

0%, 100% {

transform: scale(1);

background: #3498db;

}

50% {

transform: scale(1.1);

background: #2ecc71;

}

}

/* Utilisation */

.element {

animation-name: slideIn;

animation-duration: 2s;

animation-timing-function: ease-in-out;

animation-delay: 0.5s;

animation-iteration-count: infinite;

animation-direction: alternate;

animation-fill-mode: forwards;

animation-play-state: running;

/* Raccourci */

animation: pulse 2s ease-in-out 0s infinite alternate;

}

2.9 Variables CSS (Custom Properties)

Définition : Les Variables CSS (Custom Properties) permettent de stocker des valeurs réutilisables (couleurs, polices, espacements) et de les modifier dynamiquement en JavaScript ou via les media queries.

Avantages :

  • Réutilisabilité (DRY).
  • Mise à jour globale facile.
  • Modifiable dynamiquement (JS).
  • Thèmes (clair/sombre).

/* Déclaration des variables */

:root {

/* Couleurs */

--color-primary: #3498db;

--color-secondary: #2ecc71;

--color-danger: #e74c3c;

--color-text: #2c3e50;

--color-background: #f8f9fa;

/* Polices */

--font-family: 'Inter', system-ui, sans-serif;

--font-size-base: 16px;

/* Espacements */

--spacing-small: 0.5rem;

--spacing-medium: 1rem;

--spacing-large: 2rem;

/* Border Radius */

--radius-small: 4px;

--radius-medium: 8px;

--radius-large: 16px;

/* Ombres */

--shadow-small: 0 1px 3px rgba(0,0,0,0.1);

--shadow-large: 0 4px 12px rgba(0,0,0,0.15);

}

/* Utilisation */

.button {

background: var(--color-primary);

color: white;

padding: var(--spacing-medium) var(--spacing-large);

border-radius: var(--radius-medium);

font-family: var(--font-family);

font-size: var(--font-size-base);

box-shadow: var(--shadow-small);

transition: all 0.3s ease;

}

.button:hover {

background: color-mix(in srgb, var(--color-primary) 80%, black 20%);

box-shadow: var(--shadow-large);

transform: scale(1.02);

}

/* Thème sombre */

@media (prefers-color-scheme: dark) {

:root {

--color-background: #1a1a1a;

--color-text: #f0f0f0;

--shadow-small: 0 1px 3px rgba(255,255,255,0.1);

}

}

/* Modification via JavaScript */

// document.documentElement.style.setProperty('--color-primary', '#e74c3c');

2.10 Fonctions CSS Avancées

/* color-mix : Mélange de couleurs */

.element { color: color-mix(in srgb, #3498db 70%, #2ecc71 30%); }

/* clamp : Valeur bornée (min, préférée, max) */

.responsive-text { font-size: clamp(1rem, 2.5vw, 2.5rem); }

/* min / max */

.responsive-width { width: min(100%, 800px); }

.responsive-width { width: max(300px, 50vw); }

/* calc : Calculs mathématiques */

.calc-element {

width: calc(100% - 40px);

height: calc(100vh - 200px);

margin: calc(10px + 2vw);

font-size: calc(1rem + 0.5vw);

}

/* var() : Variables */

.element { color: var(--color-primary, #3498db); /* Fallback */ }

/* env() : Variables d'environnement */

.safe-area { padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left); }

/* Gradients */

.gradient-linear {

background: linear-gradient(to right, #3498db, #2ecc71);

background: linear-gradient(45deg, #3498db, #2ecc71, #e74c3c);

}

.gradient-radial {

background: radial-gradient(circle, #3498db, #2ecc71);

}

.gradient-conic {

background: conic-gradient(from 0deg, #3498db, #2ecc71, #e74c3c, #3498db);

}

/* Box Shadows */

.shadow { box-shadow: 2px 4px 8px rgba(0, 0, 0, 0.1); }

.shadow-multiple { box-shadow: 0 2px 4px rgba(0,0,0,0.1), 0 8px 16px rgba(0,0,0,0.1); }

.shadow-inset { box-shadow: inset 0 2px 4px rgba(0,0,0,0.1); }

.text-shadow { text-shadow: 2px 2px 4px rgba(0,0,0,0.3); }

2.11 Frameworks CSS

Définition : Un framework CSS est un ensemble de classes prédéfinies qui accélèrent le développement en fournissant des composants réutilisables (grilles, boutons, formulaires, etc.).

Tailwind CSS (Utility-First)

<!-- Approche Utility-First (classes directement dans le HTML) -->

<div class="max-w-4xl mx-auto px-4 py-8">

<h1 class="text-3xl font-bold text-gray-900 mb-4 hover:text-blue-600 transition-colors">Bienvenue</h1>

<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">

<div class="bg-white rounded-lg shadow-md p-6 hover:shadow-lg transition-shadow">

<h2 class="text-xl font-semibold text-gray-800">Carte 1</h2>

<p class="text-gray-600 mt-2">Description de la carte</p>

<button class="mt-4 px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors">Action</button>

</div>

</div>

</div>

Détail méconnu : Tailwind CSS utilise PurgeCSS pour supprimer les classes non utilisées en production, ce qui donne un fichier CSS très léger (< 10KB).

CSS Modules

/* Button.module.css */

.button { background: #3498db; color: white; padding: 10px 20px; border: none; border-radius: 4px; }

.button:hover { background: #2980b9; }

.buttonPrimary { background: #2ecc71; }

.buttonDanger { background: #e74c3c; }

// Button.jsx

import styles from './Button.module.css';

function Button({ variant, children }) {

const className = [

styles.button,

variant === 'primary' && styles.buttonPrimary,

variant === 'danger' && styles.buttonDanger

].filter(Boolean).join(' ');

return <button className={className}>{children}</button>;

}

💻 3. JAVASCRIPT (Écosystème Moderne)

Définition : JavaScript est un langage de programmation interprété, orienté objet et asynchrone qui permet d'ajouter de l'interactivité aux pages web. C'est le langage de programmation le plus utilisé au monde.

Termes clés :

  • ES6 (ECMAScript 2015) : La version majeure qui a introduit les classes, les arrow functions, les promesses, etc.
  • Moteur JavaScript : Le programme qui exécute le code JS (V8 pour Chrome, SpiderMonkey pour Firefox).
  • Asynchrone : Capacité à exécuter des opérations sans bloquer le thread principal.
  • DOM : Document Object Model - l'interface pour manipuler la page HTML.
  • Event Loop : Mécanisme qui gère les événements et les opérations asynchrones.
  • Closure : Une fonction qui "se souvient" de son environnement lexical.

3.2 Variables & Constantes (ES6)

// let : Variable mutable, scope de bloc

let age = 30;

age = 31; // OK

// let est limité au bloc {} où il est défini

if (true) {

let blockScoped = 'visible uniquement ici';

}

// console.log(blockScoped); // Erreur !

// const : Constante, ne peut pas être réassignée

const name = 'Jean';

// name = 'Marie'; // Erreur !

// const pour les objets : la référence est constante, pas le contenu

const user = { name: 'Jean', age: 30 };

user.name = 'Marie'; // OK (propriété modifiée)

// user = { name: 'Marie' }; // Erreur (réassignation de la référence)

// var : ANCIEN (scope de fonction, hoisting) - À ÉVITER

var oldStyle = 'Ne plus utiliser';

if (true) {

var functionScoped = 'visible partout dans la fonction';

}

console.log(functionScoped); // 'visible partout dans la fonction'

3.3 Arrow Functions

// Fonction classique

function add(a, b) { return a + b; }

// Arrow function (syntaxe concise)

const add = (a, b) => a + b; // Retour implicite

const add = (a, b) => { return a + b; }; // Avec bloc

// Arrow function avec un seul paramètre

const double = x => x * 2;

// Arrow function sans paramètre

const greet = () => 'Bonjour !';

// Utilisation avec les tableaux

const numbers = [1, 2, 3, 4, 5];

const doubled = numbers.map(n => n * 2); // [2, 4, 6, 8, 10]

const evens = numbers.filter(n => n % 2 === 0); // [2, 4]

const sum = numbers.reduce((acc, n) => acc + n, 0); // 15

// Différence avec les fonctions classiques : le this

// Les arrow functions n'ont pas leur propre this (elles héritent du parent)

class Person {

constructor(name) { this.name = name; }

// Méthode classique

greetClassic() {

setTimeout(function() {

console.log('Classic:', this.name); // this = undefined !

}, 1000);

}

// Méthode avec arrow function

greetArrow() {

setTimeout(() => {

console.log('Arrow:', this.name); // this = instance de Person

}, 1000);

}

}

3.4 Template Literals

// Multi-lignes

const message = `

Bonjour ${name},

Bienvenue sur notre site !

Nous sommes ravis de vous voir.

`;

// Interpolation

const text = `J'ai ${age} ans`; // "J'ai 30 ans"

const html = `<div class="${className}">${content}</div>`;

// Expressions complexes

const price = 19.99;

const total = `Total : ${price * 1.2} €`; // Total : 23.988 €

// Tagged templates (fonctions personnalisées)

function highlight(strings, ...values) {

return strings.reduce((result, str, i) =>

result + str + (values[i] ? `<strong>${values[i]}</strong>` : ''), '');

}

const html = highlight`Bonjour ${name}, vous avez ${age} ans.`;

3.5 Destructuring

// Destructuring d'objet

const user = { name: 'Jean', age: 30, city: 'Paris' };

const { name, age, city } = user;

// console.log(name, age, city); // Jean 30 Paris

// Alias

const { name: userName, age: userAge } = user;

// Valeurs par défaut

const { country = 'France' } = user;

// Nested (objet imbriqué)

const user = { address: { street: 'Rue de Paris', number: 10 } };

const { address: { street, number } } = user;

// Destructuring de tableau

const colors = ['red', 'green', 'blue'];

const [first, second, third] = colors;

const [firstColor, ...restColors] = colors; // ['red'], ['green', 'blue']

// Destructuring dans les paramètres de fonction

function display({ name, age = 30, city = 'Inconnu' }) {

console.log(`${name} (${age}) - ${city}`);

}

display({ name: 'Jean', age: 25, city: 'Lyon' });

3.6 Spread & Rest Operators

// Spread (...) - Décomposition

// Tableaux

const arr1 = [1, 2, 3];

const arr2 = [4, 5, 6];

const combined = [...arr1, ...arr2]; // [1, 2, 3, 4, 5, 6]

const copy = [...arr1]; // Copie superficielle

// Objets

const obj1 = { a: 1, b: 2 };

const obj2 = { c: 3, d: 4 };

const merged = { ...obj1, ...obj2 }; // { a: 1, b: 2, c: 3, d: 4 }

// Fusion avec priorité

const user = { name: 'Jean', age: 30 };

const updates = { age: 31, city: 'Paris' };

const updatedUser = { ...user, ...updates }; // { name: 'Jean', age: 31, city: 'Paris' }

// Rest (...) - Regroupement

// Rest dans les paramètres de fonction

function sum(...numbers) {

return numbers.reduce((acc, n) => acc + n, 0);

}

console.log(sum(1, 2, 3, 4, 5)); // 15

// Rest dans les tableaux

const [first, ...rest] = [1, 2, 3, 4]; // first=1, rest=[2,3,4]

// Rest dans les objets

const { name, ...other } = user; // name='Jean', other={age:30, city:'Paris'}

3.7 Promises

Définition : Une Promise est un objet qui représente la résolution future d'une opération asynchrone. Elle peut être dans trois états :

  • Pending : En attente (état initial).
  • Fulfilled : Résolue avec succès (resolve).
  • Rejected : Échouée (reject).

// Création d'une Promise

const promise = new Promise((resolve, reject) => {

// Opération asynchrone

setTimeout(() => {

const success = true;

if (success) {

resolve('Opération réussie !');

} else {

reject(new Error('Opération échouée'));

}

}, 1000);

});

// Utilisation avec .then() et .catch()

promise

.then(result => {

console.log('Succès :', result);

})

.catch(error => {

console.error('Erreur :', error.message);

})

.finally(() => {

console.log('Fin de l\'opération');

});

// Chaînage de Promises

fetchUser(userId)

.then(user => fetchOrders(user.id))

.then(orders => processOrders(orders))

.then(result => console.log('Terminé :', result))

.catch(error => console.error('Erreur :', error));

// Promise.all (attendre plusieurs promesses)

Promise.all([

fetch('/api/users'),

fetch('/api/products'),

fetch('/api/orders')

])

.then(responses => Promise.all(responses.map(r => r.json())))

.then(([users, products, orders]) => {

console.log('Utilisateurs :', users);

console.log('Produits :', products);

console.log('Commandes :', orders);

});

// Promise.race (première promesse qui se termine)

Promise.race([

fetch('/api/fast'),

fetch('/api/slow')

]).then(response => console.log('Premier arrivé :', response));

3.8 Async/Await

Définition : async/await est une syntaxe qui permet d'écrire du code asynchrone de manière synchrone, rendant le code plus lisible et plus facile à maintenir.

// Fonction asynchrone

async function fetchUserData(userId) {

try {

const response = await fetch(`/api/users/${userId}`);

if (!response.ok) {

throw new Error(`HTTP error! status: ${response.status}`);

}

const user = await response.json();

return user;

} catch (error) {

console.error('Erreur de récupération :', error.message);

throw error; // Propager l'erreur

}

}

// Utilisation

async function displayUser(userId) {

try {

const user = await fetchUserData(userId);

console.log(`Nom: ${user.name}, Email: ${user.email}`);

} catch (error) {

console.error('Impossible d\'afficher l\'utilisateur');

}

}

// Exécution parallèle avec Promise.all

async function fetchAll() {

const [users, products] = await Promise.all([

fetch('/api/users').then(r => r.json()),

fetch('/api/products').then(r => r.json())

]);

return { users, products };

}

3.9 Classes ES6

// Déclaration de classe

class User {

// Constructeur

constructor(name, age) {

this.name = name;

this.age = age;

this.createdAt = new Date();

}

// Méthode d'instance

greet() {

return `Bonjour, je suis ${this.name}`;

}

// Getter

get isAdult() {

return this.age >= 18;

}

// Setter

set age(value) {

if (value < 0) throw new Error('L\'âge ne peut pas être négatif');

this._age = value;

}

// Méthode statique (appelable sans instance)

static createGuest() {

return new User('Invité', 18);

}

// Méthode privée (ES2022) - préfixée par #

#validateEmail(email) {

return email.includes('@');

}

setEmail(email) {

if (this.#validateEmail(email)) {

this.email = email;

} else {

throw new Error('Email invalide');

}

}

}

// Héritage

class Admin extends User {

constructor(name, age, role) {

super(name, age); // Appel au constructeur parent

this.role = role;

}

// Override de méthode

greet() {

return `${super.greet()} - Je suis un admin (${this.role})`;

}

// Méthode spécifique à Admin

manageUsers() {

return 'Gestion des utilisateurs';

}

}

// Utilisation

const user = new User('Jean', 30);

console.log(user.greet()); // "Bonjour, je suis Jean"

console.log(user.isAdult); // true

const guest = User.createGuest();

const admin = new Admin('Marie', 25, 'SuperAdmin');

console.log(admin.greet()); // "Bonjour, je suis Marie - Je suis un admin (SuperAdmin)"

3.10 Fetch API

Définition : Fetch est une API moderne pour effectuer des requêtes HTTP (GET, POST, PUT, DELETE). Elle retourne une Promise et est plus puissante que l'ancien XMLHttpRequest.

// Requête GET

async function getUsers() {

try {

const response = await fetch('/api/users');

if (!response.ok) {

throw new Error(`Erreur HTTP: ${response.status}`);

}

const data = await response.json();

return data;

} catch (error) {

console.error('Erreur fetch:', error);

throw error;

}

}

// Requête POST

async function createUser(userData) {

const response = await fetch('/api/users', {

method: 'POST',

headers: {

'Content-Type': 'application/json',

'Authorization': 'Bearer ' + token

},

body: JSON.stringify(userData)

});

if (!response.ok) {

throw new Error(`Erreur HTTP: ${response.status}`);

}

return await response.json();

}

// Requête PUT (mise à jour complète)

async function updateUser(userId, userData) {

const response = await fetch(`/api/users/${userId}`, {

method: 'PUT',

headers: { 'Content-Type': 'application/json' },

body: JSON.stringify(userData)

});

return await response.json();

}

// Requête PATCH (mise à jour partielle)

async function patchUser(userId, updates) {

const response = await fetch(`/api/users/${userId}`, {

method: 'PATCH',

headers: { 'Content-Type': 'application/json' },

body: JSON.stringify(updates)

});

return await response.json();

}

// Requête DELETE

async function deleteUser(userId) {

const response = await fetch(`/api/users/${userId}`, {

method: 'DELETE'

});

if (!response.ok) {

throw new Error(`Erreur HTTP: ${response.status}`);

}

return response.status === 204; // No Content

}

// Requête avec FormData (upload de fichier)

async function uploadFile(file) {

const formData = new FormData();

formData.append('file', file);

const response = await fetch('/api/upload', {

method: 'POST',

body: formData

});

return await response.json();

}

3.11 DOM Manipulation

// Sélection d'éléments

const element = document.querySelector('.my-class'); // Premier élément

const elements = document.querySelectorAll('div'); // Tous les div

const byId = document.getElementById('header'); // Par ID

const byClass = document.getElementsByClassName('item'); // Par classe

// Création d'éléments

const div = document.createElement('div');

div.textContent = 'Nouveau div';

div.className = 'my-class';

div.id = 'unique-id';

div.setAttribute('data-id', '123');

div.style.color = 'blue';

div.style.backgroundColor = '#f0f0f0';

// Ajout au DOM

document.body.appendChild(div);

document.body.prepend(div); // Au début

parent.insertBefore(div, referenceNode); // Avant un nœud

// parent.replaceChild(newNode, oldNode);

// parent.removeChild(child);

// Modifier le contenu

element.innerHTML = '<strong>Nouveau contenu</strong>';

element.textContent = 'Texte simple';

// element.innerText = 'Texte visible';

// Gestion des classes

element.classList.add('active');

element.classList.remove('inactive');

element.classList.toggle('visible');

element.classList.contains('active'); // true/false

// Événements

element.addEventListener('click', (event) => {

console.log('Clicked!', event.target);

console.log('Position X:', event.clientX);

event.preventDefault(); // Empêcher le comportement par défaut

});

// Délégation d'événements (performance)

document.querySelector('.list').addEventListener('click', (event) => {

if (event.target.matches('li')) {

console.log('Item clicked:', event.target.textContent);

}

});

// Événements courants

// click, dblclick, mouseenter, mouseleave, mouseover, mouseout

// keydown, keyup, keypress, change, input, submit

// focus, blur, scroll, resize, load, DOMContentLoaded

🔒 4. SÉCURITÉ WEB

4.1 HTTPS (Chiffrement)

Définition : HTTPS (HyperText Transfer Protocol Secure) est une version sécurisée de HTTP utilisant TLS/SSL (Transport Layer Security / Secure Sockets Layer) pour chiffrer les données échangées entre le client et le serveur.

Pourquoi HTTPS est essentiel :

  • Chiffrement des données : Les données sont illisibles en cas d'interception.
  • Intégrité : Les données ne peuvent pas être altérées en transit.
  • Authentification : Le certificat vérifie l'identité du serveur.
  • Confiance : Les utilisateurs font confiance aux sites HTTPS (cadenas vert).
  • SEO : Google pénalise les sites non-HTTPS.

// Handshake TLS simplifié

1. Client → Serveur : "Bonjour, je veux une connexion sécurisée"

2. Serveur → Client : "Voici mon certificat (clé publique)"

3. Client vérifie le certificat (autorité de certification)

4. Client → Serveur : "Voici une clé de session (chiffrée avec ta clé publique)"

5. Communication chiffrée via la clé de session (AES, CHACHA20)

4.2 CORS (Cross-Origin Resource Sharing)

Définition : CORS est un mécanisme de sécurité qui permet à un navigateur de demander à un serveur l'autorisation d'accéder à des ressources situées sur un domaine différent (cross-origin).

Termes clés :

  • Same-Origin Policy : Les pages ne peuvent faire des requêtes qu'au même domaine (protocole + domaine + port).
  • Preflight Request : Une requête OPTIONS envoyée avant une requête "non-simple" pour vérifier les permissions.
  • En-têtes CORS : Les en-têtes que le serveur doit renvoyer pour autoriser l'accès.

// En-têtes CORS côté serveur (Express)

app.use((req, res, next) => {

res.header('Access-Control-Allow-Origin', 'https://mon-site.com');

res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');

res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Custom-Header');

res.header('Access-Control-Allow-Credentials', 'true');

res.header('Access-Control-Max-Age', '86400'); // Cache preflight 24h

if (req.method === 'OPTIONS') {

return res.sendStatus(204);

}

next();

});

// Configuration CORS avec le package cors

// npm install cors

const cors = require('cors');

app.use(cors({

origin: 'https://mon-site.com',

methods: ['GET', 'POST', 'PUT', 'DELETE'],

allowedHeaders: ['Content-Type', 'Authorization'],

credentials: true,

optionsSuccessStatus: 204

}));

4.3 XSS (Cross-Site Scripting)

Définition : XSS est une attaque où un attaquant injecte du JavaScript malveillant dans une page web, qui s'exécute alors dans le navigateur des victimes.

Types :

  • Reflected XSS : Le script est injecté via l'URL (ex: ?q=<script>...</script>).
  • Stored XSS : Le script est stocké en base de données (ex: commentaires, messages).
  • DOM-based XSS : Le script manipule le DOM de manière malveillante.

// ❌ EXEMPLE VULNÉRABLE

// Si un utilisateur entre <script>alert('XSS')</script> dans un commentaire

const comment = userInput; // "<script>alert('XSS')</script>"

document.getElementById('comments').innerHTML = comment; // ❌ DANGER !

// ✅ Échappement HTML (protection)

function escapeHTML(str) {

const div = document.createElement('div');

div.textContent = str;

return div.innerHTML;

}

const safeComment = escapeHTML(userInput);

document.getElementById('comments').textContent = safeComment; // ✅ SÉCURISÉ

// ✅ Politique de sécurité du contenu (CSP)

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://images.unsplash.com;">

// ✅ Sanitize HTML (DOMPurify)

// npm install dompurify

import DOMPurify from 'dompurify';

const cleanHTML = DOMPurify.sanitize(userInput);

document.getElementById('comments').innerHTML = cleanHTML;

4.4 CSRF (Cross-Site Request Forgery)

Définition : CSRF est une attaque où un site malveillant force le navigateur d'un utilisateur authentifié à envoyer une requête non désirée vers un site légitime.

Protections :

  • Token CSRF : Un token unique généré par le serveur et inclus dans chaque formulaire.
  • SameSite Cookie : SameSite=Strict ou SameSite=Lax empêche les cookies d'être envoyés lors de requêtes cross-origin.
  • Double Submit Cookie : Envoyer le token dans un cookie et dans la requête.

// ✅ Token CSRF dans le formulaire

<form action="/transfer" method="POST">

<input type="hidden" name="csrf_token" value="${csrfToken}">

<input type="number" name="amount">

<button type="submit">Transférer</button>

</form>

// ✅ Cookie SameSite

res.cookie('session', token, {

httpOnly: true,

secure: true,

sameSite: 'Strict', // ou 'Lax'

maxAge: 7 * 24 * 60 * 60 * 1000 // 7 jours

});

4.5 SQL Injection

Définition : L'injection SQL est une attaque où l'attaquant injecte du code SQL dans une requête via des entrées utilisateur non sécurisées, permettant d'accéder ou de modifier la base de données.

Termes clés :

  • Requête préparée (Prepared Statement) : Séparation entre le code SQL et les données.
  • Paramètres : Les valeurs sont passées séparément de la requête.
  • ORM : Object-Relational Mapping (ex: Prisma, Sequelize) qui protège par défaut.

// ❌ À ÉVITER (vulnérable)

const email = req.body.email;

const query = `SELECT * FROM users WHERE email = '${email}'`;

// Si email = "admin' OR '1'='1" → SELECT * FROM users WHERE email = 'admin' OR '1'='1'

// Tous les utilisateurs sont renvoyés !

// ✅ Utiliser des paramètres préparés (PostgreSQL)

const result = await pool.query(

'SELECT * FROM users WHERE email = $1',

[req.body.email]

);

// ✅ Utiliser un ORM (Prisma)

const user = await prisma.user.findUnique({

where: { email: req.body.email }

});

// ✅ MySQL (paramètres positionnels)

const result = await connection.execute(

'SELECT * FROM users WHERE email = ?',

[req.body.email]

);

4.6 Autres Menaces

Menace Description Protection
DDoS Distributed Denial of Service - Surcharge du serveur avec des requêtes massives. Cloudflare, Rate Limiting, WAF, CDN.
Clickjacking L'attaquant trompe l'utilisateur en superposant des éléments invisibles. X-Frame-Options: DENY, CSP frame-ancestors.
Man-in-the-Middle Interception de la communication entre client et serveur. HTTPS, HSTS (HTTP Strict Transport Security).
Session Hijacking Vol du cookie de session pour usurper l'identité. HttpOnly, Secure, SameSite, régénération de session.
Brute Force Tentatives multiples de mots de passe. Rate Limiting, CAPTCHA, 2FA, délai entre tentatives.

⚡ 5. PERFORMANCE WEB

5.1 Core Web Vitals

Définition : Les Core Web Vitals sont un ensemble de métriques de performance définies par Google pour mesurer l'expérience utilisateur réelle. Elles sont utilisées comme signal de ranking SEO.

Métrique Nom Description Objectif
LCP Largest Contentful Paint Temps de chargement de l'élément le plus grand (image, vidéo, bloc de texte). < 2.5s
FID First Input Delay Délai avant que le navigateur réponde à la première interaction (clic, tap). < 100ms
CLS Cumulative Layout Shift Stabilité visuelle : mesure des déplacements d'éléments pendant le chargement. < 0.1

5.2 Optimisations des Images

<!-- Format WebP avec fallback -->

<picture>

<source srcset="image.webp" type="image/webp">

<source srcset="image.avif" type="image/avif">

<img src="image.jpg" alt="Description" loading="lazy" decoding="async">

</picture>

<!-- Lazy Loading natif -->

<img loading="lazy" src="image.jpg" alt="Description">

<!-- Image responsive avec srcset -->

<img src="image.jpg"

srcset="image-small.jpg 480w, image-medium.jpg 800w, image-large.jpg 1200w"

sizes="(max-width: 600px) 100vw, 50vw"

alt="Image responsive" loading="lazy">

5.3 Optimisations CSS

/* ✅ Bonnes pratiques CSS pour la performance */

/* 1. Minification (cssnano, clean-css) */

/* 2. Critical CSS (inline pour le premier rendu) */

/* 3. Éviter les sélecteurs complexes */

/* 4. Utiliser contain pour isoler les composants */

.card { contain: layout; }

/* 5. Utiliser will-change (avec parcimonie) */

.element { will-change: transform; }

/* 6. Éviter les recalculs de layout (reflows) */

/* ❌ Éviter : modification de width/height/top/left en boucle */

for (let i = 0; i < 100; i++) {

element.style.left = i + 'px'; // Force reflow

}

/* ✅ Préférer : transformations GPU-accélérées */

element.style.transform = `translateX(${i}px)`;

/* 7. Éviter les animations sur les propriétés qui causent des reflows */

/* ✅ Bonnes propriétés pour animations : transform, opacity */

.animated {

transition: transform 0.3s ease, opacity 0.3s ease;

}

5.4 Optimisations JavaScript

// ✅ Code Splitting (React)

const LazyComponent = React.lazy(() => import('./LazyComponent'));

// ✅ Tree Shaking (importer uniquement ce qui est utilisé)

import { map, filter } from 'lodash-es'; // ✅

// import _ from 'lodash-es'; // ❌ (importe tout)

// ✅ Debouncing (limiter les appels fréquents)

const debouncedSearch = debounce((query) => {

fetchSearch(query);

}, 300);

// ✅ Throttling (limiter le taux d'exécution)

const throttledScroll = throttle(() => {

handleScroll();

}, 100);

// ✅ Web Workers pour les calculs lourds

const worker = new Worker('heavy-worker.js');

// ✅ requestAnimationFrame pour les animations

function animate() {

// Mettre à jour l'animation

requestAnimationFrame(animate);

}

// ✅ Éviter les fuites de mémoire

// Nettoyer les event listeners, les timers, les observateurs

componentWillUnmount() {

clearInterval(this.timer);

this.element.removeEventListener('click', this.handler);

}

5.5 Cache & Mise en Cache

<!-- En-têtes de cache HTTP -->

Cache-Control: public, max-age=31536000, immutable

// Ressources statiques (images, fonts) - 1 an

Cache-Control: public, max-age=86400, stale-while-revalidate=604800

// Pages dynamiques - 1 jour, possibilité de servir du contenu périmé pendant 7 jours

Cache-Control: private, no-cache, no-store, must-revalidate

// Données sensibles - pas de cache

<!-- Service Worker (mise en cache côté client) -->

<script>

if ('serviceWorker' in navigator) {

navigator.serviceWorker.register('/sw.js')

.then(reg => console.log('Service Worker enregistré'))

.catch(err => console.error('Erreur SW:', err));

}

</script>

5.6 Outils de Performance

Outil Utilisation Métriques
Lighthouse Audit de performance (Chrome DevTools). Performance, Accessibilité, SEO, Best Practices.
WebPageTest Test de performance multi-localisations. LCP, FID, CLS, TTFB, First Contentful Paint.
Chrome DevTools Analyse en temps réel. Network, Performance, Memory, Coverage.
GTmetrix Analyse de performance. Core Web Vitals, Structure du site.

📊 6. RÉSUMÉ COMPLET

Composant Rôle Technologies Clés Bonnes Pratiques
HTML5 Structure et contenu. Balises sémantiques, Multimédia, APIs (Canvas, Web Storage). Accessibilité, SEO, validation des formulaires.
CSS3 Style et mise en page. Flexbox, Grid, Animations, Variables, Container Queries. Responsive Design, performance, bonnes pratiques de cascade.
JavaScript Comportement et interactivité. ES6+, Promises, Async/Await, Classes, DOM, Fetch. Code asynchrone, performance, gestion des événements.
Sécurité Protection des données et utilisateurs. HTTPS, CORS, XSS, CSRF, CSP, SQL Injection. Validation des entrées, échappement, HTTPS partout.
Performance Optimisation et rapidité. LCP, FID, CLS, Lazy Loading, Code Splitting, Cache. Images optimisées, code minifié, caching stratégique.