Catálogo · Contenido
Contenido incrustado
Un póster y un botón de reproducir en lugar de un reproductor de otro sitio, que se carga solo cuando el visitante lo pide, tras el consentimiento.
Encaja mejor en: cualquier sitio — una página que muestra un vídeo o un mapa de otro sitio
Ejemplo
El vídeo de la NASA del saludo de John Young en la Luna, con un póster de este sitio. No se pide nada al servicio de vídeo hasta que pulsas el botón y aceptas: el ejemplo pregunta primero, como lo haría un sitio que quiere consentimiento, y solo entonces carga el reproductor. Su respuesta se guarda con su propia clave, luz-consent-demo, así que no cuenta como respuesta para este sitio.
Play video:
Sin JavaScript, el póster es un enlace al vídeo.
Esta es la única página de este sitio que puede cargar otro sitio, y solo después de que pulses el botón y aceptes: la política de seguridad del sitio permite que esta página, y ninguna otra, muestre en un marco www.youtube-nocookie.com.
Problemas conocidos
Dos cosas que conviene saber antes de fiarse de él.
- La pregunta no tiene un botón para retirar «Reproducir siempre». Para que un visitante pueda retirarlo, ofrece la categoría como casilla en el aviso de cookies, con su botón de cambiar: la respuesta del aviso se fusiona en el mismo registro, y su evento
luz:consentindica lo retirado endetail.withdrawn. - No se ha probado con un lector de pantalla.
Código
Copiar el marcado
import "@luz-ds/catalog/components/embed.css";
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@luz-ds/catalog@0.3.0/dist/components/embed.min.css" integrity="sha384-4EY9C7PN373Q38ElCXt3Rp+L44k42GwbC9m/nXfz5dvXn0Zeki8AXTPkFLJU3Qrn" crossorigin="anonymous">
El enlace es la página sin JavaScript, así que escríbelo como la página a la que quieres que llegue el lector: apunta al vídeo donde está alojado. src es la dirección del reproductor, completa, tal como la da el otro sitio (aquí, la dirección de incrustación con privacidad reforzada que YouTube da para un vídeo); LUZ no construye ninguna dirección ni nombra a ningún proveedor. El póster es tu propia imagen, en tu propio servidor: un póster pedido al otro sitio lo alcanzaría al cargar la página.
catalog.min.js carga el archivo propio del elemento, embed.min.js, cuando recorre la página; una página sin catalog.min.js carga ese archivo por su cuenta.
<script type="module" src="https://cdn.jsdelivr.net/npm/@luz-ds/catalog@0.3.0/dist/catalog.min.js"></script>
<luz-embed src="https://www.youtube-nocookie.com/embed/g5aPoRtF2vw?autoplay=1" consent="youtube">
<a class="luz-embed__link" href="https://www.youtube.com/watch?v=g5aPoRtF2vw">
<img class="luz-embed__poster" src="/media/apollo-16-poster.jpg" alt="" width="1280" height="720" loading="lazy">
<span class="u-sr-only">Play video: </span>
<span class="luz-embed__title">John Young’s Lunar Salute on Apollo 16</span>
</a>
<div class="luz-embed__ask" data-luz-embed-ask hidden>
<p>This video is hosted by YouTube (Google). If you play it, YouTube receives your IP address and details of your browser, and may store information on your device. We receive none of it. <a href="/docs/privacy/">Privacy and storage</a></p>
<div class="o-actions">
<button class="luz-btn luz-btn--primary" type="button" value="once">Play this video</button>
<button class="luz-btn luz-btn--primary" type="button" value="cancel">Do not play</button>
<button class="luz-btn luz-btn--secondary" type="button" value="always">Always play YouTube videos on this site</button>
</div>
</div>
</luz-embed>
Tus scripts pueden preguntar qué cargaría el elemento:
import { playerURL } from "@luz-ds/catalog/embed";
// The address the element would load, or null when it stays a link
const url = playerURL(document.querySelector("luz-embed"));
Variantes y opciones
No hay variantes. La proporción es una propiedad y los puntos de extensión son atributos.
| Clase o atributo | Efecto |
|---|---|
<luz-embed> | El elemento personalizado que define el módulo: un bloque con la proporción del marco. Se conecta solo al añadirse a la página |
src | Obligatorio. La dirección completa del reproductor, escrita por ti: https: o del mismo origen que la página. Cualquier otra (javascript:, http: de otro origen, un error de escritura) deja el enlace |
consent | El nombre de una categoría del consentimiento para cookies (una letra minúscula y después minúsculas, dígitos o guiones, 32 como máximo). Mientras no se conceda no se pide nada al origen del reproductor, y un clic pregunta primero. Sin bloque de pregunta y sin la categoría concedida, se queda como enlace |
data-luz-consent-key | La clave de almacenamiento de la elección, que debe empezar por luz-; por defecto luz-consent, la del aviso |
data-luz-consent-days, data-luz-consent-policy | Se leen del aviso de cookies de la página, si lo hay: cuántos días dura «Siempre» (180 por defecto, 395 como máximo) y la versión de la política mostrada, que se guarda con la elección |
--luz-embed-ratio | La proporción del marco, 16 / 9 por defecto. Se fija en el elemento: style="--luz-embed-ratio: 4 / 3" |
.luz-embed | El enlace de la página sin JavaScript: contiene el póster y el título, y ocupa todo el marco. Con JavaScript pasa a ser un button.luz-embed con los mismos hijos, así que su nombre no cambia |
.luz-embed, .luz-embed | Tu imagen, que cubre el marco, y el título, sobre un velo en la parte inferior |
.luz-embed with data-luz-embed-ask | Opcional, con hidden en el marcado: la pregunta que se muestra cuando el clic necesita un consentimiento que no está. Sus botones tienen un value: once, always o cancel |
data-luz-state | Lo escribe el script: ready, ask o playing. Dale estilo, pero no lo fijes |
playerURL(el) | Lo exporta @luz-ds/catalog/embed: la dirección validada del elemento, o null |
Cómo funciona
CSS de @luz-ds/catalog y un archivo propio, @luz-ds/catalog/embed (dist/embed.min.js, menos de 1,5 kB comprimido), que define <luz-embed>. No usa ninguna biblioteca, y el script del reproductor, si lo tiene, se ejecuta solo dentro del marco, una vez cargado. Un vídeo o un audio nativos no lo necesitan: usa el reproductor. Esto es para lo que solo otro sitio puede mostrar.
- Antes del clic: la página contiene un póster y un botón, y no pide nada al otro sitio. Cuando el puntero pasa sobre el botón, o el foco llega a él, se avisa al navegador de que abra una conexión con el origen del reproductor (un
preconnect, una vez por origen), salvo que el sitio quiera consentimiento y no esté concedido. - El clic: si nada necesita consentimiento, o está concedido, se escribe el marco con permiso de
autoplayy el foco entra en él. Si hace falta consentimiento, la pregunta se muestra en su lugar y el foco va a su primer botón. - La pregunta:
value="once"reproduce este vídeo.value="always"lo reproduce y guarda la categoría, como hace el aviso de cookies, enlocalStoragecomo{"version":1,"expires":…,"asked":[…],"granted":[…],"given":"…"}, fusionado en el registro que ya hay para que se conserven las categorías del aviso, emiteluz:consentendocumenty desbloquea todos los demás contenidos incrustados con esa categoría.value="cancel"vuelve al póster, con el foco en su botón. Escape no hace nada; el botón que cancela es la vuelta atrás. - El marco: tiene el título del vídeo,
allowpara las funciones que usan los reproductores,allowfullscreenyreferrerpolicy="strict-origin-when-cross-origin", que algunos reproductores necesitan para aceptar la incrustación. - El script no escribe ningún texto: cada palabra está en tu marcado, en el idioma de la página.
Un servidor que construya tus páginas puede escribir src y guardar el póster al guardar el contenido, para que el lector nunca contacte con el otro sitio antes de elegirlo.
Sin JavaScript
El póster es un enlace con un título visible que abre el vídeo donde está alojado, y la pregunta queda oculta. Hace lo mismo cuando src no es válido, y cuando la categoría no está concedida y no hay pregunta que hacer.
Teclado y ARIA
- Teclas: Tab llega al botón; Intro o Espacio lo pulsan, como en cualquier botón. En la pregunta, Tab recorre sus botones. Escape no hace nada.
- Nombre: el botón tiene el nombre del enlace al que sustituye: las palabras ocultas «Play video:» y luego el título.
- Foco: al primer botón de la pregunta cuando se muestra, al marco cuando se carga el reproductor, de vuelta al botón con No reproducir. Cuando el reproductor está en el marco, sus teclas y controles son los del otro sitio, y la página no puede alcanzarlos.
- Idioma: la pregunta y los nombres son tuyos, en el idioma de la página. Los del reproductor son los del otro sitio.
Contraste y foco están en la pestaña Diseño.
Diseño
Cuándo usarlo
Úsalo para un vídeo, un mapa o cualquier reproductor que una página toma de otro sitio. Cargar un marco así envía la dirección del lector a ese sitio, y su script pesa más que el resto de la página; un póster y un botón cuestan una imagen.
Cuándo no usarlo
No lo uses para un vídeo o un sonido que alojas tú: eso es el reproductor, que tiene controles con estilo de LUZ y un teclado que LUZ prueba.
- No lo uses para un enlace a una página que resulta tener un vídeo: eso es una tarjeta o un enlace.
- No lo uses para ocultar un marco que el lector nunca pidió: se carga solo tras un clic.
Sustituye al código de iframe que te da el otro sitio y a los scripts de fachada de un proveedor. No se quita nada de LUZ.
Qué hacer y qué no
Cómo escribir el contenido
El título es el título del vídeo, como lo diría el lector, y las palabras ocultas que lo preceden dicen qué hace el botón: «Reproducir vídeo:». No repitas el título en el alt del póster, que queda vacío porque el título ya lo nombra.
- Nombra el servicio en la pregunta («alojado por YouTube (Google)»), di qué conoce («tu dirección IP y datos de tu navegador») y qué puede hacer («guardar información en tu dispositivo»), en pocas frases claras, con un enlace a tu página de privacidad.
- Escribe los botones como la acción y la cosa: «Reproducir este vídeo», «No reproducir», «Reproducir siempre los vídeos de YouTube en este sitio». Da a los dos primeros el mismo peso. Nunca «OK» ni «Sí».
- Elige un póster cuya parte importante no esté en el centro: la marca de reproducir la cubre.
Contraste y foco
El título va sobre un velo que es sólido donde está el texto, así que se lee también sobre un póster blanco.
| Parte | Color sobre el fondo | Claro | Oscuro | Alto contraste | Mínimo necesario |
|---|---|---|---|---|---|
Título sobre su velo | --luz-text-on-fill on --luz-scrim | 5.2:1 | 20.1:1 | 5.0:1 | 4.5:1 |
Triángulo de la marca de reproducir | --luz-text-on-fill on --luz-brand-fill | 6.0:1 | 4.9:1 | 14.1:1 | 3:1 |
Disco de la marca de reproducir, sobre el póster más claro | --luz-brand-fill on --luz-surface-page | 5.6:1 | 3.5:1 | 14.1:1 | 3:1 |
Borde del disco, sobre el póster más oscuro | --luz-text-on-fill on --luz-surface-media | 21.0:1 | 21.0:1 | 21.0:1 | 3:1 |
Texto de la pregunta | --luz-text-primary on --luz-surface-muted | 15.8:1 | 15.1:1 | 20.1:1 | 4.5:1 |
Anillo de foco, sobre la página | --luz-focus-ring on --luz-surface-page | 5.6:1 | 7.7:1 | 21.0:1 | 3:1 |
Calculado a partir de los valores de los tokens de cada modo, redondeado hacia abajo. El mínimo es el de WCAG 2.2 AA: 4,5:1 para el texto y 3:1 para la marca de reproducir, los anillos de foco y los bordes. El velo se mide sobre la página, el póster más claro que existe.
- Foco: un contorno de 2 px de
--luz-focus-ringalrededor de todo el marco, por fuera y con 2 px de separación, para que el póster nunca lo oculte. Los botones de la pregunta son de core. - La marca de reproducir es un disco y un triángulo, no solo color. En colores forzados es un anillo y un triángulo con el color del texto de botón del sistema.
Tokens que usa
Los 14 tokens que leen las reglas de components/embed.css del catálogo, agrupados por familia; los botones de la pregunta son de core. Cada familia enlaza a su página, con los valores de todos los modos. En Figma son variables con los mismos nombres: consulta Tokens en Figma.
- Color
--luz-brand-fill,--luz-brand-fill-hover,--luz-focus-ring,--luz-scrim,--luz-surface-media,--luz-surface-muted,--luz-text-on-fill,--luz-text-primary- Spacing and sizing
--luz-space-lg,--luz-space-md,--luz-space-sm- Typography
--luz-font-sans,--luz-text-md- Radius
--luz-radius-md
Teclado y ARIA están en la pestaña Código.