J'avais besoin d'un guide d'achat pour les consoles rétro portables — le genre de page qu'on consulte depuis un canapé un samedi soir avant de craquer sur eBay. Contenu statique, pas de dynamique, pas d'API. Un prétexte parfait pour faire du CSS débridé sans avoir à le justifier devant une équipe. L'idée : un dark theme cyberpunk, des scanlines qui rappellent les vieux écrans CRT, des typos rétro-futuristes. Et surtout, aucun framework, aucune ligne de JavaScript.
Ce que j'ai appris en le construisant, c'est que les effets les plus visuellement forts ne viennent pas des bibliothèques d'animation — ils viennent de la bonne combinaison de CSS gradients, de pseudo-éléments et de custom properties bien structurées. Voici comment ça marche.
Le contexte
La page cible : retro-consoles.html. Un guide d'achat avec une vingtaine de consoles rétro portables — Game Boy, Analogue Pocket, Miyoo Mini, Anbernic RG35XX et toute la bande. Chaque console a ses specs, son prix, ses pour et contre.
La contrainte technique était simple : page statique, hébergée sur le même serveur Apache
que le CV, zéro dépendance runtime. Le parti pris esthétique était plus ambitieux : recréer
l'ambiance visuelle d'un écran CRT des années 80 dans un navigateur moderne. L'accent couleur
cyan #00d4ff, choisi pour son côté phosphore vert converti en bleu électrique,
donne le ton. Le reste du thème en découle.
L'effet scanlines — pure CSS
Les scanlines sont l'effet le plus reconnaissable visuellement et le plus simple à
implémenter techniquement. L'idée : un ::before en position fixe qui couvre
toute la page, avec un repeating-linear-gradient qui alterne transparent et
semi-opaque toutes les deux lignes.
body::before {
content: '';
position: fixed;
inset: 0;
pointer-events: none;
z-index: 9999;
background: repeating-linear-gradient(
to bottom,
transparent,
transparent 1px,
rgba(0, 0, 0, 0.08) 1px,
rgba(0, 0, 0, 0.08) 2px
);
}
Trois décisions ici qui méritent d'être explicitées.
position: fixed et non absolute.
L'effet doit se superposer à tout le contenu même quand on scrolle, comme un vrai écran
physique. fixed reste ancré à la fenêtre.
pointer-events: none. Sans ça, le pseudo-élément absorbe
tous les clics et la page devient inutilisable. Un oubli classique avec les overlays CSS.
Opacité à 0.08 sur les lignes sombres. Le chiffre est arbitraire mais résulte de plusieurs itérations. Trop fort (0.2+) et ça devient illisible. Trop faible (0.03) et l'effet disparaît sur les fonds clairs — mais ici le fond est sombre, donc le contraste fonctionne à des valeurs basses.
Typographies rétro : Orbitron, Space Mono, pourquoi ces choix
Le choix typographique dans un design thématique, c'est 70% de l'identité visuelle. Trois polices, trois rôles distincts :
/* Titres : Orbitron — chiffres géométriques, majuscules angulaires */
h1, h2, h3 {
font-family: 'Orbitron', monospace;
letter-spacing: 0.05em;
text-transform: uppercase;
}
/* Prix, specs techniques : Space Mono — monospace à personnalité */
.price,
.spec-value {
font-family: 'Space Mono', monospace;
}
/* Corps de texte : DM Sans — lisible, neutre, passe partout */
body {
font-family: 'DM Sans', sans-serif;
}
Orbitron pour les titres : c'est la police "rétro-futuriste" par excellence, dessinée avec des formes géométriques et des angles droits. Elle marche aussi bien pour "GAME BOY" que pour "ANALOGUE POCKET". La contrepartie : elle est illisible en corps de texte. Un titre en Orbitron à 14px donne envie de fermer l'onglet.
Space Mono pour les données chiffrées. Une monospace dessinée par Colophon Foundry, plus personnelle qu'une Courier ou une Roboto Mono. Les prix alignés verticalement en Space Mono sur fond sombre rappellent les écrans de terminal des années 80.
DM Sans pour le reste. La règle est simple : ne jamais mettre une typo de caractère dans le corps du texte. Orbitron pour 500 mots de descriptions de consoles, ce serait de la maltraitance.
Custom properties pour tout le thème
La contrainte d'un dark theme cohérent avec un accent couleur unique se gère bien avec
des custom properties dès le début. Pas une couleur en dur dans tout le fichier CSS —
tout passe par :root.
:root {
/* Fond */
--bg-primary: #0a0a0f;
--bg-secondary: #111118;
--bg-card: #16161f;
--bg-card-hover:#1c1c28;
/* Accent principal */
--accent: #00d4ff;
--accent-dim: rgba(0, 212, 255, 0.15);
--accent-glow: 0 0 20px rgba(0, 212, 255, 0.3);
/* Texte */
--text-primary: #e8e8f0;
--text-secondary:#9090a8;
--text-muted: #5a5a72;
/* Bordures */
--border: rgba(0, 212, 255, 0.2);
--border-strong: rgba(0, 212, 255, 0.5);
}
Quelques détails qui font la différence. --accent-dim : une version très
atténuée de l'accent pour les fonds de survol et les badges. Sans ça, on se retrouve
à recalculer rgba(0, 212, 255, X) partout dans le CSS. --accent-glow
: le halo néon sur les éléments mis en avant, défini une seule fois comme valeur de
box-shadow.
L'effet de lueur sur les cartes au survol se réduit alors à :
.console-card:hover {
background: var(--bg-card-hover);
border-color: var(--border-strong);
box-shadow: var(--accent-glow);
transform: translateY(-2px);
transition: all 0.2s ease;
}
Le layout responsive sans framework
CSS Grid avec auto-fill et minmax — la seule façon de faire
un layout multi-colonnes vraiment responsive sans une seule media query pour les cartes :
.consoles-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;
}
Avec minmax(280px, 1fr), le navigateur calcule lui-même combien de colonnes
rentrent. Sur un écran 1440px : 4 colonnes. Sur un iPad 768px : 2 colonnes. Sur iPhone :
1 colonne. Aucun breakpoint à gérer manuellement pour la grille.
Les media queries restent nécessaires pour d'autres ajustements : réduire les
font-size d'Orbitron sur mobile (les titres géométriques sont larges),
passer le header de deux colonnes à une colonne, ajuster les paddings.
.page-header {
display: grid;
grid-template-columns: 1fr auto;
align-items: center;
gap: 32px;
}
@media (max-width: 768px) {
.page-header {
grid-template-columns: 1fr;
}
h1 {
font-size: clamp(1.4rem, 5vw, 2.5rem);
}
}
clamp() pour les titres Orbitron : essentiel. Sans ça, un h1
de 2.5rem en Orbitron dépasse du viewport sur iPhone SE.
Conclusion
Ce projet a confirmé quelque chose que je savais en théorie mais que je sous-estime
régulièrement en pratique : un design fort ne nécessite pas de JS. L'animation du
survol sur les cartes, l'effet scanlines, le halo néon — tout ça fonctionne avec
transition, box-shadow, et un pseudo-élément. Le navigateur
fait le rendu sur le GPU, sans un seul requestAnimationFrame.
La véritable complexité n'était pas technique — c'était le calibrage visuel. Trouver l'opacité des scanlines qui crée l'atmosphère sans gêner la lecture. Choisir la luminosité du cyan qui évoque le phosphore sans cramer les yeux. Ce sont des décisions qui ne s'écrivent pas en code, elles se valident à l'œil.
Le résultat : retro-consoles.html.