interactions · scroll · lecture
Fine barre qui se remplit au fur et à mesure de la lecture. Ici démontrée dans un cadre autonome (scrollez DANS le cadre) — sur un vrai site, remplace 'position: sticky' par 'position: fixed' pour qu'elle reste collée en haut de l'écran pendant tout le scroll de la page.
<style>
.bn-reading-demo {
padding: 2rem;
font-family: 'Inter', sans-serif;
background: #0B0F10;
}
/* Ce cadre (hauteur fixe + overflow-y: auto) ne sert QU'À LA DÉMO,
pour recréer une "page qui scrolle" en miniature. Sur un vrai
site, tu n'as pas besoin de ce cadre : la page entière fait
office de zone de scroll. */
.bn-reading-demo__box {
position: relative;
height: 260px;
overflow-y: auto;
border: 1px solid rgba(230, 228, 221, 0.12);
border-radius: 8px;
}
/* "sticky" colle la barre en haut DU CADRE tant qu'on scrolle
dedans — c'est l'équivalent, à l'échelle du cadre, de ce que fait
"position: fixed" à l'échelle d'une vraie page. Sur ton site,
remplace "sticky" par "fixed" (et retire le cadre autour) pour
qu'elle reste collée à l'écran plutôt qu'à ce conteneur. */
.bn-reading-bar {
position: sticky;
top: 0;
left: 0;
right: 0;
height: 3px;
background: rgba(230, 228, 221, 0.1);
z-index: 2;
}
.bn-reading-bar__fill {
height: 100%;
width: 0%;
background: #E6E4DD;
transition: width 0.1s linear;
}
.bn-reading-demo__article {
padding: 1.5rem;
}
.bn-reading-demo__kicker {
display: block;
font-size: 0.7rem;
letter-spacing: 0.1em;
text-transform: uppercase;
color: #979793;
margin-bottom: 0.4rem;
}
.bn-reading-demo__title {
font-family: 'Bebas Neue', sans-serif;
font-size: 1.4rem;
letter-spacing: 0.02em;
color: #E6E4DD;
margin: 0 0 1rem;
}
.bn-reading-demo__article p {
color: #979793;
font-size: 0.85rem;
line-height: 1.65;
margin: 0 0 1rem;
}
.bn-reading-demo__hint {
margin: 0.75rem 0 0;
color: #5C6160;
font-size: 0.75rem;
}
</style>
<div class="bn-reading-demo" data-fx-root>
<!-- Ce cadre à hauteur fixe et scroll interne n'existe QUE pour
la démo, afin que tu puisses voir l'effet sans avoir à
scroller toute la page. Sur un vrai site, la barre reprend
les mêmes classes mais sans ce cadre autour — voir la note
dans le CSS. -->
<div class="bn-reading-demo__box">
<div class="bn-reading-bar"><div class="bn-reading-bar__fill"></div></div>
<div class="bn-reading-demo__article">
<span class="bn-reading-demo__kicker">Réflexion</span>
<h3 class="bn-reading-demo__title">L'inconnu comme horizon</h3>
<p>Dans un monde saturé d'informations, Blaig Nova choisit la voie du silence et de la profondeur. Ici, chaque projet est une exploration.</p>
<p>Chaque réflexion, une tentative de comprendre ce qui nous échappe. Nous avançons dans l'inconnu, guidés par la curiosité, la rigueur et l'intuition.</p>
<p>Explorer, créer, partager : trois mouvements essentiels pour donner forme à ce qui n'existe pas encore.</p>
<p>Blaig Nova n'apporte pas de réponses toutes faites. Il ouvre des pistes, pose des questions, et invite chacun à trouver sa propre direction.</p>
<p>Ce n'est pas un simple portfolio. C'est un espace vivant, en constante évolution, où les idées prennent forme et où les projets deviennent des territoires à explorer.</p>
</div>
</div>
<p class="bn-reading-demo__hint">↕ Scrollez à l'intérieur du cadre ci-dessus pour voir la barre se remplir.</p>
</div>
<script>
/* ==========================================================
BARRE DE PROGRESSION DE LECTURE
Dans cette démo, le cadre a son propre scroll interne (voir le
CSS) : on écoute donc simplement le scroll de CE cadre, pas celui
de la page entière. Sur un vrai site (sans le cadre de démo), il
suffit d'écouter le scroll de "window" à la place.
========================================================== */
(function () {
const root = document.querySelector('.bn-reading-demo[data-fx-root]');
if (!root) return;
const box = root.querySelector('.bn-reading-demo__box');
const fill = root.querySelector('.bn-reading-bar__fill');
function update() {
const maxScroll = box.scrollHeight - box.clientHeight;
const percent = maxScroll > 0 ? (box.scrollTop / maxScroll) * 100 : 0;
fill.style.width = `${percent}%`;
}
box.addEventListener('scroll', update, { passive: true });
update();
})();
</script>