Ce qui est inclus
Un jeu de cartes déployé en éventail, dans deux fichiers : une feuille de style et un script. Aucune dépendance, aucune étape de build, aucune requête externe — on les copie dans un projet et ça marche.
Chaque carte s’écarte, retombe, s’incline et rapetisse en
proportion de sa distance à la carte choisie. Cette
arithmétique est faite en CSS, à partir d’un seul nombre :
l’index du bouton radio coché, que
:has() publie dans une variable. C’est pour ça
que l’éventail est en place avant que le script n’arrive, et
qu’il y reste si le script ne vient jamais.
Fonctionnalités
- L’état vit dans le document — une case cochée, pas une variable JavaScript. Le CSS la lit, le clavier la parcourt, un formulaire l’enverrait telle quelle.
- Clavier complet, sans une ligne de code — ce sont des boutons radio natifs : les flèches passent d’une carte à l’autre, Tab entre et sort du groupe, et l’anneau de focus se pose sur la pastille.
- Marche sans JavaScript — l’éventail est déployé, les cartes se cliquent, les pastilles répondent. Le script n’ajoute que le glisser au doigt et à la souris.
-
Une variable pour l’échelle — carte, arc,
inclinaison, arrondi, ombres et les cinq tailles de texte
dérivent tous de
--arc-font-size. -
Le ressort d’origine, en CSS — la courbe
linear()est échantillonnée sur le ressort de la référence, dépassement de 8,3 % compris. Trajectoire mesurée : 0,67 px d’écart moyen sur une course de 214. -
Il s’adapte à son conteneur, pas à la fenêtre
— les seuils sont des
@container, donc un éventail posé dans une colonne étroite se resserre même sur un grand écran.
Le poser dans une page
Deux fichiers à charger, puis le balisage :
<link rel="stylesheet" href="fan-carousel.css">
<script src="fan-carousel.js" defer></script>
<section class="fan-carousel" data-fan-carousel aria-label="Nos formules">
<header class="fan-carousel__intro">
<p class="fan-carousel__eyebrow">Surtitre</p>
<h2 class="fan-carousel__headline">Le titre</h2>
</header>
<div class="fan-carousel__stage">
<article class="fan-carousel__card" role="group" aria-labelledby="t1">
<div class="fan-carousel__frame">
<img class="fan-carousel__image" src="…" alt="…">
<div class="fan-carousel__caption">
<div class="fan-carousel__text">
<h3 class="fan-carousel__title" id="t1">Titre</h3>
<p class="fan-carousel__subtitle">Sous-titre</p>
</div>
<span class="fan-carousel__tag">Étiquette</span>
</div>
</div>
<label class="fan-carousel__hit" for="c1" aria-hidden="true"></label>
</article>
<!-- … -->
</div>
<div class="fan-carousel__dots" role="radiogroup" aria-label="Carte à mettre en avant">
<input class="fan-carousel__radio" type="radio" name="deck" id="c1" checked>
<label class="fan-carousel__dot" for="c1"><span class="fan-carousel__sr">Titre</span></label>
<!-- … -->
</div>
<div class="fan-carousel__probe" aria-hidden="true"></div>
</section>
Une case cochée par carte, dans l’ordre des cartes : c’est tout ce que le composant demande. La case cochée au départ est celle qui sera devant.
Ce qu’il faut savoir
- L’éventail est plus large que son cadre. C’est le dessin : les cartes sortent des deux côtés. La scène les coupe à l’horizontale et les laisse retomber vers le bas, de sorte que le composant ne donne jamais de barre de défilement à la page qui l’accueille — ce que la référence, elle, fait de 31 px à 810 et de 131 px à 390.
-
Douze cartes au plus. Le CSS écrit une
règle par rang ; au-delà, l’éventail n’est plus lisible de
toute façon. Chaque instance a besoin d’un
nameet d’idqui lui sont propres. -
Les flèches restent dans le composant.
Elles agissent quand une pastille a le focus, parce que ce
sont les flèches natives d’un groupe de boutons radio. La
référence les écoutait sur
window: elles changeaient de carte même pendant qu’on tapait dans un champ ailleurs sur la page. -
Aucun style ni script en ligne. Le
composant respecte la politique de sécurité stricte du
site, vérifiée en le servant sous l’en-tête, et n’utilise
jamais
innerHTML. - Le dessin vient d’ailleurs. Les proportions reprennent celles d’un composant Framer commercial, relevées sur le site publié à cinq largeurs. Le code, lui, est original : rien n’a été repris de son implémentation. Les six photographies sont celles de la démonstration d’origine, de licence inconnue — à remplacer par les vôtres.
Prends-le, ouvre-le, casse-le.
Ce composant est gratuit. La bibliothèque complète — les templates et les autres composants — est incluse dans l’abonnement, avec la formation.
Accès immédiat · Sans engagement · Annulation en 1 clic