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

🏗️ 1. HTML5 (HyperText Markup Language)

1.1 Histoire & Évolution

Version Année Innovations Majeures
HTML 1.0 1991 Balises basiques (titres, paragraphes, liens)
HTML 2.0 1995 Standardisation des formulaires, tables simples
HTML 3.2 1997 Tables complexes, applets Java, scripts
HTML 4.01 1999 CSS, frames, support des scripts étendu
XHTML 1.0 2000 XML strict, syntaxe rigide
HTML5 2014 Sémantique, multimédia, API avancées

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 sur la direction du HTML. Il a fallu 8 ans (2006-2014) pour finaliser la spécification.

1.2 Structure Fondamentale

<!DOCTYPE html>

<html lang="fr">

<head>

<!-- Métadonnées : informations sur la page -->

<meta charset="UTF-8">

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

<title>Ma Page Web</title>

<!-- Liens vers des ressources externes -->

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

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

</head>

<body>

<!-- Contenu visible de la page -->

<header>

<h1>Bienvenue</h1>

</header>

<main>

<section>

<article>

<h2>Article 1</h2>

<p>Contenu de l'article...</p>

</article>

</section>

</main>

<footer>

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

</footer>

</body>

</html>

1.3 Balises Sémantiques (HTML5)

Les balises sémantiques donnent du sens au contenu, améliorant le SEO (Search Engine Optimization) et l'accessibilité.

Balise Rôle Exemple d'utilisation
<header> En-tête de page/section Logo, navigation, titre
<nav> Navigation principale Menu de liens
<main> Contenu principal Une seule par page
<section> Section thématique Chapitre, groupe de contenu
<article> Contenu indépendant Article de blog, produit
<aside> Contenu secondaire Sidebar, publicité
<footer> Pied de page Copyright, liens annexes
<figure> Illustration légendée Image avec légende
<figcaption> Légende de figure Description de l'image
<time> Date/heure Publication, événements
<details> Contenu dépliable FAQ, informations supplémentaires
<summary> Titre du détail En-tête du contenu dépliable

<article>

<header>

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

<p>Publié le <time datetime="2026-07-29">29 juillet 2026</time></p>

</header>

<section>

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

<p>HTML5 a introduit des balises qui donnent du sens...</p>

</section>

<aside>

<h3>À lire aussi</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="#">Technologie</a></p>

</footer>

</article>

1.4 Éléments Multimédia

Images

<!-- 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">

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

</figure>

<!-- Image responsive (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">

<!-- Image avec lazy loading -->

<img src="photo.jpg" alt="Photo" loading="lazy" decoding="async">

Détail méconnu : L'attribut srcset permet de charger différentes images selon la taille de l'écran, économisant la bande passante sur mobile.

Audio

<!-- Audio basique -->

<audio controls>

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

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

Votre navigateur ne supporte pas l'audio.

</audio>

<!-- Audio avec autoplay (déconseillé) -->

<audio controls autoplay loop muted>

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

</audio>

Détail méconnu : Les navigateurs bloquent l'autoplay sur les pages au chargement pour éviter les sons intempestifs.

Vidéo

<!-- Vidéo basique -->

<video controls width="640" height="360">

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

<video controls>

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

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

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

</video>

<!-- Vidéo avec poster (image d'aperçu) -->

<video controls poster="apercu.jpg">

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

</video>

Canvas (Dessin 2D/3D)

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

<script>

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

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

// Dessiner un rectangle

ctx.fillStyle = '#3498db';

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

// Dessiner un cercle

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

</script>

  • Graphiques, diagrammes (Chart.js)
  • Jeux en 2D (Phaser.js)
  • Édition d'images (Fabric.js)
  • Animations (Three.js pour 3D)

1.5 Formulaires & Inputs

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

<!-- Types de base -->

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

<input type="text" id="nom" name="nom" placeholder="Jean Dupont" required>

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

<input type="email" id="email" name="email" required>

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

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

<!-- Types modernes (HTML5) -->

<label for="telephone">Téléphone :</label>

<input type="tel" id="telephone" name="telephone" pattern="[0-9]{10}">

<label for="date">Date :</label>

<input type="date" id="date" name="date">

<label for="heure">Heure :</label>

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

<label for="couleur">Couleur :</label>

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

<label for="range">Volume :</label>

<input type="range" id="range" name="volume" min="0" max="100" step="1">

<!-- Select -->

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

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

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

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

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

</select>

<!-- Textarea -->

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

<textarea id="message" name="message" rows="5" cols="33" maxlength="500"></textarea>

<!-- Checkbox -->

<label>

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

S'inscrire à la newsletter

</label>

<!-- Radio -->

<fieldset>

<legend>Genre :</legend>

<label><input type="radio" name="genre" value="H"> Homme</label>

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

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

</fieldset>

<!-- File upload -->

<label for="fichier">Fichier :</label>

<input type="file" id="fichier" name="fichier" accept="image/*,.pdf">

<!-- Datasets -->

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

<datalist id="villes">

<option value="Paris">

<option value="Lyon">

<option value="Marseille">

</datalist>

<!-- Boutons -->

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

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

<button type="button">Bouton personnalisé</button>

</form>

Attributs avancés :

Attribut Rôle Exemple
required Champ obligatoire <input type="email" required>
pattern Validation regex pattern="[A-Za-z]{3,}"
min / max Valeurs minimales/maximales min="18" max="99"
step Incrément step="0.5"
placeholder Texte d'exemple placeholder="Entrez votre nom"
autocomplete Auto-complétion autocomplete="email"
autofocus Focus automatique autofocus
multiple Sélection multiple <input type="file" multiple>
accept Types de fichiers acceptés accept=".jpg,.png"
form Associer à un formulaire <input form="form2">

1.6 APIs HTML5 Avancées

Web Storage (LocalStorage & SessionStorage)

// 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');

  • Stockage max : ~5-10 MB par domaine.
  • Pas de structure de données complexes (tout en string).
  • Pas de sécurité (accessible en JS).

IndexedDB (Base de données NoSQL)

// Ouvrir une base de données

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

request.onupgradeneeded = (event) => {

const db = event.target.result;

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

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

};

};

  • Stockage illimité (gigaoctets).
  • Index et requêtes complexes.
  • Transactions ACID.

Web Workers (Multi-threading)

// main.js

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

worker.postMessage({ action: 'calcul', data: 1000000 });

worker.onmessage = (event) => {

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

};

worker.onerror = (error) => {

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

};

// worker.js

self.onmessage = (event) => {

const result = event.data.data * 2; // Simulation de calcul lourd

self.postMessage(result);

};

  • Calculs intensifs (crypto, algorithmes).
  • Traitement d'images.
  • Parsing de gros fichiers.

Service Workers (Hors-ligne & Notifications)

// Enregistrement

if ('serviceWorker' in navigator) {

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

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

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

}

// sw.js

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

event.waitUntil(

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

return cache.addAll([

'/',

'/style.css',

'/app.js',

'/offline.html'

]);

})

);

});

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

event.respondWith(

caches.match(event.request)

.then((response) => {

return response || fetch(event.request);

})

.catch(() => {

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

})

);

});

  • Mode hors-ligne.
  • Push notifications.
  • Mises à jour en arrière-plan.

WebSocket (Communication bidirectionnelle)

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

socket.onopen = () => {

console.log('Connexion établie');

socket.send('Hello Server!');

};

socket.onmessage = (event) => {

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

};

socket.onclose = () => {

console.log('Connexion fermée');

};

socket.onerror = (error) => {

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

};

  • Chat en temps réel.
  • Jeux multijoueurs.
  • Trading financier.
  • Notifications push.

WebRTC (Communication Audio/Vidéo)

// Obtenir la caméra et le microphone

navigator.mediaDevices.getUserMedia({ video: true, audio: true })

.then((stream) => {

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

videoElement.srcObject = stream;

})

.catch((error) => {

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

});

// Connexion Peer-to-Peer

const peerConnection = new RTCPeerConnection({

iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]

});

peerConnection.ontrack = (event) => {

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

remoteVideo.srcObject = event.streams[0];

};

// Créer une offre

peerConnection.createOffer()

.then(offer => peerConnection.setLocalDescription(offer));

  • Vidéoconférence (Zoom, Google Meet).
  • Partages d'écran.
  • Streaming en direct.
  • Applications de téléphonie VoIP.

Geolocation API

// Position unique

navigator.geolocation.getCurrentPosition(

(position) => {

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

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

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

},

(error) => {

console.error('Erreur géolocalisation :', error.message);

}

);

// Suivi continu

const watchId = navigator.geolocation.watchPosition(

(position) => {

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

},

(error) => console.error(error)

);

// Arrêter le suivi

navigator.geolocation.clearWatch(watchId);

Intersection Observer (Lazy Loading)

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

entries.forEach(entry => {

if (entry.isIntersecting) {

const img = entry.target;

img.src = img.dataset.src;

observer.unobserve(img);

}

});

});

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

observer.observe(img);

});

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

Fullscreen API

// Demander le plein écran

document.documentElement.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;

// Événements

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

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

});

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

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

});

Notification API

// Demander la permission

Notification.requestPermission()

.then(permission => {

if (permission === 'granted') {

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

}

});

// Envoyer une notification

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

new Notification('Nouveau message', {

body: 'Vous avez un nouveau message de Jean',

icon: '/icon.png',

tag: 'message-123',

requireInteraction: true,

actions: [

{ action: 'reply', title: 'Répondre' },

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

]

});

}

🎨 2. CSS3 (Cascading Style Sheets)

2.1 Histoire & Évolution

Version Année Innovations Majeures
CSS 1 1996 Style de base (couleurs, polices, marges)
CSS 2 1998 Positionnement, z-index, media types
CSS 2.1 2004 Corrections, standardisation
CSS3 2011+ Modules (animations, flexbox, grid, transitions)
CSS4 En développement Nouvelles fonctionnalités incrémentales

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

2.2 Sélecteurs CSS

Sélecteurs Basiques

/* Sélecteur de type */

p { color: blue; }

/* Sélecteur de classe */

.important { font-weight: bold; }

/* Sélecteur d'ID */

#header { background: #333; }

/* Sélecteur universel */

* { margin: 0; }

/* Sélecteur d'attribut */

input[type="text"] { border: 1px solid #ccc; }

/* Sélecteur descendant */

article p { color: red; }

/* Sélecteur enfant direct */

ul > li { list-style: none; }

/* Sélecteur adjacent */

h1 + p { margin-top: 0; }

/* Sélecteur de frère général */

h1 ~ p { color: gray; }

Sélecteurs Avancés (CSS3)

/* Sélecteur d'attribut avec valeur commençant par */

a[href^="https"] { color: green; }

/* Sélecteur d'attribut avec valeur finissant par */

a[href$=".pdf"] { color: red; }

/* Sélecteur d'attribut avec valeur contenant */

a[href*="google"] { background: yellow; }

/* Sélecteur de placeholder */

input::placeholder { color: #999; }

/* Sélecteur de premier élément */

p:first-child { font-weight: bold; }

/* Sélecteur de dernier élément */

p:last-child { color: blue; }

/* Sélecteur de nième enfant */

li:nth-child(2n+1) { background: #f0f0f0; }

/* Sélecteur de nième de type */

li:nth-of-type(3) { color: red; }

/* Sélecteur de premier de type */

p:first-of-type { font-weight: bold; }

/* Sélecteur de seul de type */

p:only-of-type { text-transform: uppercase; }

/* Sélecteur :not (négation) */

div:not(.excluded) { color: green; }

/* Sélecteur :is (simplification) */

:is(header, footer, nav) { background: #eee; }

/* Sélecteur :where (zéro spécificité) */

:where(header, footer) { color: blue; }

/* Sélecteur :has (parent) */

figure:has(img) { border: 1px solid #ccc; }

/* Sélecteur :focus-visible */

button:focus-visible { outline: 2px solid blue; }

Pseudo-classes de Formulaire

/* Input valide/invalide */

input:valid { border-color: green; }

input:invalid { border-color: red; }

/* Input requis/optionnel */

input:required { border-left: 3px solid red; }

input:optional { border-left: 3px solid blue; }

/* Input vérifié (checkbox) */

input:checked + label { font-weight: bold; }

/* Input désactivé/enabled */

input:disabled { opacity: 0.5; }

input:enabled { cursor: pointer; }

/* Input en focus */

input:focus { outline: 2px solid #3498db; }

/* Input dans une plage */

input:in-range { background: #e8f5e9; }

input:out-of-range { background: #ffebee; }

2.3 Propriétés CSS Essentielles

Box Model

/* Box Model complet */

.element {

/* Contenu */

width: 200px;

height: 100px;

/* Padding (intérieur) */

padding: 20px; /* 20px partout */

padding: 10px 20px; /* haut/bas, gauche/droite */

padding: 10px 20px 30px 40px; /* haut, droite, bas, gauche */

/* Border */

border: 2px solid #333;

border-radius: 8px; /* Coins arrondis */

/* Margin (extérieur) */

margin: 20px; /* 20px partout */

margin: 10px 20px; /* haut/bas, gauche/droite */

/* Box-sizing */

box-sizing: border-box; /* Inclut padding et border dans width/height */

/* ou content-box (par défaut) */

}

Box Model Visual

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

│ MARGIN (extérieur) │

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

│ │ BORDER │ │

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

│ │ │ PADDING │ │ │

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

│ │ │ │ CONTENT │ │ │ │

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

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

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

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

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

Display & Position

/* Display */

.display-examples {

/* Éléments de bloc */

display: block; /* Occupe toute la largeur */

display: inline; /* Sur la même ligne */

display: inline-block; /* Comme inline mais avec block (width, height) */

/* Flexbox */

display: flex;

display: inline-flex;

/* CSS Grid */

display: grid;

display: inline-grid;

/* Spéciaux */

display: none; /* Cache l'élément */

display: table; /* Comportement de tableau */

display: list-item; /* Comportement de liste */

display: contents; /* Seul le contenu compte */

}

/* Position */

.position-examples {

position: static; /* Par défaut, suit le flux normal */

position: relative; /* Se déplace par rapport à sa position normale */

position: absolute; /* Par rapport au parent positionné */

position: fixed; /* Par rapport à la fenêtre */

position: sticky; /* Collant (mix between relative/fixed) */

/* Déplacements (pour relative, absolute, fixed, sticky) */

top: 10px;

right: 20px;

bottom: 10px;

left: 20px;

/* Z-index (ordre de superposition) */

z-index: 10;

}

Flexbox (Flexible Box Layout)

/* Parent (conteneur flex) */

.flex-container {

display: flex;

/* ou inline-flex */

/* Direction */

flex-direction: row; /* Horizontal (par défaut) */

flex-direction: row-reverse; /* Horizontal inversé */

flex-direction: column; /* Vertical */

flex-direction: column-reverse; /* Vertical inversé */

/* Retour à la ligne */

flex-wrap: nowrap; /* Pas de retour (par défaut) */

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

flex-wrap: wrap-reverse; /* Retour inversé */

/* Alignement horizontal (main axis) */

justify-content: flex-start; /* Début (par défaut) */

justify-content: flex-end; /* Fin */

justify-content: center; /* Centré */

justify-content: space-between; /* Espace entre */

justify-content: space-around; /* Espace autour */

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

/* Alignement vertical (cross axis) */

align-items: stretch; /* Étiré (par défaut) */

align-items: flex-start; /* Début */

align-items: flex-end; /* Fin */

align-items: center; /* Centré */

align-items: baseline; /* Aligné sur la ligne de base */

/* Alignement multi-lignes */

align-content: stretch; /* Étiré (par défaut) */

align-content: flex-start; /* Début */

align-content: flex-end; /* Fin */

align-content: center; /* Centré */

align-content: space-between; /* Espace entre */

align-content: space-around; /* Espace autour */

/* Espacement */

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

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

}

/* Enfants (éléments flex) */

.flex-item {

/* Ordre */

order: 1; /* Changement d'ordre visuel */

/* Croissance */

flex-grow: 1; /* 0 = ne grandit pas (par défaut) */

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

/* Rétrécissement */

flex-shrink: 1; /* 1 = rétrécit (par défaut) */

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

/* Taille de base */

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

flex-basis: auto; /* Basé sur le contenu (par défaut) */

/* 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: auto; /* Hérite de align-items (par défaut) */

align-self: flex-start; /* Début */

align-self: flex-end; /* Fin */

align-self: center; /* Centré */

align-self: stretch; /* Étiré */

}

CSS Grid

/* Parent (conteneur grid) */

.grid-container {

display: grid;

/* ou inline-grid */

/* Colonnes et lignes */

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-rows: 100px 200px; /* 2 lignes fixes */

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

/* Espacement */

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

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

/* Alignement horizontal */

justify-items: stretch; /* Étiré (par défaut) */

justify-items: start; /* Début */

justify-items: end; /* Fin */

justify-items: center; /* Centré */

/* Alignement vertical */

align-items: stretch; /* Étiré (par défaut) */

align-items: start; /* Début */

align-items: end; /* Fin */

align-items: center; /* Centré */

/* Alignement du conteneur */

justify-content: start; /* Début (par défaut) */

justify-content: end; /* Fin */

justify-content: center; /* Centré */

justify-content: space-between; /* Espace entre */

justify-content: space-around; /* Espace autour */

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

align-content: start; /* Début (par défaut) */

align-content: end; /* Fin */

align-content: center; /* Centré */

align-content: space-between; /* Espace entre */

align-content: space-around; /* Espace autour */

/* Zones nommées */

grid-template-areas:

"header header header"

"sidebar main main"

"footer footer footer";

}

/* Enfants (éléments grid) */

.grid-item {

/* Placement sur les colonnes */

grid-column-start: 1;

grid-column-end: 3; /* De la colonne 1 à 3 */

grid-column: 1 / 3; /* Raccourci */

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

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

/* Placement sur les lignes */

grid-row-start: 1;

grid-row-end: 3; /* De la ligne 1 à 3 */

grid-row: 1 / 3; /* Raccourci */

/* 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: stretch; /* Étiré (par défaut) */

justify-self: start; /* Début */

justify-self: end; /* Fin */

justify-self: center; /* Centré */

align-self: stretch; /* Étiré (par défaut) */

align-self: start; /* Début */

align-self: end; /* Fin */

align-self: center; /* Centré */

}

2.4 Responsive Design

Media Queries

/* Types d'écrans */

@media screen { /* Écrans */ }

@media print { /* Impression */ }

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

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

/* Breakpoints */

@media (max-width: 768px) { /* Mobile */ }

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

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

/* Approche Mobile-First */

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

body { font-size: 16px; }

/* Tablette */

@media (min-width: 768px) {

body { font-size: 18px; }

}

/* Desktop */

@media (min-width: 1025px) {

body { font-size: 20px; }

}

/* 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és absolues (fixes) */

px, pt, pc, mm, cm, in

/* Unités relatives à la police */

em /* Relatif à la taille de police du parent */

rem /* Relatif à la taille de police racine (généralement 16px) */

ex /* Relatif à la hauteur de la lettre 'x' */

ch /* Relatif à la largeur du caractère '0' */

/* Unités relatives au viewport */

vw /* 1% de la largeur du viewport */

vh /* 1% de la hauteur du viewport */

vmin /* 1% de la plus petite dimension (min(vw, vh)) */

vmax /* 1% de la plus grande dimension (max(vw, vh)) */

/* Unités relatives au conteneur (CSS Container Queries) */

cqw /* 1% de la largeur du conteneur */

cqh /* 1% de la hauteur du conteneur */

cqi /* 1% de la taille inline du conteneur */

cqb /* 1% de la taille block du conteneur */

/* Pourcentage */

% /* Relatif au parent (width, height, etc.) */

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;

}

}

2.5 Animations & Transitions

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; /* Par défaut */

transition-timing-function: linear; /* Linéaire */

transition-timing-function: ease-in; /* Accélère */

transition-timing-function: ease-out; /* Décélère */

transition-timing-function: ease-in-out; /* Accélère puis décélère */

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

/* Délai */

transition-delay: 0.2s; /* Attendre 200ms */

/* Raccourci */

transition: all 0.3s ease 0.2s; /* propriété durée timing delay */

transition: width 0.5s ease-in-out, height 0.3s ease;

}

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-color: #3498db;

}

50% {

transform: scale(1.1);

background-color: #2980b9;

}

}

@keyframes multi-step {

0% { transform: translateX(0); }

20% { transform: translateX(100px); }

80% { transform: translateX(-50px); }

100% { transform: translateX(0); }

}

/* Utilisation de l'animation */

.element {

/* Nom de l'animation */

animation-name: slideIn;

/* Durée */

animation-duration: 2s; /* 2 secondes */

/* Timing function */

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

/* Délai */

animation-delay: 0.5s; /* 500ms d'attente */

/* Nombre d'itérations */

animation-iteration-count: 1; /* Une fois (par défaut) */

animation-iteration-count: infinite; /* Infini */

/* Direction */

animation-direction: normal; /* Normal (par défaut) */

animation-direction: reverse; /* Inversé */

animation-direction: alternate; /* Alterne */

/* Fill mode */

animation-fill-mode: none; /* Retour initial (par défaut) */

animation-fill-mode: forwards; /* Reste à l'état final */

animation-fill-mode: backwards; /* État initial avant le début */

animation-fill-mode: both; /* Forwards + Backwards */

/* Play state */

animation-play-state: running; /* En cours (par défaut) */

animation-play-state: paused; /* Pausé */

/* Raccourci */

animation: slideIn 2s ease-in-out 0.5s infinite alternate forwards;

}

2.6 CSS Avancé

Variables CSS (Custom Properties)

/* Déclaration */

:root {

/* Couleurs */

--color-primary: #3498db;

--color-secondary: #2ecc71;

--color-text: #2c3e50;

--color-background: #f8f9fa;

/* Polices */

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

--font-size-base: 16px;

/* Espacements */

--spacing-small: 0.5rem;

--spacing-medium: 1rem;

--spacing-large: 2rem;

/* Border Radius */

--border-radius-small: 4px;

--border-radius-medium: 8px;

--border-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-color: var(--color-primary);

color: white;

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

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

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

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

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

}

.button:hover {

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

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

}

Fonctions CSS

/* 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);

}

/* 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

/* Linear Gradients */

.gradient-linear {

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

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

background: linear-gradient(to bottom right, #3498db 0%, #2ecc71 50%, #e74c3c 100%);

}

/* Radial Gradients */

.gradient-radial {

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

background: radial-gradient(ellipse at center, #3498db, #2ecc71, #e74c3c);

background: radial-gradient(circle at top left, #3498db 30%, #2ecc71 70%);

}

/* Conic Gradients */

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

Box Shadows

/* Ombre simple */

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

/* Ombre multiple */

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

/* Ombre intérieure */

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

/* Ombre de texte */

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

2.7 Frameworks CSS

Tailwind CSS (Utility-First)

<!-- Approche Utility-First -->

<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">Card 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">Bouton</button>

</div>

</div>

</div>

  • Pas de CSS personnalisé.
  • Design cohérent.
  • Production rapide.
  • Bundle size maîtrisé (PurgeCSS).

CSS Modules

/* Button.module.css */

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

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

.button--primary { background: #2ecc71; }

.button--danger { background: #e74c3c; }

// Button.jsx

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

function Button({ variant, children }) {

const className = [

styles.button,

variant === 'primary' && styles['button--primary'],

variant === 'danger' && styles['button--danger']

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

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

}

💻 3. JAVASCRIPT (Écosystème)

3.1 JavaScript Moderne (ES6+)

Variables & Constantes

// let : Variable mutable, scope de bloc

let age = 30;

age = 31; // OK

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

user.name = 'Marie'; // OK

// user = { name: 'Marie' }; // Erreur !

// var : Ancien, scope de fonction (à éviter)

var oldStyle = 'à ne plus utiliser';

Arrow Functions

// Fonction classique

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

// Arrow function (avec retour implicite)

const add = (a, b) => a + b;

// Arrow function (un seul paramètre)

const double = x => x * 2;

// Utilisation avec les tableaux

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

const doubled = numbers.map(n => n * 2);

const evens = numbers.filter(n => n % 2 === 0);

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

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"

// Tagged templates

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.`;

Destructuring

// Objet

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

const { name, age, city } = user;

// Alias

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

// Valeurs par défaut

const { country = 'France' } = user;

// Nested

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

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

// Tableau

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

const [first, second, third] = colors;

// Paramètres de fonction

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

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

}

Spread & Rest Operators

// Spread (décomposition)

const arr1 = [1, 2, 3];

const arr2 = [4, 5, 6];

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

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

// Rest (regroupement)

function sum(...numbers) {

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

}

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

Classes

// Déclaration de classe

class User {

// Constructeur

constructor(name, age) {

this.name = name;

this.age = age;

this.createdAt = new Date();

}

// Méthode

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

// Getter

get isAdult() { return this.age >= 18; }

// Méthode statique

static createGuest() { return new User('Invité', 18); }

// Méthode privée (ES2022)

#validateEmail(email) { return email.includes('@'); }

}

// Héritage

class Admin extends User {

constructor(name, age, role) {

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

this.role = role;

}

// Override

greet() {

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

}

}

Promises

// 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);

});

// Chaînage

fetchUser(userId)

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

.then(orders => processOrders(orders))

.then(result => console.log(result))

.catch(error => console.error(error));

// Promise.all

Promise.all([

fetch('/api/users'),

fetch('/api/products')

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

Async/Await

// 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);

throw error;

}

}

3.2 DOM Manipulation

// Sélection d'éléments

const element = document.querySelector('.my-class');

const elements = document.querySelectorAll('div');

// Création d'éléments

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

div.textContent = 'Nouveau div';

div.className = 'my-class';

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

// Ajout au DOM

document.body.appendChild(div);

// Événements

element.addEventListener('click', (event) => { console.log('Clicked!', event); });

// Délégation d'événements

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

if (event.target.matches('li')) { console.log('Item clicked:', event.target.textContent); }

});

3.3 Fetch & HTTP

// GET

fetch('/api/users')

.then(response => { if (!response.ok) throw new Error('Network error'); return response.json(); })

.then(data => console.log(data))

.catch(error => console.error(error));

// POST

fetch('/api/users', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: 'Jean' }) })

.then(response => response.json())

.then(data => console.log(data));

🔒 4. SÉCURITÉ WEB

4.1 HTTPS (Chiffrement)

Pourquoi HTTPS est essentiel :

  • Chiffrement des données (confidentialité).
  • Intégrité des données (non-altération).
  • Authentification du serveur (certificat).

1. Client → Serveur : Hello (versions TLS supportées)

2. Serveur → Client : Certificat + Clé publique

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

4. Client → Serveur : Clé de session (chiffrée avec clé publique)

5. Communication chiffrée via la clé de session

4.2 CORS (Cross-Origin Resource Sharing)

Problème : Un site example.com ne peut pas faire de requêtes vers api.other.com pour des raisons de sécurité (Same-Origin Policy).

Solution : Le serveur doit renvoyer les en-têtes CORS appropriés.

// Serveur (Express)

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

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

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

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

next();

});

4.3 XSS (Cross-Site Scripting)

Problème : Injection de JavaScript malveillant.

Protections :

// Échappement HTML

function escapeHTML(str) {

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

div.textContent = str;

return div.innerHTML;

}

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

<meta http-equiv="Content-Security-Policy" content="default-src 'self'">

4.4 CSRF (Cross-Site Request Forgery)

Problème : Un site malveillant fait des requêtes vers un site où l'utilisateur est authentifié.

Protections :

<!-- Token CSRF dans les formulaires -->

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

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

<!-- ... -->

</form>

4.5 SQL Injection

Problème : Injection de code SQL via des entrées utilisateur.

Protections :

// ❌ À éviter

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

// ✅ Utiliser des paramètres préparés

const user = await prisma.user.findUnique({ where: { email: email } });

const result = await pool.query('SELECT * FROM users WHERE email = $1', [email]);

5. PERFORMANCE WEB

5.1 Core Web Vitals

Métrique Description Objectif
LCP Temps de chargement du contenu principal < 2.5s
FID Réactivité aux interactions < 100ms
CLS Stabilité visuelle < 0.1

5.2 Optimisations

Images

<!-- WebP (meilleure compression) -->

<picture>

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

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

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

</picture>

<!-- Lazy Loading -->

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

CSS

/* ✅ Bonnes pratiques */

/* - Minifier (cssnano, Clean CSS) */

/* - Critiques (Inline pour le premier render) */

.element { contain: layout; }

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

.element { will-change: transform; }

/* - Éviter les recalculs de layout */

/* Éviter : */

for (let i = 0; i < 100; i++) { element.style.left = i + 'px'; } // Force reflow

/* Préférer : */

element.style.transform = `translateX(${i}px)`; // Utilise le GPU

JavaScript

// ✅ Code Splitting (React)

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

// ✅ Tree Shaking (import only needed)

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

// import _ from 'lodash-es'; // ❌

// ✅ Debouncing

const debouncedSearch = debounce((query) => { fetchSearch(query); }, 300);

// ✅ Web Workers pour calculs lourds

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

Cache

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

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

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

<!-- Service Worker -->

<script>

if ('serviceWorker' in navigator) {

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

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

}

</script>

📊 RÉSUMÉ COMPLET

Composant Rôle Technologies Clés
HTML5 Structure Sémantique, Multimédia, Formulaires, APIs
CSS3 Style Flexbox, Grid, Animations, Variables, Container Queries
JavaScript Comportement ES6+, Promises, Async/Await, Classes, Fetch, DOM
Sécurité Protection HTTPS, CORS, XSS, CSRF, CSP, SQL Injection
Performance Optimisation LCP, FID, CLS, Lazy Loading, Code Splitting, Cache