EX 05
Responsive Design — Mobile First
Media queries min-width
⏱ 25 min
SOLUTION CSS
/* ===== BASE MOBILE (par défaut) ===== */
.container {
width: 100%;
padding: 15px;
}
.nav-menu {
display: flex;
flex-direction: column; /* vertical sur mobile */
gap: 5px;
}
.content { display: block; }
.sidebar { display: none; } /* cachée sur mobile */
/* ===== TABLETTE ≥ 768px ===== */
@media (min-width: 768px) {
.container {
max-width: 720px;
margin: 0 auto;
padding: 20px;
}
.nav-menu {
flex-direction: row; /* horizontal sur tablette+ */
gap: 12px;
}
.content {
display: grid;
grid-template-columns: 1fr 200px;
gap: 20px;
}
.sidebar { display: block; }
}
/* ===== DESKTOP ≥ 1024px ===== */
@media (min-width: 1024px) {
.container { max-width: 960px; }
.content {
grid-template-columns: 1fr 280px;
gap: 32px;
}
.nav-menu { gap: 20px; }
}
VISUALISATION DES BREAKPOINTS
Accueil
Services
Contact
Main
Accueil
Services
Contact
Main
Accueil
Services
Contact
Main content
EX 06
Variables CSS & Thèmes
Design tokens pour thème clair et sombre
⏱ 20 min
SOLUTION CSS
/* ===== THÈME CLAIR (défaut) ===== */
:root {
--color-primary: #2563eb;
--color-primary-hover: #1d4ed8;
--bg-base: #ffffff;
--bg-surface: #f8f9fa;
--text-primary: #111827;
--text-secondary: #6b7280;
--border-color: #e5e7eb;
--radius-base: 8px;
--shadow-base: 0 1px 3px rgba(0,0,0,0.1);
}
/* ===== THÈME SOMBRE ===== */
[data-theme="dark"] {
--color-primary: #60a5fa;
--color-primary-hover: #93c5fd;
--bg-base: #0f172a;
--bg-surface: #1e293b;
--text-primary: #f1f5f9;
--text-secondary: #94a3b8;
--border-color: #334155;
--shadow-base: 0 1px 3px rgba(0,0,0,0.4);
}
/* OU : préférence système */
@media (prefers-color-scheme: dark) {
:root { /* mêmes variables dark... */ }
}
/* Utilisation dans les composants */
.card {
background: var(--bg-surface);
border: 1px solid var(--border-color);
color: var(--text-primary);
border-radius: var(--radius-base);
}
APERÇU DES DEUX THÈMES
☀️ Thème clair
🌙 Thème sombre
EX 07
Transitions & Animations CSS
@keyframes et transition
⏱ 20 min
SOLUTION CSS
.btn {
display: inline-block;
padding: 12px 28px;
background: #2563eb;
color: #fff;
border: none;
border-radius: 8px;
font-size: 15px;
font-weight: 600;
cursor: pointer;
box-shadow: 0 2px 8px rgba(37,99,235,0.3);
transition:
background-color 0.25s ease,
transform 0.2s ease,
box-shadow 0.25s ease;
}
.btn:hover {
background: #1d4ed8;
transform: translateY(-2px) scale(1.03);
box-shadow: 0 6px 20px rgba(37,99,235,0.45);
}
.btn:active {
transform: translateY(0) scale(0.98);
}
.btn:focus-visible {
outline: 3px solid rgba(37,99,235,0.5);
outline-offset: 2px;
}
ESSAYEZ LES BOUTONS
SOLUTION CSS
/* ① Spinner classique */
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.spinner {
width: 36px; height: 36px;
border: 3px solid rgba(37,99,235,0.15);
border-top-color: #2563eb;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
/* ② Dots loader */
@keyframes pulse-dot {
0%, 80%, 100% { transform: scale(0.6); opacity: 0.5; }
40% { transform: scale(1); opacity: 1; }
}
.dot-1, .dot-2, .dot-3 {
width: 8px; height: 8px;
background: #2563eb;
border-radius: 50%;
animation: pulse-dot 1.2s ease-in-out infinite;
}
.dot-2 { animation-delay: 0.2s; }
.dot-3 { animation-delay: 0.4s; }
/* Accessibilité */
@media (prefers-reduced-motion: reduce) {
.spinner, .dot-1, .dot-2, .dot-3 { animation: none; }
}
SPINNERS EN DIRECT