Altura de escena e indicadores de progreso
Estos dos patrones amplían la escena anclada básica: uno hace que la altura de una escena anclada siga la cantidad de elementos que realmente contiene, el otro construye una barra fina que se llena con el progreso de cualquier escena o rango de scroll.
Altura de escena que sigue el número de elementos
Con 3 pasos o con 12, cada uno debería recibir la misma cantidad de scroll para reproducir su propia animación. En lugar de fijar una altura de escena a mano, esta receta mide cuántos elementos hay realmente presentes y deriva de ahí la altura correcta — y recalcula el progreso de la ventana anclada para exactamente esa altura.
Estructura:
section .scene-section reinicio de overflow-x, padding 0
└─ div .scene su propia fila Custom, sin Start/End (sin "Get parent")
└─ div .scene__stage sticky (ver Escenas ancladas)
└─ … .scene__item ×n los elementos que se cuentan, a cualquier profundidad
Los hijos leen el --fa-scroll--custom de la escena por herencia; no necesitan su propia fila.
CSS:
.scene {
position: relative;
width: 100%;
--sc-x: 4;
--sc-h: calc(var(--fa-scroll--custom) * 0vh + var(--sc-x) * 100vh);
height: var(--sc-h, auto);
}
.scene:has(.scene__item:nth-child(2)) { --sc-x: 2.2; }
.scene:has(.scene__item:nth-child(3)) { --sc-x: 2.8; }
.scene:has(.scene__item:nth-child(4)) { --sc-x: 3.4; }
.scene:has(.scene__item:nth-child(5)) { --sc-x: 4; }
.scene:has(.scene__item:nth-child(6)) { --sc-x: 4.6; }
/* … X = 1 + .6 × k, continuando hasta k = 12 (X = 8.2); mantenlas en orden ascendente, gana la última coincidencia */
.scene__stage {
--sc-q: clamp(0, (var(--fa-scroll--custom) * (var(--sc-x) + 1) - 1) / (var(--sc-x) - 1), 1);
}
- Una escena que mide
Xpantallas de alto se ancla desde el progreso1/(X+1)hastaX/(X+1).--sc-qreasigna exactamente ese tramo a un limpio 0 → 1, sea cual sea elXresultante. :has(.scene__item:nth-child(k))coincide siempre que haya al menoskelementos. Sin soporte de:has(),Xsimplemente se queda en su valor por defecto de 4.- Sin la animación en marcha,
--sc-hse vuelve inválida y la escena recurre a su altura natural — el escenario simplemente no queda anclado, y su contenido fluye como una sección normal. - El elemento
i(desde 0) denen total está "actual" mientras--sc-q × nse sitúa entreiyi + 1. Con "Index children" en el propio padre de los elementos,--fa-iy--fa-nte daniyndirectamente.
Valores que puedes cambiar: el multiplicador .6 (pantallas de scroll por elemento), y el
--sc-x por defecto (4, usado como respaldo en navegadores sin soporte de :has()).
- Bricks
- Etch
- Escena: añade una fila Custom sin Start/End. Si sus hijos necesitan suavizado del scroll, ajústalo aquí también, ya que heredan el valor suavizado.
- Las reglas
:has()van en el CSS personalizado propio de la escena, referenciando el nombre de clase real del elemento.
- Clases de la escena:
fa--custom(opcionalmentefa--smooth-20). - Escribe las reglas anidadas dentro de la propia clase de
.scene:&:has(.scene__item:nth-child(2)) { --sc-x: 2.2; }, y así sucesivamente.
Problemas comunes:
- El progreso ajustado a ojo se descuadra en cuanto se añade o quita un elemento. Las ventanas
se fijaron a mano en lugar de derivarlas de
--sc-qy del índice del elemento — deriva todo de esos valores en su lugar. - El escenario se corta en pantallas bajas dentro del constructor. Se usó una altura fija en
lugar del patrón de respaldo
var(--sc-h, auto). --sc-qda un valor que no cuadra. El propio elemento de la escena estaba transformado, o se está midiendo a través de "Get parent" desde otro sitio — debe medirse a sí mismo, y permanecer sin transformar.
Indicador de progreso
Una barra fina que se llena de 0% a 100% a medida que una escena se reproduce, o a medida que una lista larga pasa de largo junto a una columna lateral fija.
Estructura (horizontal, dentro de una escena anclada):
div .scroll-progress centra la barra
└─ div .scroll-progress__bar el carril: tamaño fijo, overflow hidden
└─ div .scroll-progress__fill "Get parent" + una fila Custom — la misma ventana que la animación que reporta
Estructura (vertical, junto a una lista que hace scroll normal):
section .list-progress "I am parent", reinicio de overflow-x
└─ div .list-progress__row fila flex
├─ div .list-progress__content la lista larga
└─ div .list-progress__side columna fija (sticky), una pantalla de alto
└─ .scroll-progress__bar > .scroll-progress__fill "Get parent" + Custom, Start 20, End 80
CSS:
.scroll-progress { display: flex; justify-content: center; }
.scroll-progress__bar {
width: 300px; height: 3px;
background: #d4d4d8; border-radius: 10em; overflow: hidden;
}
.scroll-progress__fill {
height: 100%; min-width: 0;
background: var(--primary, #2563eb);
width: calc(var(--fa-scroll--custom, 0) * 100%);
}
/* variante vertical */
.list-progress__row { display: flex; justify-content: space-between; }
.list-progress__content { width: calc(100% - 4rem); }
.list-progress__side {
position: sticky; top: 0; height: 100vh; width: 1rem;
display: flex; align-items: center; justify-content: center;
}
.list-progress__side .scroll-progress__bar { width: 4px; height: 180px; }
.list-progress__side .scroll-progress__fill { width: 100%; min-height: 0; height: calc(var(--fa-scroll--custom, 0) * 100%); }
El elemento de relleno también puede prescindir de su propia fila y simplemente heredar
--fa-scroll--custom de un ancestro que ya tenga una — el valor es el mismo de cualquier forma.
Valores que puedes cambiar: usa el mismo Start/End (y el mismo valor de suavizado del scroll) que la animación que la barra está reportando, o ambas se irán desincronizando visiblemente. Para la pista horizontal anclada en concreto, usa en su lugar la barra de progreso incorporada en esa receta — la altura de su escena sigue las tarjetas directamente, así que una ventana fija aquí se desincronizaría de ella.
- Bricks
- Etch
- Fill: "Get parent" + una fila Custom con el Start/End que estás reportando.
- La barra y el fill son elementos vacíos — dale a sus clases un ancho/alto mínimo explícito de 0, o el lienzo del constructor los muestra con su tamaño de marcador de posición por defecto de 90px.
- Variante vertical: la sección necesita "I am parent" y el reinicio de overflow-x; las reglas
descendientes
.list-progress__side …van en el CSS personalizado propio de la columna lateral, escritas completas.
- Clases del fill:
fa--parent fa--custom fa--custom--start-25 fa--custom--end-75(ajusta a la ventana que estés reportando). - Los elementos vacíos se muestran como una caja de marcador de posición en el lienzo — ajusta la variable de tamaño de elemento vacío exclusiva del lienzo en la clase de la barra si resulta molesta.
- Anida las reglas descendientes dentro de la clase de la columna lateral:
& .scroll-progress__fill { … }.
Problemas comunes:
- La barra está llena desde el principio, o nunca se mueve. Falta "Get parent" (así que se mide a sí misma, lo cual dentro de un escenario anclado nunca cambia), o falta "I am parent" por encima.
- Va por delante, o por detrás, de la animación que debería seguir. Una ventana distinta, o un valor de suavizado del scroll distinto, al de lo que está reportando.
- La columna lateral no se queda fija. Falta el reinicio de overflow-x en la sección, o la columna no mide una pantalla completa de alto.
- El fill muestra una franja visible incluso al 0%. Un ancho/alto mínimo por defecto del constructor en un elemento vacío — ajústalo explícitamente a 0.