Adding Image and Video Headers to Your WordPress Themes

Reading Time: 3 minutes

Video headers are becoming more and more of a trend in websites. Especially as backgrounds. I’ll leave the debate as to whether that’s a good or bad thing up to others.

The fact is that if you do any form of client work on the web you’ll probably need to implement a video header at some point. You may as well implement it the WordPress way.

Adding Theme Support for Video Headers

WordPress introduced video headers in version 4.7. This takes care of a lot of the dirty work such as performance and accessibility considerations.

If your theme already supports header images you’ll just need to add the video parameter and set it to true in your add_theme_support( ‘custom-header’ ) function. If you don’t already support custom headers that can be done with the following code:

function prefix_custom_header_setup() {
    add_theme_support( 'custom-header', array(
        'video' => true
    ) );
add_action( 'after_setup_theme', 'prefix_custom_header_setup' );

For a more in depth look at custom headers check out the Theme Handbook on Custom Headers.

Performance Considerations

Video is a bandwidth hog. Especially when autoplayed as a background. WordPress knows this and the video header theme support will only display the video on screens larger than 900px wide and 500px tall. It also caps the video upload at 8mb. Although it’s recommended to go much smaller.

By default the video headers will only display on the front page too. But if needed elsewhere that can be by creating a custom callback for the video-active-callback and using the is_header_video_active filter.

From the perspective of your site’s bandwidth you can also use videos from YouTube instead of hosting and serving the video yourself. A definite consideration for keeping your bandwidth in check.

Accessibility Considerations

Video headers are cool, but did you realize they could disorient or distract some users of your site?

To battle that, when video headers are added to your site a play and pause button is also output.

Displaying the Header in Your Site with the_custom_header_markup()

When WordPress introduced video headers they also added in the_custom_header_markup() which can be used to display both images and video. All with one nifty function.

If you’re using a video or image header, the_custom_header_markup() will output a div with the class wp-custom-header containing a img, video, or iframe. This is useful for styling the output which we’ll be getting into shortly. But first you’ll drop the_custom_header_markup() in your theme where you want your image or video header output. Probably within your header.php.

Styling The Header Output

Styling the header markup can be a little tricky because you want to make sure things look good across various screen sizes.

Position fixed vs absolute

Using position fixed on your background is going to create a pseudo parallax effect1 where the image or video will stay in place as the user scrolls. Absolutely positioning your header will make the image or video scroll with the rest of the page.

CSS to fit the screen

Here’s a block of code I’m using on my Aurora theme for background images. Repurposed from twentyseventeen.

.wp-custom-header video,
.wp-custom-header img,
.wp-custom-header iframe {
      position: fixed;
        height: auto;
        left: 50%;
        max-width: 1000%;
        min-height: 100%;
        min-width: 100%;
        min-width: 100vw; /* vw prevents 1px gap on left that 100% has */
        width: auto;
        top: 50%;
        padding-bottom: 1px; /* Prevent header from extending beyond the footer */
        -ms-transform: translateX(-50%) translateY(-50%);
        -moz-transform: translateX(-50%) translateY(-50%);
        -webkit-transform: translateX(-50%) translateY(-50%);
        transform: translateX(-50%) translateY(-50%);

@supports ( object-fit: cover ) {
    .wp-custom-header video,
    .wp-custom-header img,
    .wp-custom-header iframe {
        height: 100%;
        left: 0;
        -o-object-fit: cover;
        object-fit: cover;
          top: 0;
          -ms-transform: none;
          -moz-transform: none;
          -webkit-transform: none;
          transform: none;
          width: 100%;

First we’re setting the position of the img, video, and iframe to a fixed position.

We’re then setting the top and left values to 50%. Then using the transform X and Y properties to -50% to vertically and horizontally center our media.

The final block of code wrapped in the @supports statement is only applied to browsers that support the object-fit property. This is a newer addition to CSS that lets us make sure our media fits the container it’s in. So in this block we’re overwriting the top, left, and transform values since we don’t need to reposition the element.


Implementing custom media headers is extremely easy if you follow the WordPress best practices. And it will also give you tools to keep your site optimized and accessible.

  1. Pseudo because only one item is moving instead of both at different rates.

Pin It on Pinterest