Efectos de texto
Cuatro acabados para tipografía display: un titular que sube línea a línea al llegar, un halo alrededor de los glifos, letras huecas dibujadas con un trazo y una banda de luz que cruza una línea una vez. Los cuatro son CSS. Solo la aparición y el destello de una sola pasada necesitan script, y únicamente para saber que el elemento está en pantalla: eso es Reveal, que ya documenta la página de efectos. Con prefers-reduced-motion: reduce, cada uno de ellos es un titular quieto y legible.
Están hechos para text-3xl en adelante. A 1,5 rem un trazo de un píxel recoge las franjas de color del antialiasing subpíxel y un halo se mete en los contornos interiores de las letras. El texto corrido conserva el contraste del tema y nada más.
Aparición, línea a línea
Cada línea es una máscara —iv-text-reveal__line con un span dentro— y el span interior empieza una línea más abajo hasta que Reveal marca el titular con data-iv-inview. Los saltos de línea los escribe el autor: ningún script parte el texto, así que sigue siendo seleccionable, traducible y legible tal como se sirvió. El escalonado es --iv-i multiplicado por --iv-text-reveal-step, dos propiedades personalizadas sin ningún temporizador detrás.
<section id="text-reveal" data-iv-component="reveal" class="iv-stack iv-u-gap-8">
<p class="iv-u-m-0 iv-u-max-w-measure">Sample copy for the fixture. Each line of the headline below is a mask; the span inside it starts one line lower and rises when <code>Reveal</code> marks the heading with <code>data-iv-inview</code>. The author writes the line breaks: no script splits the text, so it stays selectable, translatable and readable exactly as it was served. Without JavaScript, and under <code>prefers-reduced-motion: reduce</code>, every line is already up.</p>
<h2 class="iv-text-reveal iv-u-m-0" style="font-size: var(--iv-text-4xl); line-height: var(--iv-leading-tight); letter-spacing: var(--iv-tracking-tight)" data-iv-reveal>
<span class="iv-text-reveal__line"><span>The interface</span></span>
<span class="iv-text-reveal__line" style="--iv-i: 1"><span>starts here.</span></span>
</h2>
<div class="iv-stack iv-u-gap-4 iv-u-py-12" style="min-block-size: 90vh">
<h3 class="iv-u-m-0">Filler, so the next headline arrives on scroll</h3>
<p class="iv-u-m-0 iv-u-max-w-measure">The first heading is above the fold and reveals as soon as the observer reports it. The second one is below, and waits.</p>
<p class="iv-u-m-0 iv-u-max-w-measure">More filler. Sample copy for the fixture, with no claim of any kind.</p>
</div>
<h2 class="iv-text-reveal iv-u-m-0" style="font-size: var(--iv-text-4xl); line-height: var(--iv-leading-tight); letter-spacing: var(--iv-tracking-tight); --iv-text-reveal-step: 110ms" data-iv-reveal>
<span class="iv-text-reveal__line"><span>Four lines,</span></span>
<span class="iv-text-reveal__line" style="--iv-i: 1"><span>one after another,</span></span>
<span class="iv-text-reveal__line" style="--iv-i: 2"><span><span class="iv-gradient-text">staggered</span> by the index</span></span>
<span class="iv-text-reveal__line" style="--iv-i: 3"><span>the author served.</span></span>
</h2>
<p class="iv-u-m-0 iv-u-max-w-measure iv-u-py-12">The stagger is <code>--iv-i</code> multiplied by <code>--iv-text-reveal-step</code>, both plain custom properties: there is no JavaScript timer behind them.</p>
</section>.iv-root {
--iv-i: 1;
--iv-text-reveal-step: 110ms;
}// data-iv-component="reveal"
{
reveal: true,
}Halo
Dos capas de text-shadow: una ceñida que engorda los trazos y otra ancha que se derrama sobre la superficie de detrás. El color es el token de halo del tema, así que sigue al claro y al oscuro. iv-text-glow--pulse respira en un ciclo de 2,4 segundos. Un halo es un acabado, no un recurso de contraste: el glifo conserva el contraste que tenía.
<section id="text-glow" class="iv-stack iv-u-gap-8">
<p class="iv-u-m-0 iv-u-max-w-measure">Sample copy for the fixture. <code>.iv-text-glow</code> is two layers of <code>text-shadow</code> around the glyphs: a tight one that thickens the strokes and a wide one that spills onto the surface behind. The colour is the halo token of the theme, so it changes with light and dark.</p>
<h2 class="iv-text-glow iv-u-m-0" style="font-size: var(--iv-text-4xl); line-height: var(--iv-leading-tight); letter-spacing: var(--iv-tracking-tight)">Voltage in the type</h2>
<h2 class="iv-text-glow iv-text-glow--pulse iv-u-m-0" style="font-size: var(--iv-text-4xl); line-height: var(--iv-leading-tight); letter-spacing: var(--iv-tracking-tight)">And the same line, breathing</h2>
<p class="iv-u-m-0 iv-u-max-w-measure">The pulse runs for 2.4 seconds and repeats; under <code>prefers-reduced-motion: reduce</code> it stops at the glow itself. In forced colours the shadow is dropped and the heading is plain system text.</p>
<div class="iv-card iv-texture-mesh">
<div class="iv-card__body iv-stack iv-u-gap-4 iv-u-py-10">
<h3 class="iv-text-glow iv-u-m-0" style="font-size: var(--iv-text-3xl); line-height: var(--iv-leading-tight); letter-spacing: var(--iv-tracking-tight); --iv-text-glow-color: var(--iv-glow-secondary); --iv-text-glow-size: 0.7em">Over a gradient surface</h3>
<p class="iv-u-m-0 iv-u-max-w-measure">Both <code>--iv-text-glow-color</code> and <code>--iv-text-glow-size</code> are public locals; here the halo is the secondary one and a little wider.</p>
</div>
</div>
<p class="iv-u-m-0 iv-u-max-w-measure iv-u-text-sm iv-u-text-muted">A halo is a finish, not a contrast device: the glyph itself keeps the contrast of the theme, and the glow only adds presence around it.</p>
</section>.iv-root {
--iv-text-glow-color: var(--iv-glow-secondary);
--iv-text-glow-size: 0.7em;
}Contorno
iv-text-outline dibuja las letras huecas con el trazo que el motor pinta alrededor de cada glifo, detrás de un @supports: donde falta la propiedad, el titular simplemente conserva su relleno. iv-text-outline--fill lo devuelve mientras el enlace que lo rodea está bajo el puntero o enfocado. El trazo usa -webkit-text-fill-color: transparent y no un color transparente, porque tanto el trazo como el destello leen currentColor, y su color es el primario: el acento del tema oscuro es un cian brillante y no aguanta el contraste como línea fina.
<section id="text-outline" class="iv-stack iv-u-gap-8">
<p class="iv-u-m-0 iv-u-max-w-measure">Sample copy for the fixture. <code>.iv-text-outline</code> draws the letters hollow with the stroke the engine paints around each glyph. Where the property is missing the heading keeps its normal fill: less dramatic, never lost. In forced colours it goes back to plain text as well.</p>
<h2 class="iv-text-outline iv-u-m-0" style="font-size: var(--iv-text-4xl); line-height: var(--iv-leading-tight); letter-spacing: var(--iv-tracking-tight)">Hollow headline</h2>
<h2 class="iv-text-outline iv-u-m-0" style="font-size: var(--iv-text-4xl); line-height: var(--iv-leading-tight); letter-spacing: var(--iv-tracking-tight); --iv-text-outline-width: 2px; --iv-text-outline-color: var(--iv-color-primary)">Thicker, in the primary</h2>
<h3 class="iv-u-m-0">Filled by the link around it</h3>
<p class="iv-u-m-0 iv-u-max-w-measure">Hover the line below, or reach it with the keyboard: the fill returns while the link that contains it is hovered or focused. The link points back at this fixture and does nothing else.</p>
<p class="iv-u-m-0"><a href="#text-outline" style="font-size: var(--iv-text-4xl); line-height: var(--iv-leading-tight); letter-spacing: var(--iv-tracking-tight); text-decoration-thickness: 2px; text-underline-offset: 0.12em"><span class="iv-text-outline iv-text-outline--fill">Point at me</span></a></p>
<p class="iv-u-m-0 iv-u-max-w-measure iv-u-text-sm iv-u-text-muted">An outlined heading is thinner than solid text: keep it large, keep the stroke colour at contrast — the accent of the light theme is a bright green and does not reach it — and never use it for body copy. Below a display size the hairline picks up the colour fringing of subpixel antialiasing.</p>
</section>.iv-root {
--iv-text-outline-width: 2px;
--iv-text-outline-color: var(--iv-color-primary);
}Destello
Un degradado recortado a los glifos, con solo su posición animada, de modo que una banda de luz cruza la línea y no se repinta nada fuera de ella. iv-text-shimmer--once espera a data-iv-inview, pasa la banda una sola vez y se queda quieto: un bucle junto a texto corrido compite con la lectura. No lo combines con iv-gradient-text: los dos son dueños del mismo fondo, así que elige uno.
<section id="text-shimmer" data-iv-component="reveal" class="iv-stack iv-u-gap-8">
<p class="iv-u-m-0 iv-u-max-w-measure">Sample copy for the fixture. <code>.iv-text-shimmer</code> clips a gradient to the glyphs and moves only its position, so a band of light crosses the line and nothing repaints outside it. Do not combine it with <code>.iv-gradient-text</code>: both own the same background, so pick one. The band is the primary of the theme, not the accent: it replaces the colour of the glyph while it passes, and it has to stay readable the whole way across.</p>
<h2 class="iv-text-shimmer iv-u-m-0" style="font-size: var(--iv-text-4xl); line-height: var(--iv-leading-tight); letter-spacing: var(--iv-tracking-tight)">A band of light crosses the line</h2>
<h3 class="iv-u-m-0">Once, when it arrives</h3>
<p class="iv-u-m-0 iv-u-max-w-measure">The heading below carries <code>--once</code> and <code>data-iv-reveal</code>: it waits, still, until <code>Reveal</code> marks it as in view, runs the band across a single time and stays put. A loop next to running text would compete with the reading.</p>
<div class="iv-u-py-12" style="min-block-size: 90vh">
<p class="iv-u-m-0 iv-u-max-w-measure">Filler, so the heading below starts out of view.</p>
</div>
<h2 class="iv-text-shimmer iv-text-shimmer--once iv-u-m-0" style="font-size: var(--iv-text-4xl); line-height: var(--iv-leading-tight); letter-spacing: var(--iv-tracking-tight)" data-iv-reveal>One pass, then still</h2>
<p class="iv-u-m-0 iv-u-max-w-measure iv-u-py-12">Under <code>prefers-reduced-motion: reduce</code> the band is parked off the glyphs, so the line keeps its own colour and its contrast. In forced colours the gradient is dropped entirely.</p>
</section>// data-iv-component="reveal"
{
reveal: true,
}Teclado y tecnología asistiva
Los cuatro son titulares y siguen siéndolo. No hay nada que enfocar, ningún rol que añadir y ningún aria-hidden que colgar de una mitad decorativa, porque aquí nada duplica el texto: la aparición envuelve los saltos de línea del propio autor, el halo y el destello pintan los mismos glifos y el contorno los vacía. Los lectores de pantalla reciben el titular tal como está escrito. En modo de colores forzados se descartan la sombra, el degradado y el trazo, y el titular queda como texto del sistema.
Sin JavaScript
El halo y el contorno nunca necesitaron script. El destello se repite solo; únicamente su variante --once espera a Reveal, y sin el script se queda visible. La aparición es el caso interesante: la regla que esconde una línea está escrita bajo :root[data-iv-js], así que una página cuyo script no llegue muestra todas las líneas arriba y legibles. Una aparición que no ocurre no puede esconder un titular.
Tokens y locales
| Local | Por defecto | Qué mueve |
|---|---|---|
--iv-text-reveal-distance | 110% | Cuánto por debajo de la máscara empieza una línea. |
--iv-text-reveal-duration | token de movimiento lento × 3 | Duración de la subida de una línea. |
--iv-text-reveal-step | 80ms | Retardo por --iv-i entre líneas. |
--iv-text-glow-color | var(--iv-glow-primary) | Color del halo. |
--iv-text-glow-size | valor del halo | Cuánto se derrama el halo. |
--iv-text-outline-width | 1px | Grosor del trazo. |
--iv-text-outline-color | currentColor | Color del trazo. |
--iv-text-shimmer-color, --iv-text-shimmer-highlight | color del texto, var(--iv-color-primary) | La línea en reposo y la banda que la cruza. |
--iv-text-shimmer-duration | 2.8s | Una pasada de la banda. |
Los keyframes del destello van del 100 % al 0 %, no al revés: fuera de ese rango el degradado se sale de la caja y el titular desaparece con él.
Errores habituales
- Dejar que un script parta el titular en palabras o caracteres. Los saltos de línea son decisiones de contenido: escríbelos.
- Contorno o halo en texto corrido, o en cualquier cosa por debajo de un tamaño display.
- Apilar
iv-text-shimmersobreiv-gradient-text. Un fondo, un dueño. - Un destello en bucle al lado de un párrafo que alguien intenta leer. Usa
--once. - Recurrir a un halo para arreglar un problema de contraste. Arregla el color.