Saltar al contenido principal

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

Esta traducción la ha escrito una IA y todavía no la ha revisado ninguna persona. Leer esta página en inglés

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: John Young’s Lunar Salute on Apollo 16

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:consent indica lo retirado en detail.withdrawn.
  • No se ha probado con un lector de pantalla.

Código

Copiar el marcado

Bundler
import "@luz-ds/catalog/components/embed.css";
HTML
<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.

HTML
<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:

JS
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 atributoEfecto
<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__link
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__play con los mismos hijos, así que su nombre no cambia
.luz-embed__poster, .luz-embed__title
Tu imagen, que cubre el marco, y el título, sobre un velo en la parte inferior
.luz-embed__ask 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 autoplay y 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, en localStorage como {"version":1,"expires":…,"asked":[…],"granted":[…],"given":"…"}, fusionado en el registro que ya hay para que se conserven las categorías del aviso, emite luz:consent en document y 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, allow para las funciones que usan los reproductores, allowfullscreen y referrerpolicy="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

Do Di qué pasa con cada respuesta: quién aloja el vídeo y qué conoce si lo reproduces, y da a «Reproducir» y «No reproducir» el mismo peso.
Don't Preguntar con «OK» y «Cancelar»: nadie sabe si OK carga el vídeo o acepta otra cosa.

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.

ParteColor sobre el fondoClaroOscuroAlto contrasteMí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-ring alrededor 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.

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.