Le grand final de la formation CSS ! 20 projets complets, du simple au complexe, avec code HTML de départ et solutions CSS détaillées. Chaque projet mobilise les compétences des chapitres précédents.
PROGRESSION DES PROJETS
════════════════════════
★★☆☆☆ DÉBUTANT ★★★☆☆ INTERMEDIAIRE ★★★★☆ AVANCÉ ★★★★★ EXPERT
─────────────── ────────────────── ───────────── ─────────────
1. Carte profil 5. Form inscription 8. Dashboard 15. Clone YouTube
2. Carte produit 6. Nav responsive 9. Landing page 16. Clone Netflix
3. Page recette 7. Menu hamburger 10. Portfolio 17. Clone GitHub
4. Form connexion 11. Blog responsive 18. Clone Facebook
12. Restaurant 19. Clone Stripe
13. E-commerce 20. Site complet
14. Admin panel (light/dark)
Progression de difficulté des 20 projets
| # | Projet | Difficulté | Techniques principales |
|---|---|---|---|
| 1 | Carte de profil | ★★☆☆☆ | Box model, border-radius, flexbox, ombres |
| 2 | Carte produit | ★★☆☆☆ | Grid, images, hover effects, badges |
| 3 | Page de recette | ★★☆☆☆ | Typography, listes, layout, timer |
| 4 | Formulaire connexion | ★★☆☆☆ | Formulaires, focus states, validation |
| 5 | Formulaire inscription | ★★★☆☆ | Multi-step, validation, animations |
| 6 | Nav responsive | ★★★☆☆ | Flexbox, media queries, sticky nav |
| 7 | Menu hamburger | ★★★☆☆ | Transform, transitions, overlay |
| 8 | Tableau de bord | ★★★★☆ | Grid, sidebar, cards, responsive |
| 9 | Landing page | ★★★★☆ | Hero, pricing, CTA, animations |
| 10 | Portfolio | ★★★☆☆ | Grid projects, about, contact |
| 11 | Blog responsive | ★★★☆☆ | Sidebar, post list, categories |
| 12 | Restaurant | ★★★★☆ | Hero, menu, gallery, reservations |
| 13 | E-commerce | ★★★★☆ | Product grid, filters, cart sidebar |
| 14 | Admin panel | ★★★★☆ | Full admin UI, all components |
| 15 | Clone YouTube | ★★★★★ | Video grid, sidebar, player |
| 16 | Clone Netflix | ★★★★★ | Carousels, dark theme, hero |
| 17 | Clone GitHub | ★★★★★ | Repo page, file tree, code view |
| 18 | Clone Facebook | ★★★★★ | News feed, stories, reactions |
| 19 | Clone Stripe | ★★★★★ | Gradients, modern landing, features |
| 20 | Site complet L/S | ★★★★★ | All features, light/dark mode |
Une carte de profil avec avatar, nom, bio et liens sociaux. Projet idéal pour maîtriser le box model, flexbox et les ombres.
<!-- HTML -->
<div class="profile-card">
<img class="avatar" src="avatar.jpg" alt="Photo de Marie Dupont">
<h2 class="name">Marie Dupont</h2>
<p class="role">Développeuse Web Frontend</p>
<p class="bio">Passionnée par le CSS et les interfaces accessibles.</p>
<div class="social-links">
<a href="#" aria-label="GitHub">GH</a>
<a href="#" aria-label="Twitter">TW</a>
<a href="#" aria-label="LinkedIn">LI</a>
</div>
</div>
<!-- CSS Solution -->
<style>
.profile-card {
max-width: 320px;
margin: 2rem auto;
padding: 2rem;
background: white;
border-radius: 16px;
box-shadow: 0 4px 24px rgba(0,0,0,0.1);
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
gap: 0.75rem;
}
.avatar {
width: 96px;
height: 96px;
border-radius: 50%;
object-fit: cover;
border: 3px solid #e2e8f0;
}
.name { font-size: 1.25rem; color: #1e293b; margin: 0; }
.role { font-size: 0.85rem; color: #2563eb; font-weight: 600; margin: 0; }
.bio { font-size: 0.9rem; color: #64748b; margin: 0; }
.social-links {
display: flex;
gap: 0.75rem;
margin-top: 0.5rem;
}
.social-links a {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background: #f1f5f9;
color: #475569;
text-decoration: none;
font-weight: 700;
font-size: 0.75rem;
transition: background 0.2s, color 0.2s;
}
.social-links a:hover {
background: #2563eb;
color: white;
}
</style>
Carte e-commerce avec image, titre, prix, note et bouton d'ajout au panier. Apprenez Grid, les images responsive et les effets hover.
<!-- HTML -->
<div class="product-card">
<div class="product-image">
<img src="produit.jpg" alt="Chaussures sport bleues">
<span class="badge-promo">-20%</span>
</div>
<div class="product-info">
<h3>Chaussures Sport Air</h3>
<div class="rating">★★★★☆ <span>(128)</span></div>
<div class="price">
<span class="current">89,99 €</span>
<span class="old">112,49 €</span>
</div>
<button class="add-to-cart">Ajouter au panier</button>
</div>
</div>
<!-- CSS Solution -->
<style>
.product-card {
max-width: 280px;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 2px 12px rgba(0,0,0,0.08);
background: white;
transition: transform 0.2s, box-shadow 0.2s;
}
.product-card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 24px rgba(0,0,0,0.12);
}
.product-image {
position: relative;
overflow: hidden;
aspect-ratio: 1;
}
.product-image img {
width: 100%;
height: 100%;
object-fit: cover;
}
.badge-promo {
position: absolute;
top: 12px;
left: 12px;
background: #dc2626;
color: white;
padding: 4px 10px;
border-radius: 9999px;
font-size: 0.75rem;
font-weight: 700;
}
.product-info { padding: 1.25rem; }
.product-info h3 { margin: 0 0 0.5rem; font-size: 1rem; }
.rating { font-size: 0.85rem; color: #f59e0b; margin-bottom: 0.5rem; }
.rating span { color: #94a3b8; }
.price { display: flex; gap: 0.5rem; align-items: baseline; margin-bottom: 1rem; }
.current { font-size: 1.25rem; font-weight: 700; color: #1e293b; }
.old { font-size: 0.85rem; color: #94a3b8; text-decoration: line-through; }
.add-to-cart {
width: 100%;
padding: 0.75rem;
background: #2563eb;
color: white;
border: none;
border-radius: 8px;
font-weight: 600;
cursor: pointer;
transition: background 0.2s;
}
.add-to-cart:hover { background: #1d4ed8; }
</style>
Page de recette avec hero, liste d'ingrédients, étapes de préparation et timer. Travaillez la typographie et les listes.
<!-- HTML -->
<article class="recipe">
<header class="recipe-hero">
<img src="recette.jpg" alt="Tarte aux pommes">
<div class="recipe-hero-content">
<h1>Tarte aux Pommes</h1>
<p class="meta">⏱ 45 min • 👤 6 personnes • ★★★★☆</p>
</div>
</header>
<div class="recipe-body">
<section class="ingredients">
<h2>Ingrédients</h2>
<ul>
<li>6 pommes Golden</li>
<li>250g de pâte feuilletée</li>
<li>80g de sucre</li>
<li>50g de beurre</li>
</ul>
</section>
<section class="steps">
<h2>Préparation</h2>
<ol>
<li>Éplucher et couper les pommes en quartiers.</li>
<li>Étaler la pâte dans un moule.</li>
<li>Disposer les pommes et parsemer de sucre.</li>
<li>Enfourner 30 min à 180°C.</li>
</ol>
</section>
</div>
</article>
<!-- CSS Solution -->
<style>
.recipe { max-width: 700px; margin: 2rem auto; }
.recipe-hero { position: relative; border-radius: 16px; overflow: hidden; margin-bottom: 2rem; }
.recipe-hero img { width: 100%; height: 300px; object-fit: cover; }
.recipe-hero-content {
position: absolute; bottom: 0; left: 0; right: 0;
padding: 2rem; background: linear-gradient(transparent, rgba(0,0,0,0.7)); color: white;
}
.recipe-hero-content h1 { margin: 0 0 0.5rem; font-size: 2rem; }
.meta { margin: 0; font-size: 0.9rem; opacity: 0.9; }
.recipe-body { display: grid; grid-template-columns: 1fr 1.5fr; gap: 2rem; }
@media (max-width: 600px) { .recipe-body { grid-template-columns: 1fr; } }
.ingredients, .steps { background: #f8fafc; padding: 1.5rem; border-radius: 12px; }
.ingredients ul, .steps ol { padding-left: 1.25rem; }
.ingredients li, .steps li { margin-bottom: 0.5rem; line-height: 1.5; }
h1, h2 { color: #1e293b; }
</style>
Formulaire de connexion élégant avec email, password, "remember me" et submit. Concentrez-vous sur les formulaires et les focus states.
<!-- HTML -->
<div class="login-wrapper">
<form class="login-form" onsubmit="return false">
<h1>Connexion</h1>
<p class="subtitle">Connectez-vous à votre compte</p>
<div class="form-group">
<label for="email">Email</label>
<input type="email" id="email" placeholder="vous@exemple.com" required>
</div>
<div class="form-group">
<label for="password">Mot de passe</label>
<input type="password" id="password" placeholder="••••••••" required>
</div>
<label class="checkbox-group">
<input type="checkbox"> Se souvenir de moi
</label>
<button type="submit" class="btn-login">Se connecter</button>
<p class="forgot"><a href="#">Mot de passe oublié ?</a></p>
</form>
</div>
<!-- CSS Solution -->
<style>
.login-wrapper {
min-height: 100vh;
display: grid;
place-items: center;
background: #f1f5f9;
}
.login-form {
background: white;
padding: 2.5rem;
border-radius: 16px;
box-shadow: 0 4px 24px rgba(0,0,0,0.08);
width: 100%;
max-width: 400px;
}
.login-form h1 { margin: 0 0 0.25rem; text-align: center; }
.subtitle { text-align: center; color: #64748b; margin-bottom: 1.5rem; }
.form-group { margin-bottom: 1rem; display: flex; flex-direction: column; gap: 0.25rem; }
.form-group label { font-weight: 600; font-size: 0.9rem; color: #374151; }
.form-group input {
padding: 0.75rem 1rem;
border: 2px solid #e2e8f0;
border-radius: 8px;
font-size: 1rem;
min-height: 44px;
transition: border-color 0.2s, box-shadow 0.2s;
}
.form-group input:focus {
outline: none;
border-color: #2563eb;
box-shadow: 0 0 0 3px rgba(37,99,235,0.15);
}
.checkbox-group {
display: flex; align-items: center; gap: 0.5rem;
margin-bottom: 1.25rem; font-size: 0.9rem; color: #475569; cursor: pointer;
}
.btn-login {
width: 100%;
padding: 0.75rem;
background: #2563eb;
color: white;
border: none;
border-radius: 8px;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
min-height: 44px;
transition: background 0.2s;
}
.btn-login:hover { background: #1d4ed8; }
.forgot { text-align: center; margin-top: 1rem; }
.forgot a { color: #2563eb; text-decoration: none; font-weight: 500; }
</style>
Formulaire multi-étapes avec nom, email, mot de passe, confirmation et acceptation des conditions. Intégrez les animations de transition.
<!-- HTML -->
<div class="register-wrapper">
<form class="register-form">
<div class="progress-bar"><div class="progress-fill"></div></div>
<h1>Créer un compte</h1>
<div class="form-row">
<div class="form-group">
<label for="first-name">Prénom</label>
<input type="text" id="first-name" placeholder="Marie" required>
</div>
<div class="form-group">
<label for="last-name">Nom</label>
<input type="text" id="last-name" placeholder="Dupont" required>
</div>
</div>
<div class="form-group">
<label for="reg-email">Email</label>
<input type="email" id="reg-email" placeholder="marie@exemple.com" required>
</div>
<div class="form-group">
<label for="reg-pwd">Mot de passe</label>
<input type="password" id="reg-pwd" placeholder="8 caractères min" required>
</div>
<div class="form-group">
<label for="reg-pwd2">Confirmer</label>
<input type="password" id="reg-pwd2" placeholder="Répétez le mot de passe" required>
</div>
<label class="checkbox-group">
<input type="checkbox" required> J'accepte les conditions d'utilisation
</label>
<button type="submit" class="btn-register">S'inscrire</button>
</form>
</div>
<!-- CSS Solution -->
<style>
.register-wrapper { min-height: 100vh; display: grid; place-items: center; background: #f1f5f9; }
.register-form {
background: white; padding: 2.5rem; border-radius: 16px;
box-shadow: 0 4px 24px rgba(0,0,0,0.08); width: 100%; max-width: 500px;
}
.progress-bar { height: 4px; background: #e2e8f0; border-radius: 2px; margin-bottom: 1.5rem; }
.progress-fill { height: 100%; width: 66%; background: linear-gradient(90deg, #2563eb, #7c3aed); border-radius: 2px; }
.register-form h1 { margin: 0 0 1.5rem; text-align: center; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
@media (max-width: 500px) { .form-row { grid-template-columns: 1fr; } }
.form-group { margin-bottom: 1rem; display: flex; flex-direction: column; gap: 0.25rem; }
.form-group label { font-weight: 600; font-size: 0.9rem; }
.form-group input {
padding: 0.75rem 1rem; border: 2px solid #e2e8f0; border-radius: 8px;
font-size: 1rem; min-height: 44px; transition: border-color 0.2s, box-shadow 0.2s;
}
.form-group input:focus { outline: none; border-color: #2563eb; box-shadow: 0 0 0 3px rgba(37,99,235,0.15); }
.checkbox-group { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 1.25rem; font-size: 0.9rem; }
.btn-register {
width: 100%; padding: 0.75rem; background: #2563eb; color: white; border: none;
border-radius: 8px; font-size: 1rem; font-weight: 600; cursor: pointer; min-height: 44px;
}
.btn-register:hover { background: #1d4ed8; }
</style>
Navigation avec logo, liens et hamburger sur mobile. Maîtrisez Flexbox, les media queries et le sticky positioning.
<!-- HTML -->
<nav class="navbar">
<a href="#" class="nav-logo">Logo</a>
<button class="hamburger" aria-label="Menu">
<span></span><span></span><span></span>
</button>
<ul class="nav-links">
<li><a href="#">Accueil</a></li>
<li><a href="#">Services</a></li>
<li><a href="#">Portfolio</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
<!-- CSS Solution -->
<style>
.navbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem 2rem;
background: white;
box-shadow: 0 2px 8px rgba(0,0,0,0.06);
position: sticky;
top: 0;
z-index: 100;
}
.nav-logo {
font-size: 1.5rem;
font-weight: 700;
color: #2563eb;
text-decoration: none;
}
.nav-links {
display: flex;
list-style: none;
gap: 2rem;
margin: 0;
padding: 0;
}
.nav-links a {
text-decoration: none;
color: #475569;
font-weight: 500;
transition: color 0.2s;
}
.nav-links a:hover { color: #2563eb; }
.hamburger { display: none; background: none; border: none; cursor: pointer; padding: 0.5rem; }
.hamburger span {
display: block; width: 24px; height: 2px; background: #1e293b;
margin: 5px 0; transition: all 0.3s;
}
@media (max-width: 768px) {
.hamburger { display: block; }
.nav-links {
position: fixed; top: 60px; right: -100%;
width: 250px; height: calc(100vh - 60px);
flex-direction: column; background: white; padding: 2rem;
box-shadow: -4px 0 12px rgba(0,0,0,0.1);
transition: right 0.3s ease;
}
.nav-links.active { right: 0; }
}
</style>
Menu hamburger animé en croix, slide-in latéral et overlay. Travaillez les transforms et transitions CSS.
<!-- HTML -->
<div class="hamburger-wrapper">
<button class="hamburger-btn" id="hamburger-btn">
<span class="bar"></span><span class="bar"></span><span class="bar"></span>
</button>
</div>
<div class="overlay" id="overlay"></div>
<aside class="sidebar-menu" id="sidebar">
<ul>
<li><a href="#">🏠 Accueil</a></li>
<li><a href="#">👤 Profil</a></li>
<li><a href="#">⚙️ Paramètres</a></li>
<li><a href="#">🚪 Déconnexion</a></li>
</ul>
</aside>
<!-- CSS Solution -->
<style>
.hamburger-btn {
position: fixed; top: 1rem; left: 1rem; z-index: 200;
background: white; border: none; width: 44px; height: 44px;
border-radius: 8px; cursor: pointer; padding: 10px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.bar { display: block; width: 100%; height: 2px; background: #1e293b; transition: all 0.3s; }
.hamburger-btn.active .bar:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.hamburger-btn.active .bar:nth-child(2) { opacity: 0; }
.hamburger-btn.active .bar:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
.overlay {
position: fixed; inset: 0; background: rgba(0,0,0,0.5);
z-index: 100; opacity: 0; visibility: hidden; transition: all 0.3s;
}
.overlay.active { opacity: 1; visibility: visible; }
.sidebar-menu {
position: fixed; top: 0; left: -280px; width: 280px; height: 100vh;
background: white; z-index: 150; padding: 4rem 2rem 2rem;
transition: left 0.3s ease; box-shadow: 4px 0 12px rgba(0,0,0,0.1);
}
.sidebar-menu.active { left: 0; }
.sidebar-menu ul { list-style: none; padding: 0; margin: 0; }
.sidebar-menu li { margin-bottom: 0.5rem; }
.sidebar-menu a {
display: block; padding: 0.75rem 1rem; border-radius: 8px;
text-decoration: none; color: #475569; font-weight: 500;
transition: background 0.2s;
}
.sidebar-menu a:hover { background: #f1f5f9; color: #2563eb; }
</style>
Dashboard avec sidebar, statistiques en haut, zone de graphiques et tableau de données. Un vrai layout CSS Grid complexe.
<!-- HTML -->
<div class="dashboard">
<aside class="dash-sidebar">
<div class="dash-logo">Dashboard</div>
<nav class="dash-nav">
<a href="#" class="dash-nav-item active">📊 Overview</a>
<a href="#" class="dash-nav-item">📈 Analytics</a>
<a href="#" class="dash-nav-item">👥 Users</a>
<a href="#" class="dash-nav-item">⚙️ Settings</a>
</nav>
</aside>
<main class="dash-main">
<header class="dash-header">
<h1>Overview</h1>
<span class="dash-date">Janvier 2026</span>
</header>
<div class="dash-stats">
<div class="stat-card"><div class="stat-value">12,345</div><div class="stat-label">Visiteurs</div></div>
<div class="stat-card"><div class="stat-value">3,456</div><div class="stat-label">Ventes</div></div>
<div class="stat-card"><div class="stat-value">89,2%</div><div class="stat-label">Taux</div></div>
<div class="stat-card"><div class="stat-value">€45,678</div><div class="stat-label">Revenus</div></div>
</div>
<div class="dash-content">
<div class="chart-area">Graphiques ici</div>
<div class="table-area">Tableau ici</div>
</div>
</main>
</div>
<!-- CSS Solution -->
<style>
.dashboard { display: grid; grid-template-columns: 240px 1fr; min-height: 100vh; }
.dash-sidebar {
background: #1e293b; color: white; padding: 1.5rem;
display: flex; flex-direction: column; gap: 1rem;
}
.dash-logo { font-size: 1.25rem; font-weight: 700; padding-bottom: 1rem; border-bottom: 1px solid #334155; }
.dash-nav { display: flex; flex-direction: column; gap: 0.25rem; }
.dash-nav-item {
padding: 0.6rem 1rem; border-radius: 8px; text-decoration: none;
color: #94a3b8; font-weight: 500; transition: all 0.2s;
}
.dash-nav-item:hover, .dash-nav-item.active { background: #334155; color: white; }
.dash-main { background: #f8fafc; padding: 2rem; overflow-y: auto; }
.dash-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem; }
.dash-header h1 { margin: 0; }
.dash-date { color: #64748b; }
.dash-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; margin-bottom: 1.5rem; }
.stat-card {
background: white; padding: 1.25rem; border-radius: 12px;
box-shadow: 0 1px 3px rgba(0,0,0,0.06);
}
.stat-value { font-size: 1.5rem; font-weight: 700; color: #1e293b; }
.stat-label { font-size: 0.85rem; color: #64748b; margin-top: 0.25rem; }
.dash-content { display: grid; grid-template-columns: 2fr 1fr; gap: 1rem; }
.chart-area, .table-area {
background: white; border-radius: 12px; padding: 1.5rem;
box-shadow: 0 1px 3px rgba(0,0,0,0.06); min-height: 200px;
}
@media (max-width: 1024px) {
.dashboard { grid-template-columns: 1fr; }
.dash-sidebar { display: none; }
.dash-stats { grid-template-columns: repeat(2, 1fr); }
.dash-content { grid-template-columns: 1fr; }
}
</style>
Landing page complète avec hero, features, pricing, CTA et footer. Mobilisez toutes les compétences de layout, typographie et animation.
<!-- HTML -->
<div class="landing">
<nav class="landing-nav">
<span class="logo">Startup</span>
<div class="nav-links">
<a href="#features">Fonctionnalités</a>
<a href="#pricing">Tarifs</a>
<a href="#" class="btn-nav">Commencer</a>
</div>
</nav>
<section class="hero">
<h1>Créez l'avenir du web</h1>
<p>La plateforme tout-en-un pour construire des applications modernes.</p>
<div class="hero-cta">
<a href="#" class="btn-primary">Essai gratuit</a>
<a href="#" class="btn-secondary">En savoir plus</a>
</div>
</section>
<section class="features" id="features">
<h2>Fonctionnalités</h2>
<div class="features-grid">
<div class="feature-card"><div class="feature-icon">⚡</div><h3>Rapide</h3><p>Performance optimale.</p></div>
<div class="feature-card"><div class="feature-icon">🔒</div><h3>Sécurisé</h3><p>Données protégées.</p></div>
<div class="feature-card"><div class="feature-icon">🎨</div><h3>Personnalisable</h3><p>Flexible et modulable.</p></div>
</div>
</section>
<section class="pricing" id="pricing">
<h2>Tarifs</h2>
<div class="pricing-grid">
<div class="price-card"><h3>Basic</h3><div class="price">9€/mois</div><a href="#">Choisir</a></div>
<div class="price-card featured"><h3>Pro</h3><div class="price">29€/mois</div><a href="#">Choisir</a></div>
<div class="price-card"><h3>Enterprise</h3><div class="price">99€/mois</div><a href="#">Choisir</a></div>
</div>
</section>
</div>
<!-- CSS Solution -->
<style>
.landing { font-family: system-ui, sans-serif; color: #1e293b; }
.landing-nav {
display: flex; justify-content: space-between; align-items: center;
padding: 1rem 2rem; background: white; position: sticky; top: 0; z-index: 100;
}
.logo { font-weight: 700; font-size: 1.25rem; color: #2563eb; }
.nav-links { display: flex; align-items: center; gap: 1.5rem; }
.nav-links a { text-decoration: none; color: #475569; font-weight: 500; }
.btn-nav { background: #2563eb; color: white !important; padding: 0.5rem 1rem; border-radius: 8px; }
.hero {
text-align: center; padding: 6rem 2rem;
background: linear-gradient(135deg, #eff6ff, #f0f9ff);
}
.hero h1 { font-size: clamp(2rem, 5vw, 3.5rem); margin-bottom: 1rem; }
.hero p { font-size: 1.2rem; color: #64748b; margin-bottom: 2rem; max-width: 600px; margin-inline: auto; }
.hero-cta { display: flex; gap: 1rem; justify-content: center; }
.btn-primary { background: #2563eb; color: white; padding: 0.75rem 2rem; border-radius: 8px; text-decoration: none; font-weight: 600; }
.btn-secondary { border: 2px solid #e2e8f0; color: #475569; padding: 0.75rem 2rem; border-radius: 8px; text-decoration: none; font-weight: 600; }
section { padding: 4rem 2rem; text-align: center; }
section h2 { font-size: 2rem; margin-bottom: 2rem; }
.features-grid, .pricing-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1.5rem; max-width: 1000px; margin: 0 auto; }
.feature-card { background: white; padding: 2rem; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.06); }
.feature-icon { font-size: 2rem; margin-bottom: 1rem; }
.price-card { background: white; padding: 2rem; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.06); }
.price-card.featured { border: 2px solid #2563eb; transform: scale(1.05); }
.price { font-size: 2rem; font-weight: 700; margin: 1rem 0; }
.price-card a { display: block; padding: 0.75rem; background: #2563eb; color: white; border-radius: 8px; text-decoration: none; font-weight: 600; margin-top: 1rem; }
</style>
Portfolio avec header, grille de projets, section à propos et formulaire de contact.
<!-- CSS Solution -->
<style>
.portfolio { font-family: system-ui, sans-serif; }
.port-header { display: flex; justify-content: space-between; align-items: center; padding: 1.5rem 2rem; position: sticky; top: 0; background: white; z-index: 100; }
.port-hero { text-align: center; padding: 5rem 2rem; background: linear-gradient(135deg, #eff6ff, #f0f9ff); }
.port-hero h1 { font-size: clamp(2rem, 5vw, 3rem); margin-bottom: 0.5rem; }
.port-hero p { color: #64748b; font-size: 1.1rem; }
.port-section { padding: 4rem 2rem; max-width: 1000px; margin: 0 auto; }
.port-section h2 { text-align: center; margin-bottom: 2rem; }
.projects-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1.5rem; }
.project-item {
border-radius: 12px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,0.08);
transition: transform 0.2s, box-shadow 0.2s; background: white;
}
.project-item:hover { transform: translateY(-4px); box-shadow: 0 8px 24px rgba(0,0,0,0.12); }
.project-item img { width: 100%; aspect-ratio: 16/9; object-fit: cover; }
.project-item-info { padding: 1rem; }
.project-item-info h3 { margin: 0 0 0.25rem; font-size: 1rem; }
.project-item-info p { margin: 0; font-size: 0.85rem; color: #64748b; }
.about-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; align-items: center; }
@media (max-width: 600px) { .about-grid { grid-template-columns: 1fr; } }
</style>
Blog avec liste d'articles, sidebar, catégories et recherche. Layout classique blog avec responsive.
<!-- CSS Solution -->
<style>
.blog { font-family: system-ui, sans-serif; max-width: 1100px; margin: 0 auto; padding: 2rem; }
.blog-layout { display: grid; grid-template-columns: 1fr 300px; gap: 2rem; }
@media (max-width: 768px) { .blog-layout { grid-template-columns: 1fr; } }
.post-card { display: flex; gap: 1.5rem; padding: 1.5rem; background: white; border-radius: 12px; box-shadow: 0 1px 3px rgba(0,0,0,0.06); margin-bottom: 1rem; }
@media (max-width: 600px) { .post-card { flex-direction: column; } }
.post-card img { width: 200px; height: 140px; object-fit: cover; border-radius: 8px; flex-shrink: 0; }
@media (max-width: 600px) { .post-card img { width: 100%; height: auto; aspect-ratio: 16/9; } }
.post-meta { font-size: 0.8rem; color: #64748b; margin-bottom: 0.25rem; }
.post-card h2 { margin: 0 0 0.5rem; font-size: 1.2rem; }
.post-card p { margin: 0; color: #475569; font-size: 0.9rem; }
.sidebar { display: flex; flex-direction: column; gap: 1.5rem; }
.sidebar-widget { background: white; border-radius: 12px; padding: 1.25rem; box-shadow: 0 1px 3px rgba(0,0,0,0.06); }
.sidebar-widget h3 { margin: 0 0 1rem; font-size: 1rem; }
.search-input { width: 100%; padding: 0.5rem 0.75rem; border: 2px solid #e2e8f0; border-radius: 6px; font-size: 0.9rem; }
.category-list { list-style: none; padding: 0; margin: 0; }
.category-list li { padding: 0.5rem 0; border-bottom: 1px solid #f1f5f9; font-size: 0.9rem; }
</style>
Site complet de restaurant avec hero, menu, galerie, réservations et footer. Design élégant et responsive.
<!-- CSS Solution -->
<style>
.restaurant { font-family: Georgia, 'Times New Roman', serif; }
.rest-hero {
height: 80vh; background: linear-gradient(rgba(0,0,0,0.5), rgba(0,0,0,0.5)),
url('restaurant-hero.jpg') center/cover; display: grid; place-items: center;
text-align: center; color: white;
}
.rest-hero h1 { font-size: clamp(2rem, 5vw, 3.5rem); margin-bottom: 0.5rem; }
.rest-hero p { font-size: 1.2rem; opacity: 0.9; margin-bottom: 1.5rem; }
.btn-reserve {
display: inline-block; padding: 0.75rem 2rem; border: 2px solid white;
color: white; text-decoration: none; font-weight: 600; letter-spacing: 0.1em;
transition: all 0.3s; font-family: system-ui, sans-serif;
}
.btn-reserve:hover { background: white; color: #1e293b; }
.rest-section { padding: 4rem 2rem; text-align: center; }
.rest-section h2 { font-size: 2rem; margin-bottom: 0.5rem; }
.rest-section .subtitle { color: #64748b; margin-bottom: 2rem; }
.menu-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1.5rem; max-width: 900px; margin: 0 auto; text-align: left; }
.menu-item { display: flex; justify-content: space-between; padding-bottom: 0.75rem; border-bottom: 1px dotted #e2e8f0; }
.menu-item-name { font-weight: 600; }
.menu-item-price { color: #2563eb; font-weight: 700; }
.gallery-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.5rem; max-width: 900px; margin: 0 auto; }
.gallery-grid img { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 8px; transition: transform 0.3s; cursor: pointer; }
.gallery-grid img:hover { transform: scale(1.05); }
@media (max-width: 600px) { .gallery-grid { grid-template-columns: repeat(2, 1fr); } }
</style>
Boutique avec grille de produits, filtres latéraux et panier. Layout complexe avec CSS Grid et composants dynamiques.
<!-- CSS Solution -->
<style>
.shop-layout { display: grid; grid-template-columns: 250px 1fr; gap: 2rem; padding: 2rem; max-width: 1200px; margin: 0 auto; }
@media (max-width: 768px) { .shop-layout { grid-template-columns: 1fr; } }
.filter-sidebar { display: flex; flex-direction: column; gap: 1.5rem; }
.filter-group h3 { font-size: 0.9rem; margin-bottom: 0.75rem; }
.filter-group label { display: flex; align-items: center; gap: 0.5rem; font-size: 0.9rem; margin-bottom: 0.35rem; cursor: pointer; }
.filter-group input[type="range"] { width: 100%; }
.products-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 1rem; }
.product-card { background: white; border-radius: 12px; overflow: hidden; box-shadow: 0 1px 3px rgba(0,0,0,0.06); transition: transform 0.2s; }
.product-card:hover { transform: translateY(-2px); }
.product-card img { width: 100%; aspect-ratio: 1; object-fit: cover; }
.product-card-info { padding: 1rem; }
.product-card-info h4 { margin: 0 0 0.25rem; font-size: 0.95rem; }
.product-card-info .price { font-weight: 700; color: #2563eb; }
.product-card-info .add-btn {
display: block; width: 100%; margin-top: 0.75rem; padding: 0.5rem;
background: #2563eb; color: white; border: none; border-radius: 6px;
font-weight: 600; cursor: pointer; transition: background 0.2s;
}
.product-card-info .add-btn:hover { background: #1d4ed8; }
</style>
Admin panel complet avec sidebar, topbar, stats, chartes, tableaux, formulaires et notifications. Le projet admin ultime.
<!-- CSS Solution -->
<style>
.admin { display: grid; grid-template-columns: 260px 1fr; min-height: 100vh; }
.admin-sidebar {
background: #0f172a; color: white; padding: 1.5rem;
display: flex; flex-direction: column; gap: 0.5rem;
}
.admin-logo { font-size: 1.25rem; font-weight: 700; padding-bottom: 1.5rem; border-bottom: 1px solid #1e293b; margin-bottom: 1rem; }
.admin-nav-item {
display: flex; align-items: center; gap: 0.75rem;
padding: 0.6rem 1rem; border-radius: 8px; text-decoration: none;
color: #94a3b8; font-size: 0.9rem; transition: all 0.15s;
}
.admin-nav-item:hover, .admin-nav-item.active { background: #1e293b; color: white; }
.admin-main { background: #f8fafc; }
.admin-topbar {
display: flex; justify-content: space-between; align-items: center;
padding: 1rem 2rem; background: white; border-bottom: 1px solid #e2e8f0;
}
.admin-content { padding: 2rem; }
.admin-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; margin-bottom: 2rem; }
.admin-stat {
background: white; padding: 1.25rem; border-radius: 12px;
box-shadow: 0 1px 3px rgba(0,0,0,0.04);
}
.admin-stat h4 { margin: 0; font-size: 0.8rem; color: #64748b; text-transform: uppercase; }
.admin-stat .value { font-size: 1.5rem; font-weight: 700; color: #1e293b; margin-top: 0.25rem; }
.admin-table {
width: 100%; border-collapse: collapse; background: white;
border-radius: 12px; overflow: hidden; box-shadow: 0 1px 3px rgba(0,0,0,0.04);
}
.admin-table th { background: #f8fafc; padding: 0.75rem 1rem; text-align: left; font-size: 0.8rem; text-transform: uppercase; color: #64748b; }
.admin-table td { padding: 0.75rem 1rem; border-top: 1px solid #f1f5f9; font-size: 0.9rem; }
@media (max-width: 1024px) {
.admin { grid-template-columns: 1fr; }
.admin-sidebar { display: none; }
.admin-stats { grid-template-columns: repeat(2, 1fr); }
}
</style>
Grille de vidéos, sidebar de catégories et page de lecture vidéo. Reproduisez le layout complexe de YouTube.
<!-- CSS Solution -->
<style>
.yt-header { display: flex; align-items: center; justify-content: space-between; padding: 0.75rem 1.5rem; background: white; position: sticky; top: 0; z-index: 100; }
.yt-header h2 { color: #ff0000; font-size: 1.25rem; }
.yt-search { flex: 1; max-width: 600px; margin: 0 2rem; display: flex; }
.yt-search input { flex: 1; padding: 0.5rem 1rem; border: 1px solid #ccc; border-radius: 20px 0 0 20px; font-size: 0.95rem; }
.yt-search button { padding: 0.5rem 1.25rem; background: #f8f8f8; border: 1px solid #ccc; border-left: none; border-radius: 0 20px 20px 0; cursor: pointer; }
.yt-layout { display: grid; grid-template-columns: 1fr; padding: 1rem 1.5rem; gap: 1rem; }
.yt-video-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 1rem; }
.yt-thumb { border-radius: 12px; overflow: hidden; cursor: pointer; }
.yt-thumb img { width: 100%; aspect-ratio: 16/9; object-fit: cover; }
.yt-thumb-info { display: flex; gap: 0.75rem; padding: 0.75rem 0; }
.yt-thumb-avatar { width: 36px; height: 36px; border-radius: 50%; background: #e2e8f0; flex-shrink: 0; }
.yt-thumb-text h3 { font-size: 0.9rem; margin: 0 0 0.25rem; line-height: 1.3; }
.yt-thumb-text p { margin: 0; font-size: 0.8rem; color: #64748b; }
@media (max-width: 600px) {
.yt-video-grid { grid-template-columns: 1fr; }
.yt-search { display: none; }
}
</style>
Bannière hero, carousels de contenus, thème sombre et navigation. Maîtrisez le dark mode et les overflow scroll.
<!-- CSS Solution -->
<style>
.netflix { background: #141414; color: white; font-family: system-ui, sans-serif; min-height: 100vh; }
.nf-header { display: flex; align-items: center; padding: 1rem 3rem; position: sticky; top: 0; z-index: 100; background: linear-gradient(transparent, #141414); }
.nf-logo { color: #e50914; font-size: 1.75rem; font-weight: 900; letter-spacing: -1px; }
.nf-nav { display: flex; gap: 1.5rem; margin-left: 2rem; }
.nf-nav a { color: #e5e5e5; text-decoration: none; font-size: 0.9rem; }
.nf-nav a:hover { color: #b3b3b3; }
.nf-hero {
height: 75vh; display: flex; flex-direction: column; justify-content: flex-end;
padding: 0 3rem 4rem; background: linear-gradient(transparent 40%, #141414),
linear-gradient(90deg, #141414 30%, transparent 70%), url('hero-bg.jpg') center/cover;
}
.nf-hero h1 { font-size: clamp(2rem, 5vw, 3.5rem); margin-bottom: 0.5rem; }
.nf-hero p { color: #e5e5e5; font-size: 1.1rem; max-width: 500px; margin-bottom: 1.5rem; }
.nf-btn-group { display: flex; gap: 0.75rem; }
.nf-btn { padding: 0.6rem 1.5rem; border: none; border-radius: 4px; font-weight: 600; cursor: pointer; font-size: 1rem; }
.nf-btn-play { background: white; color: #141414; }
.nf-btn-info { background: rgba(109,109,110,0.7); color: white; }
.nf-section { padding: 0 3rem 2rem; }
.nf-section h2 { font-size: 1.25rem; margin-bottom: 1rem; }
.nf-carousel { display: flex; gap: 0.5rem; overflow-x: auto; scroll-snap-type: x mandatory; padding-bottom: 1rem; }
.nf-carousel::-webkit-scrollbar { display: none; }
.nf-card { flex: 0 0 auto; width: 200px; scroll-snap-align: start; border-radius: 4px; overflow: hidden; cursor: pointer; transition: transform 0.3s; }
.nf-card:hover { transform: scale(1.08); z-index: 1; }
.nf-card img { width: 100%; aspect-ratio: 16/9; object-fit: cover; }
@media (max-width: 768px) {
.nf-header { padding: 1rem; }
.nf-hero { padding: 0 1.5rem 2rem; }
.nf-section { padding: 0 1.5rem 1rem; }
.nf-card { width: 140px; }
}
</style>
Page de dépôt avec arborescence de fichiers, vue de code, onglets et statistiques. Layout technique complexe.
<!-- CSS Solution -->
<style>
.gh-page { font-family: system-ui, sans-serif; background: #f6f8fa; color: #1f2328; padding: 2rem; max-width: 1200px; margin: 0 auto; }
.gh-repo-header { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 1.5rem; }
.gh-repo-header h1 { font-size: 1.5rem; margin: 0; }
.gh-repo-header .visibility { background: #e2e8f0; padding: 0.15rem 0.5rem; border-radius: 9999px; font-size: 0.75rem; font-weight: 600; }
.gh-tabs { display: flex; gap: 0; border-bottom: 1px solid #d0d7de; margin-bottom: 1.5rem; }
.gh-tab {
padding: 0.5rem 1rem; text-decoration: none; color: #656d76; font-weight: 500;
font-size: 0.9rem; border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.gh-tab:hover { color: #1f2328; }
.gh-tab.active { color: #1f2328; border-bottom-color: #fd8c73; }
.gh-file-list { border: 1px solid #d0d7de; border-radius: 6px; overflow: hidden; background: white; }
.gh-file-row {
display: flex; align-items: center; gap: 0.75rem; padding: 0.5rem 1rem;
border-bottom: 1px solid #eaeef2; font-size: 0.9rem;
}
.gh-file-row:last-child { border-bottom: none; }
.gh-file-row:hover { background: #f6f8fa; }
.gh-file-icon { width: 16px; text-align: center; color: #656d76; }
.gh-file-name { color: #1f2328; text-decoration: none; font-weight: 500; }
.gh-file-name:hover { text-decoration: underline; color: #0969da; }
.gh-file-msg { color: #656d76; font-size: 0.85rem; margin-left: auto; }
.gh-file-date { color: #656d76; font-size: 0.85rem; white-space: nowrap; }
.gh-code-block {
background: #161b22; color: #e6edf3; padding: 1rem; border-radius: 6px;
font-family: 'Cascadia Code', monospace; font-size: 0.85rem; overflow-x: auto;
margin-top: 1rem; line-height: 1.5;
}
</style>
News feed, stories, sidebar et publications. Reproduisez le layout à 3 colonnes de Facebook avec les réactions.
<!-- CSS Solution -->
<style>
.fb-page { font-family: system-ui, -apple-system, sans-serif; background: #f0f2f5; min-height: 100vh; }
.fb-header { background: white; padding: 0 1rem; box-shadow: 0 2px 4px rgba(0,0,0,0.1); position: sticky; top: 0; z-index: 100; display: flex; align-items: center; justify-content: space-between; height: 56px; }
.fb-logo { color: #1877f2; font-size: 1.75rem; font-weight: 700; }
.fb-search { padding: 0.5rem 1rem; border: none; border-radius: 20px; background: #f0f2f5; width: 240px; font-size: 0.9rem; }
.fb-layout { display: grid; grid-template-columns: 280px 1fr 280px; gap: 1.5rem; padding: 1.5rem; max-width: 1200px; margin: 0 auto; }
@media (max-width: 1024px) { .fb-layout { grid-template-columns: 1fr; } .fb-left, .fb-right { display: none; } }
.fb-stories { display: flex; gap: 0.5rem; overflow-x: auto; padding: 1rem; background: white; border-radius: 8px; margin-bottom: 1rem; }
.fb-story { width: 112px; height: 200px; border-radius: 12px; background: linear-gradient(135deg, #667eea, #764ba2); flex-shrink: 0; position: relative; overflow: hidden; cursor: pointer; }
.fb-story img { width: 100%; height: 100%; object-fit: cover; }
.fb-post { background: white; border-radius: 8px; box-shadow: 0 1px 2px rgba(0,0,0,0.1); margin-bottom: 1rem; padding: 1rem; }
.fb-post-header { display: flex; gap: 0.75rem; margin-bottom: 0.75rem; }
.fb-post-avatar { width: 40px; height: 40px; border-radius: 50%; background: #e4e6eb; }
.fb-post-name { font-weight: 600; font-size: 0.9rem; }
.fb-post-time { font-size: 0.8rem; color: #65676b; }
.fb-post-content { margin-bottom: 0.75rem; line-height: 1.4; }
.fb-post-image { width: 100%; border-radius: 8px; margin-bottom: 0.75rem; }
.fb-post-actions { display: flex; border-top: 1px solid #e4e6eb; padding-top: 0.5rem; }
.fb-post-action {
flex: 1; text-align: center; padding: 0.5rem; border-radius: 4px; cursor: pointer;
font-size: 0.85rem; font-weight: 600; color: #65676b; border: none; background: none;
}
.fb-post-action:hover { background: #f0f2f5; }
.fb-left, .fb-right { position: sticky; top: 72px; align-self: start; }
.fb-left nav a { display: flex; align-items: center; gap: 0.75rem; padding: 0.5rem; border-radius: 8px; text-decoration: none; color: #050505; font-weight: 500; font-size: 0.9rem; }
.fb-left nav a:hover { background: #e4e6eb; }
</style>
Landing page moderne avec gradient hero, animations, features section et design system. Le nec plus ultra du CSS moderne.
<!-- CSS Solution -->
<style>
.stripe-page {
font-family: system-ui, -apple-system, sans-serif; color: #0a2540;
background: white;
}
.stripe-hero {
background: linear-gradient(135deg, #635bff 0%, #7c3aed 50%, #a855f7 100%);
color: white; padding: 6rem 3rem; text-align: center; position: relative; overflow: hidden;
}
.stripe-hero::before {
content: ''; position: absolute; top: -50%; right: -20%; width: 600px; height: 600px;
background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 70%); border-radius: 50%;
}
.stripe-hero h1 {
font-size: clamp(2.5rem, 6vw, 4rem); margin-bottom: 1rem; position: relative;
line-height: 1.1;
}
.stripe-hero p { font-size: 1.25rem; opacity: 0.9; max-width: 600px; margin: 0 auto 2rem; position: relative; }
.stripe-hero-btns { display: flex; gap: 1rem; justify-content: center; position: relative; }
.stripe-btn-primary {
padding: 0.75rem 2rem; background: white; color: #0a2540; border: none;
border-radius: 8px; font-weight: 600; font-size: 1rem; cursor: pointer;
transition: transform 0.2s, box-shadow 0.2s;
}
.stripe-btn-primary:hover { transform: translateY(-2px); box-shadow: 0 8px 24px rgba(0,0,0,0.2); }
.stripe-btn-secondary {
padding: 0.75rem 2rem; border: 2px solid rgba(255,255,255,0.4); color: white;
background: transparent; border-radius: 8px; font-weight: 600; font-size: 1rem; cursor: pointer;
}
.stripe-section { padding: 5rem 3rem; text-align: center; }
.stripe-section h2 { font-size: 2.5rem; margin-bottom: 1rem; }
.stripe-section .subtitle { font-size: 1.2rem; color: #425466; max-width: 600px; margin: 0 auto 3rem; }
.stripe-features { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2rem; max-width: 1100px; margin: 0 auto; }
.stripe-feature { text-align: center; padding: 2rem; }
.stripe-feature-icon {
width: 64px; height: 64px; margin: 0 auto 1.5rem; border-radius: 16px;
background: linear-gradient(135deg, #635bff22, #7c3aed22); display: grid; place-items: center;
font-size: 1.5rem;
}
.stripe-feature h3 { font-size: 1.2rem; margin-bottom: 0.5rem; }
.stripe-feature p { color: #425466; font-size: 0.95rem; }
.stripe-cta {
background: linear-gradient(135deg, #0a2540, #1a365d); color: white;
padding: 5rem 3rem; text-align: center;
}
.stripe-cta h2 { font-size: 2.5rem; margin-bottom: 1rem; }
.stripe-cta p { font-size: 1.1rem; opacity: 0.8; margin-bottom: 2rem; }
@media (max-width: 768px) {
.stripe-hero { padding: 4rem 1.5rem; }
.stripe-section { padding: 3rem 1.5rem; }
.stripe-features { grid-template-columns: 1fr; }
.stripe-hero-btns { flex-direction: column; align-items: center; }
}
</style>
Le projet ultime ! Un site complet avec nav, hero, features, galerie, formulaire, footer — et un toggle clair/sombre fonctionnel. Toutes les compétences réunies.
<!-- HTML -->
<body data-theme="light">
<nav class="site-nav">
<a href="#" class="site-logo">MonSite</a>
<div class="site-nav-links">
<a href="#features">Fonctionnalités</a>
<a href="#gallery">Galerie</a>
<a href="#contact">Contact</a>
<button class="theme-toggle" onclick="toggleTheme()" aria-label="Changer de thème">☀️</button>
</div>
</nav>
<!-- ... sections ... -->
</body>
<!-- CSS Solution Complet -->
<style>
/* === DESIGN TOKENS === */
:root, [data-theme="light"] {
--bg: #ffffff;
--bg-secondary: #f8fafc;
--text: #0f172a;
--text-secondary: #475569;
--border: #e2e8f0;
--primary: #2563eb;
--primary-hover: #1d4ed8;
--card-bg: #ffffff;
--shadow: 0 1px 3px rgba(0,0,0,0.08);
--shadow-lg: 0 8px 24px rgba(0,0,0,0.1);
--code-bg: #f1f5f9;
}
[data-theme="dark"] {
--bg: #0f172a;
--bg-secondary: #1e293b;
--text: #f1f5f9;
--text-secondary: #94a3b8;
--border: #334155;
--primary: #60a5fa;
--primary-hover: #93bbfd;
--card-bg: #1e293b;
--shadow: 0 1px 3px rgba(0,0,0,0.3);
--shadow-lg: 0 8px 24px rgba(0,0,0,0.4);
--code-bg: #1e293b;
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
--bg: #0f172a; --bg-secondary: #1e293b; --text: #f1f5f9;
--text-secondary: #94a3b8; --border: #334155; --primary: #60a5fa;
--primary-hover: #93bbfd; --card-bg: #1e293b;
--shadow: 0 1px 3px rgba(0,0,0,0.3); --shadow-lg: 0 8px 24px rgba(0,0,0,0.4);
--code-bg: #1e293b;
}
}
/* === BASE === */
*, *::before, *::after { box-sizing: border-box; margin: 0; }
body {
font-family: system-ui, -apple-system, sans-serif; background: var(--bg);
color: var(--text); line-height: 1.6; transition: background 0.3s, color 0.3s;
}
/* === NAV === */
.site-nav {
display: flex; justify-content: space-between; align-items: center;
padding: 1rem 2rem; background: var(--bg); border-bottom: 1px solid var(--border);
position: sticky; top: 0; z-index: 100; transition: background 0.3s;
}
.site-logo { font-size: 1.25rem; font-weight: 700; color: var(--primary); text-decoration: none; }
.site-nav-links { display: flex; align-items: center; gap: 1.5rem; }
.site-nav-links a { text-decoration: none; color: var(--text-secondary); font-weight: 500; transition: color 0.2s; }
.site-nav-links a:hover { color: var(--primary); }
.theme-toggle {
background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 8px;
padding: 0.5rem; cursor: pointer; font-size: 1.1rem; min-width: 44px; min-height: 44px;
transition: all 0.2s;
}
.theme-toggle:hover { border-color: var(--primary); }
/* === HERO === */
.site-hero {
text-align: center; padding: 6rem 2rem;
background: var(--bg-secondary); transition: background 0.3s;
}
.site-hero h1 { font-size: clamp(2rem, 5vw, 3.5rem); margin-bottom: 1rem; }
.site-hero p { font-size: 1.15rem; color: var(--text-secondary); max-width: 600px; margin: 0 auto 2rem; }
.hero-btn {
display: inline-block; padding: 0.75rem 2rem; background: var(--primary);
color: white; border-radius: 8px; text-decoration: none; font-weight: 600;
transition: background 0.2s, transform 0.2s;
}
.hero-btn:hover { background: var(--primary-hover); transform: translateY(-2px); }
/* === SECTIONS === */
.site-section { padding: 5rem 2rem; max-width: 1100px; margin: 0 auto; }
.site-section h2 { text-align: center; font-size: 2rem; margin-bottom: 0.5rem; }
.site-section .section-subtitle { text-align: center; color: var(--text-secondary); margin-bottom: 3rem; }
/* === FEATURES === */
.features-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1.5rem; }
.feature-card {
background: var(--card-bg); padding: 2rem; border-radius: 12px;
box-shadow: var(--shadow); border: 1px solid var(--border); transition: all 0.3s;
}
.feature-card:hover { box-shadow: var(--shadow-lg); transform: translateY(-4px); }
.feature-card-icon { font-size: 2rem; margin-bottom: 1rem; }
.feature-card h3 { margin-bottom: 0.5rem; }
.feature-card p { color: var(--text-secondary); font-size: 0.9rem; }
/* === GALLERY === */
.gallery-grid {
display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 1rem;
}
.gallery-item {
border-radius: 12px; overflow: hidden; aspect-ratio: 4/3; position: relative; cursor: pointer;
}
.gallery-item img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.3s; }
.gallery-item:hover img { transform: scale(1.05); }
/* === CONTACT === */
.contact-form {
max-width: 600px; margin: 0 auto; display: flex; flex-direction: column; gap: 1rem;
}
.form-field { display: flex; flex-direction: column; gap: 0.25rem; }
.form-field label { font-weight: 600; font-size: 0.9rem; }
.form-field input, .form-field textarea {
padding: 0.75rem 1rem; border: 2px solid var(--border); border-radius: 8px;
font-size: 1rem; background: var(--card-bg); color: var(--text);
transition: border-color 0.2s, box-shadow 0.2s; min-height: 44px;
}
.form-field input:focus, .form-field textarea:focus {
outline: none; border-color: var(--primary);
box-shadow: 0 0 0 3px rgba(37,99,235,0.15);
}
.form-field textarea { min-height: 120px; resize: vertical; }
.form-submit {
padding: 0.75rem; background: var(--primary); color: white; border: none;
border-radius: 8px; font-weight: 600; font-size: 1rem; cursor: pointer;
min-height: 44px; transition: background 0.2s;
}
.form-submit:hover { background: var(--primary-hover); }
/* === FOOTER === */
.site-footer {
background: var(--bg-secondary); border-top: 1px solid var(--border);
padding: 3rem 2rem; text-align: center; color: var(--text-secondary);
}
/* === RESPONSIVE === */
@media (max-width: 768px) {
.site-nav-links a { display: none; }
.site-hero { padding: 4rem 1.5rem; }
.site-section { padding: 3rem 1.5rem; }
}
/* === ACCESSIBILITY === */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}
:focus-visible { outline: 3px solid var(--primary); outline-offset: 2px; }
</style>
<script>
function toggleTheme() {
const body = document.body;
const current = body.getAttribute('data-theme');
const next = current === 'dark' ? 'light' : 'dark';
body.setAttribute('data-theme', next);
document.querySelector('.theme-toggle').textContent = next === 'dark' ? '🌙' : '☀️';
localStorage.setItem('site-theme', next);
}
const saved = localStorage.getItem('site-theme');
if (saved) {
document.body.setAttribute('data-theme', saved);
document.querySelector('.theme-toggle').textContent = saved === 'dark' ? '🌙' : '☀️';
}
</script>
Défi final : Personnaliser un projet
Choisissez 3 projets parmi les 20 et personnalisez-les avec votre propre palette de couleurs, votre typographie et des animations originales. Le but est de créer quelque chose d'unique qui vous ressemble.
Défi : Combiner deux projets
Combinez le projet Dashboard (#8) avec le thème clair/sombre (#20) pour créer un tableau de bord avec toggle de thème complet.
Défi : Refactoriser un clone
Reprenez un des clones (#15-19) et refactorisez-le en utilisant un design system basé sur les variables CSS (Chapitre 23).
FORMATION CSS — SOMMAIRE COMPLET ══════════════════════════════════ NIVEAU 01-05 Fondamentaux ├── Introduction au CSS ├── Sélecteurs (simples, combinés, pseudo-classes, pseudo-éléments) ├── Cascade, héritage, spécificité ├── Unités (px, rem, %, vh, vw, clamp) └── Fonctions CSS (calc, var, min, max, clamp) NIVEAU 06-10 Propriétés de base ├── Couleurs, opacité, dégradés ├── Textes, typographie, web fonts ├── Box model (margin, padding, border, sizing) ├── Bordures, ombres, outlines └── Backgrounds, images, gradients NIVEAU 11-15 Composants ├── Listes et puces ├── Tableaux ├── Images responsive ├── Vidéos et embeds └── Liens et navigation NIVEAU 16-20 Layout moderne ├── Formulaires ├── Flexbox ├── CSS Grid ├── Positionnement (static, relative, absolute, fixed, sticky) └── Design responsive (media queries, clamp, fluid) NIVEAU 21-25 Animations & avancé ├── Transitions ├── Animations (@keyframes) ├── Variables CSS (Custom Properties) ├── Architecture CSS (BEM, SMACSS) └── (Niveau 26 — CSS moderne : nesting, :has, container queries) NIVEAU 26-30 Expert & Projets ├── CSS moderne (nesting, :has, container queries) ├── Accessibilité (A11Y, WCAG, contrast, focus) ├── Performance CSS (layout, paint, composite) ├── DevTools (debug, inspection, measurement) └── 20 projets finaux (★ à ★★★★★)
Récapitulatif complet de la formation CSS
rem et em ?