On-Demand Embedded Videos

Reduce Initial-Load Page Weight With On-Demand Videos

Embedded videos from 3rd-party platforms like Vimeo and YouTube are a great way to include videos on your website, but can add more than 500KB of page weight even when they're not clicked/played. This technique replaces a placeholder image and link to the video (which doubles as a no-JS fallback) with the embedded video when clicked.

Live Example

HTML

Start with a link and thumbnail image, wrapped in a container with the video ID stored as a data attribute.

HTML
<div class="video" data-videoid="VIDEO ID">
    <a href="https://www.youtube.com/watch?v=VIDEO ID" target="_blank" rel="noreferrer nofollow">
        <img src="https://img.youtube.com/vi/VIDEO ID/sddefault.jpg" width="WIDTH" height="HEIGHT" alt="VIDEO TITLE" loading="lazy">
    </a>
</div>

CSS

Style the placeholder image link as desired, including a custom play button. This setup also uses a technique for responsive embedded videos that scale with a custom aspect ratio.

CSS
.video {display:block;padding-bottom:56.25%;background-color:#111;box-shadow:0 0 0 1px #f9f9f9, 0 0 0 2px #ccc;position:relative;margin:0 0 1.5rem;overflow:hidden} /*--- bottom (or top) padding sets aspect ratio ---*/

        /*--- iframe (when loaded) ---*/
        .video iframe {border:0;position:absolute;width:100%;height:100%}

        /*--- placeholder link ---*/
        .video a {display:block}

            /*--- play button ---*/
            .video a::before {box-sizing:border-box;display:block;height:1em;width:1em;background-color:rgba(0,0,0,0.6);border:.05em solid #fff;border-radius:50%;box-shadow:0 0 0.15em 0 rgba(0,0,0,0.6);position:absolute;top:50%;left:50%;z-index:1;font-size:3em;margin:-.5em 0 0 -.5em;transition:background-color .2s;content:""}
            .video a:hover::before, .video a:focus::before {background-color:#2b9a27}
            	.video a::after {display:block;width:0;height:0;border:0 solid transparent;border-width:.2em 0 .2em .3em;border-left-color:#fff;position:absolute;top:50%;left:50%;z-index:1;font-size:3em;margin:-.2em 0 0 -.1em;content:""}

            /*--- preview image ---*/
            .video img {display:block;position:absolute;top:-16.82%;width:100%}
    }

JavaScript

Replace the image link with a normal embedded video <iframe> when the placeholder is clicked.

JavaScript
// select all .video elements
var videos = document.querySelectorAll('.video');

for (var i = 0; i < videos.length; i++) {
    videos[i].addEventListener('click', function() {
        var iframe = document.createElement('iframe');
        iframe.setAttribute('allowfullscreen', 'allowfullscreen');
        iframe.setAttribute('src', 'https://www.youtube.com/embed/'+ this.dataset.videoid +'?autoplay=1');
        iframe.setAttribute('allow', 'autoplay');
        this.innerHTML = '';
        this.appendChild(iframe);
        event.preventDefault();
    });
};

Minified:

JavaScript
var videos = document.querySelectorAll('.video'); for (var i = 0; i < videos.length; i++) { videos[i].addEventListener('click', function() { var iframe = document.createElement('iframe'); iframe.setAttribute('allowfullscreen', 'allowfullscreen'); iframe.setAttribute('src', 'https://www.youtube.com/embed/'+ this.dataset.videoid +'?autoplay=1'); iframe.setAttribute('allow', 'autoplay'); this.innerHTML = ''; this.appendChild(iframe); event.preventDefault(); }); };

Without JavaScript

This sans-JavaScript alternative is more limited in features and browser support, but similarly avoids loading the full embedded video resources until the user clicks the play button. The srcdoc attribute supersedes the regular src attribute in browsers that support it.

HTML
<div class="video">
    <iframe src="https://www.youtube.com/embed/VIDEO ID?rel=0&autoplay=1" srcdoc="<style>*{display:block;padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:-1px;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.2em black}</style><a href='https://www.youtube.com/embed/VIDEO ID?rel=0&autoplay=1'><img src='https://img.youtube.com/vi/VIDEO ID/sddefault.jpg' alt='Video Title Goes Here' loading='lazy'><span>▶</span></a>" allow="autoplay" allowfullscreen title="Video Title Goes Here" loading="lazy"></iframe>
</div>