Video elements only allow one image as the poster, which is not optimal for performance. This JavaScript plugin uses a standard image element as the poster which allows the use of responsive image techniques. This also gives full styling control of video placeholders.
Performance optimizations are also included for loading of both native and embedded videos. Third-party embedded videos are lazy loaded when the user interacts with the video.
The default setup for the plugin.
The picture element is used for the poster. The poster is the last frame of the video.
Embedded video from third-party sites e.g. Youtube, Vimeo, etc. The poster is the middle frame of the video.
$ npm install responsive-video-poster --save-dev
The script is an ES6(ES2015) module but the compiled version is included in the build as "src/scripts/responsive-video-poster-umd.js". You can also copy "src/scripts/responsive-video-poster.js" into your own site if your build process can accommodate ES6 modules.
import ResponsiveVideoPoster from 'responsive-video-poster';
const responsiveVideoPosterDefault = ResponsiveVideoPoster({
selector: '#responsive-video-poster--default'
});
Property | Default | Type | Description |
---|---|---|---|
selector |
'.responsive-video-poster' | String or Element | Container element selector. |
overlaySelector |
'.video-overlay' | String | Overlay element selector. |
posterSelector |
'.poster' | String | Poster element selector. |
videoSelector |
'.video' | String | Video element selector. |
animClass |
'is-anim' | String | CSS class to transition the video overlay between states. |
inactiveClass |
'is-inactive' | String | CSS class to hide the video overlay. |
playDelay |
0 | Integer(ms) or 'transition' | Delay playing the video by set time or wait for the overlay transition to finish. |
hideControlsOnLoad |
false | Boolean | Hide video controls while transitioning overlay. |
preConnections |
[] | Array | Domains to pre-connect to for loading an embedded video. |
Property | Type | Description |
---|---|---|
instance.playVideo() |
Method | Plays the video. |
instance['elements'] |
Object | Returns the elements used by this instance. |
@import "node_modules/responsive-video-poster/src/styles/responsive-video-poster.scss";
The demos makes use of the padding technique to maintain aspect ratio. Only one aspect ratio of 16:9 is used in the demos. You can add your own or use classes provide by frameworks such as Bootstrap.
<div class="responsive-video-poster responsive-video-poster--16by9">
<button class="video-overlay" aria-label="Play video">
<div class="poster-btn"><svg class="poster-btn-icon"> ... </svg></div>
<img srcset="images/720/image.jpg 720w, images/1080/image.jpg 1080w" src="images/1080/image.jpg" class="poster">
</button>
<video src="videos/video.mp4" preload="metadata" class="video" controls></video>
</div>
<div class="responsive-video-poster embed-responsive embed-responsive-16by9">
...
</div>
<div class="responsive-video-poster ratio ratio-16x9">
...
</div>
Responsive image techniques(srcset, sizes, source, etc) are used to load the most appropriate image. Native lazy loading is used on the responsive poster image to reduce initial page load. The plugin should also work normally with lazy load plugins.
The video element includes preload="metadata" so the video is not loaded until the user interacts with it. This will reduce the initial page load but may create lag in playback for some users. This can be removed if not needed.
The embedded video includes srcdoc="" so the video and third-party scripts are not loaded until the user interacts with it. The 'preConnections' option can be used to pass domains to start pre-connect connections for loading an embedded video. this happens when the user hovers/taps on the video using the pointerover event. For example Youtube could use ['https://www.youtube.com', 'https://www.google.com'].
A 'playVideo' event is started once a user clicks the video overlay. The event is ended once the overlay has become inactive and the video starts playing.
document.querySelector('#responsive-video-poster--default').addEventListener('playVideo', (event) => {
console.log(`Action: ${event.detail.action}`);
});
You can also attach this to the document.
document.addEventListener('playVideo', (event) => {
console.log(`Target: ${event.target.matches('#responsive-video-poster--default')}`, `Action: ${event.detail.action}`);
});
Supports all modern browsers (Firefox, Chrome, Safari and Edge) released as of April 2020.
Clone or download from Github.
$ npm install
$ gulp serve