<div class="video" data-video-inline>
<div class="video__overlay">
<button class="video__play-btn" aria-label="Play Video">
<svg viewBox="0 0 12.86 25.72" role="presentation" aria-hidden="true">
<polygon points="0,0 12.86,12.86 0,25.72"/>
</svg>
</button>
<img src="https://via.placeholder.com/1280x720" srcset="" alt="Sample Alt Text" />
</div>
<div class="video__content">
<iframe src="https://www.youtube.com/embed/-tbjPxtBfhM?enablejsapi=1" frameborder="0" allowfullscreen></iframe>
</div>
</div>
<div class="video" data-video-inline>
<div class="video__overlay">
<button class="video__play-btn" aria-label="Play Video">
<svg viewBox="0 0 12.86 25.72" role="presentation" aria-hidden="true">
<polygon points="0,0 12.86,12.86 0,25.72"/>
</svg>
</button>
<img src="{{ placeholder.src }}" srcset="{{ placeholder.srcset }}" alt="{{ placeholder.alt }}" />
</div>
<div class="video__content">
<iframe src="{{ 'https://www.youtube.com/embed/' ~ youtubeId ~ '?enablejsapi=1'}}" frameborder="0" allowfullscreen></iframe>
</div>
</div>
{
"youtubeId": "-tbjPxtBfhM",
"placeholder": {
"src": "https://via.placeholder.com/1280x720",
"alt": "Sample Alt Text"
}
}
.video {
position: relative;
&__overlay {
z-index: 1;
position: absolute;
top: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
overflow: hidden;
background-color: color(neutral, lightest);
.video--active & {
opacity: 0;
visibility: hidden;
}
img {
position: absolute;
top: 0;
left: 0;
width: 100%;
min-width: 100%;
min-height: 100%;
object-fit: cover;
}
}
&__play-btn {
z-index: 1;
position: relative;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
border: 0;
padding: 0;
width: 90px;
height: 90px;
background-color: color(primary, base);
&:focus,
&:hover {
background-color: color(primary, hover);
cursor: pointer;
}
svg {
// Negative margin here is applied to offest the play icon
// positioning from the center as it aesthetically is too
// left-justified without it
margin-right: -5px;
width: 14px;
height: 28px;
fill: color(neutral, lightest);
}
}
&__content {
position: relative;
// Padding here is used to maintain a perfect aspect ratio
// for video rectangle, making it responsive as it scales
padding-bottom: 56.25%;
max-width: 100%;
height: 0;
overflow: hidden;
iframe,
object,
embed {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
visibility: hidden;
.video--active & {
visibility: visible;
}
}
}
}
// Polyfills
if (window.NodeList && !NodeList.prototype.forEach) {
NodeList.prototype.forEach = Array.prototype.forEach;
}
// Self invoking function to setup API script in the DOM
(function() {
const apiRef = document.createElement('script');
const firstScript = document.getElementsByTagName('script')[0];
apiRef.src = "//www.youtube.com/player_api";
firstScript.parentNode.insertBefore(apiRef, firstScript);
})();
window.onYouTubePlayerAPIReady = function() {
const videos = document.querySelectorAll('[data-video-inline]');
const apiVideos = [];
videos.forEach((video, i) => {
// assign all iframes on the page to a cooresponding YT Player object
apiVideos.push(new YT.Player(videos[i].querySelectorAll('iframe')[0]));
// click event to insert and play youtube video
videos[i].addEventListener('click', function() {
if (!this.classList.contains('video--active')) {
this.classList.add('video--active');
apiVideos[i].playVideo();
}
});
// manually set controls for space bar
// this is neccesary because Youtube keyboard controls are unavailable until
// after manual click on iframe (as opposed to current button)
videos[i].addEventListener('keypress', function(e) {
if (e.keyCode === 32) {
if (apiVideos[i].getPlayerState() == 1) {
apiVideos[i].pauseVideo();
} else {
apiVideos[i].playVideo();
}
}
});
});
};
This video player is setup to specifically work with youtube videos and comes with a data attribute, data-video-inline
, which links the video the the JS video array in the event that there is more than one video on a page.
aria-label
attribute to describe its function.role="presentation"
and aria-hidden="true"
attributes.Enter
or Space
= Play/Pause video