<div class="rtds-video ">
<button type="button" class="rtds-video__play rtds-group">
<span class="rtds-video__play-icon rtds-btn rtds-btn--icon rtds-w-16 rtds-h-16 rtds-text-white rtds-cursor-pointer rtds-rounded-full rtds-border-4">
<svg class="rtds-icon rtds-fill-current rtds-w-8 rtds-h-8 rtds-transition-all" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#mini--play" />
</svg>
<span class="rtds-sr-only">Riproduci il video: Video youtube: titolo video</span>
</span>
<div class="rtds-video__overlay"></div>
<picture class="rtds-video__overlay-image">
<img class="rtds-object-cover rtds-object-center rtds-w-full rtds-h-full" src="/images/feathers.jpg" alt="" />
</picture>
</button>
<iframe class="rtds-video__iframe rtds-invisible" src="https://www.youtube.com/embed/mkggXE5e2yk?si=dqKsArDWXeMSAXnZ" title="Video youtube: titolo video" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
</div>
<div class="rtds-video{% if aspectRatio %} {{ aspectRatio }}{% endif %} {% if containerClasses %} {{ containerClasses }}{% endif %}">
<button type="button" class="rtds-video__play rtds-group">
<span class="rtds-video__play-icon rtds-btn rtds-btn--icon rtds-w-16 rtds-h-16 rtds-text-white rtds-cursor-pointer rtds-rounded-full rtds-border-4">
{% render '@icon--small', { id: 'mini--play', classes: 'rtds-transition-all', size: 'rtds-w-8 rtds-h-8' }, true %}
<span class="rtds-sr-only">Riproduci il video: {{ videoTitle }}</span>
</span>
<div class="rtds-video__overlay"></div>
{% if overlayImage %}
<picture class="rtds-video__overlay-image{% if aspectRatio %} {{ aspectRatio }}{% endif %}">
<img class="rtds-object-cover rtds-object-center rtds-w-full rtds-h-full" src="{{ overlayImage }}" alt="{{ overlayImageAlt }}" />
</picture>
{% endif %}
</button>
<iframe class="rtds-video__iframe{% if aspectRatio %} {{ aspectRatio }}{% endif %} rtds-invisible" src="{{ videoSrc }}" title="{{ videoTitle }}" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
</div>
{
"title": "video",
"videoSrc": "https://www.youtube.com/embed/mkggXE5e2yk?si=dqKsArDWXeMSAXnZ",
"overlayImage": "/images/feathers.jpg",
"overlayImageAlt": "",
"videoTitle": "Video youtube: titolo video"
}
/* Video player custom Component */
.rtds-video {
position: relative;
aspect-ratio: 16 / 9;
}
.rtds-video__iframe {
aspect-ratio: 16 / 9;
width: 100% !important;
}
.rtds-video__overlay {
position: absolute;
top: var(--spacing-0);
right: var(--spacing-0);
bottom: var(--spacing-0);
left: var(--spacing-0);
z-index: 10;
background-color: rgb(0 0 0 / var(--tw-bg-opacity, 1));
--tw-bg-opacity: 0.2;
transition-property: all;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
}
.rtds-group:hover .rtds-video__overlay {
--tw-bg-opacity: 0.4;
}
.rtds-video__overlay-image {
display: block;
height: 100%;
width: 100%;
-o-object-fit: cover;
object-fit: cover;
-o-object-position: center;
object-position: center;
}
.rtds-video__play {
position: absolute;
top: var(--spacing-0);
right: var(--spacing-0);
bottom: var(--spacing-0);
left: var(--spacing-0);
z-index: 20;
width: 100%;
transition-property: all;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
}
.rtds-video__iframe:focus-visible,
.rtds-video__play:focus-visible {
--tw-shadow: 0 0 0 7px rgba(255,255,255,1);
--tw-shadow-colored: 0 0 0 7px var(--tw-shadow-color);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
outline: 2px solid transparent;
outline-offset: 2px;
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
--tw-ring-color: var(--color-focusring);
--tw-ring-offset-width: 2px;
--tw-ring-offset-color: #ffffff;
}
.rtds-video__play-icon {
position: absolute;
top: 50%;
left: 50%;
z-index: 20;
--tw-translate-x: -50%;
--tw-translate-y: -50%;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
background-color: var(--color-background-primary);
}
/* Video player custom Component */
@layer components {
.rtds-video {
@apply rtds-aspect-video rtds-relative;
}
.rtds-video__iframe {
@apply rtds-aspect-video !rtds-w-full;
}
.rtds-video__overlay {
@apply rtds-absolute rtds-z-10 rtds-top-0 rtds-right-0 rtds-bottom-0 rtds-left-0 rtds-bg-black rtds-bg-opacity-20 group-hover:rtds-bg-opacity-40 rtds-transition-all;
}
.rtds-video__overlay-image {
@apply rtds-object-cover rtds-object-center rtds-block rtds-w-full rtds-h-full;
}
.rtds-video__play {
@apply rtds-transition-all rtds-absolute rtds-top-0 rtds-right-0 rtds-bottom-0 rtds-left-0 rtds-z-20 rtds-w-full;
}
.rtds-video__iframe,
.rtds-video__play {
@apply focus-visible:rtds-ring focus-visible:rtds-ring-offset-2 focus-visible:rtds-ring-offset-white focus-visible:rtds-ring-focusring focus-visible:rtds-shadow-[0_0_0_7px_rgba(255,255,255,1)] focus-visible:rtds-outline-none;
}
.rtds-video__play-icon {
@apply rtds-absolute rtds-z-20 rtds-top-1/2 rtds-left-1/2 -rtds-translate-x-1/2 -rtds-translate-y-1/2 rtds-background-primary;
}
}
/* VIDEO SCRIPT
* Manage cover and video play
*/
document.addEventListener('DOMContentLoaded', function () {
'use strict';
// Selezionare tutti gli elementi videoContainer sulla pagina
var videoContainers = document.querySelectorAll('.rtds-video');
console.log('Video containers trovati:', videoContainers.length);
// Iterare su ogni videoContainer trovato
videoContainers.forEach(function (videoContainer) {
var playButton = videoContainer.querySelector('.rtds-video__play');
var videoIframe = videoContainer.querySelector('.rtds-video__iframe');
function viewVideo() {
// Nascondi il pulsante play che contiene anche l'overlay
playButton.style.display = 'none';
videoIframe.classList.remove('rtds-invisible');
videoIframe.setAttribute('tabindex', '0');
videoIframe.focus();
// Aggiungi autoplay al src dell'iframe solo se non è già presente
if (!videoIframe.src.includes('autoplay=1')) {
videoIframe.src += (videoIframe.src.includes('?') ? '&' : '?') + 'autoplay=1';
}
}
if (playButton) {
playButton.addEventListener('click', viewVideo);
// listener per keydown per l'accessibilità
playButton.addEventListener('keydown', function(e) {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
viewVideo();
}
});
}
});
});
Componente per l’incorporamento di video YouTube con pulsante play personalizzato e immagine di anteprima sovrapposta. L’iframe viene reso visibile solo dopo l’attivazione del pulsante play.
Livello AA — criteri pertinenti:
rtds-sr-only con il titolo del video; l’immagine overlay ha alt descrittivotype="button" e testo accessibile<div class="rtds-video"> — wrapper presentazionale<button type="button"> — elemento nativo interattivo, accessibile da tastieratitle="" — attributo obbligatorio per identificare il contenuto agli screen readeralt="" — deve descrivere l’anteprima del video| Attributo | Valori | Condizione |
|---|---|---|
title sull’<iframe> |
valore di videoTitle |
sempre presente |
alt sull’immagine overlay |
valore di overlayImageAlt |
quando overlayImage è presente |
| Tasto | Azione |
|---|---|
Tab |
Porta il focus sul pulsante play |
Enter / Space |
Attiva il pulsante play — avvia il video (gestito da JavaScript) |
:focus-visible è sempre visibile e non viene rimosso via CSS<span class="rtds-sr-only">Riproduci il video: </span> nel pulsante play fornisce nome accessibile al controllortds-invisible — lo screen reader potrebbe comunque rilevarlo; assicurarsi che title sia sempre presentevideoSrc: URL del video YouTube con parametri (es. &controls=2&modestbranding=1&rel=0)overlayImage: percorso immagine di anteprimaoverlayImageAlt: testo alternativo dell’immagine di anteprimavideoTitle: titolo del video (usato in title sull’iframe e nel testo nascosto del pulsante play)aspectRatio: classe aspect ratio del componente (default: rtds-aspect-video)containerClasses: classi CSS aggiuntive per il contenitoreiframeClasses: classi CSS aggiuntive per l’iframe