A client using the StudioPress’s Digital Pro theme wanted to replace the front page background image with a background video. This article goes into some of the code changes we made. Just some quick background: Digital Pro theme is a child theme using the Genesis Framework.
The first thing we need to do is determine where in the markup the code for the video should be placed. The current front page image is part of the front-page-1
sidebar. You want to place a ‘Text’ widget in this sidebar with a title and content. We made the title be ‘Digital Pro Theme’ and the content be ‘Show off your work’. Below is what our original and then what our final outcome will be.
We are going to replace the background image with a background video. Actually, we will have problems running video on mobile devices such as iPhones and iPads because Safari prevents any video from autostarting (to prevent downloading large video files and using data). So the best thing to do would be to keep the image but to run the video on top of it if we are on a device that can run video. Let’s place the video then in the same container the image is placed. The image is placed in a div
with class backstretch
under the div
with id front-page-1
. The backstretch
container is positioned absolutely. We can place our video container, positioned absolutely, and give it a z-index higher than backstretch
.
The front page is the only page with this image and it’s code is placed in the template file, front-page.php
Looking through this file I’ve pulled out the pertinent section:
//* Enqueue scripts for backstretch
add_action( 'wp_enqueue_scripts', 'digital_front_page_enqueue_scripts' );
function digital_front_page_enqueue_scripts() {
$image = get_option( 'digital-front-image', sprintf( '%s/images/front-page-1.jpg', get_stylesheet_directory_uri() ) );
//*get the image from options
//* Load scripts only if custom backstretch image is being used
if ( ! empty( $image ) && is_active_sidebar( 'front-page-1' ) ) {
//* Enqueue Backstretch scripts
wp_enqueue_script( 'digital-backstretch', get_bloginfo( 'stylesheet_directory' ) . '/js/backstretch.js', array( 'jquery' ), '1.0.0' );
wp_enqueue_script( 'digital-backstretch-set', get_bloginfo('stylesheet_directory').'/js/backstretch-set.js' , array( 'jquery', 'digital-backstretch' ), '1.0.0' );
wp_localize_script( 'digital-backstretch-set', 'BackStretchImg', array( 'src' => str_replace( 'http:', '', $image ) ) );
}
}
This theme is using two javascript scripts to add the backstretch
div to the markup. The wp_localize_script
gives the scripts the URL to the image.
Now how will we add our video container? There is really not a good hook to add content within a sidebar. One way could be to add a text widget to the sidebar and use a shortcode in the text widget that would call your code. (You would also have to enable shortcodes in widgets for this work). So instead let’s put the video container like this theme does with javascript. Another good reason to use javascript is that we don’t want the video in the DOM while the page is loaded into the client’s browser. The video could be too large and cause the page to render too slow. With javascript we can tell it to load the video after the page has already rendered.
We can follow the same code in front-page.php
to load our video javascript. In this file is a function called digital_front_page_genesis_meta
. We will put the following right after the //* Enqueue scripts for backstretch
section where the digital_front_page_enqueue_scripts
function ends. Right before the //* Add front-page body class
section.
//* Enqueue scripts for video
add_action( 'wp_enqueue_scripts', 'jht_digital_front_page_enqueue_scripts' );
function jht_digital_front_page_enqueue_scripts() {
$site_url = get_site_url();
$video = $site_url . "/wp-content/uploads/2016/08/DMR-15-2.webm";
$video2 = $site_url . "/wp-content/uploads/2016/08/DMR-15-2.mp4";
if ( ! empty( $video ) && is_active_sidebar( 'front-page-1' ) ) {
wp_enqueue_script( 'jht-video', get_bloginfo('stylesheet_directory').'/js/jht-video.js' , array( 'jquery'), '1.0.0', true );
wp_localize_script( 'jht-video', 'jhtVideo', array( 'srcMov' => $video2, 'srcWebm' => $video ) );
}
}
This will load our jht-video.js
file stored in our theme’s js folder. We pass to our script the url’s to different encodings of our video. We uploaded the videos in our media library and then copied the urls and placed them in this code. It’s not the best way, but it is the fastest way. In addition, this video really will not change often. Future enhancements could be to add theme options so the user can select the videos in the dashboard.
Here’s the jht-video.js
file. It’s main function is run after the document is ready. It creates a video container using the javascript variables we added using the php code above, and then it appends the container inside the front-page-1
container.
jQuery(document).ready(function($) {
var myVideo = '';
$(".front-page-1").append(myVideo);
});
Now we should see the video container when we visit the front page in our browser’s development tools. We need to do some styling to allow us to see it on the page properly.
video#bgvid {
display: block;
position: absolute;
left: 0;
height: auto;
width: auto;
min-width: 100%;
min-height: 100%;
max-width: initial;
}
Here we create an absolute positioned block. It is filling the front-page-1
container (whose height is is set by another of the theme’s javascript).
This is a gif that gives an idea of what this will look like except the video is not nearly as smooth. Here’s the link (it’s 600KB in size).
The video is covering our text widget. Let’s add a z-index to move it back behind the text widget. We’ll give it a z-index of -1 which will put it behind the text widget but still in front of the image.
video#bgvid {
...[previous code]
z-index: -1;
}
That works but the text in the text widget is very hard to read when the video has a darkish background. Let’s add some opacity.
video#bgvid {
...[previous code]
z-index: -1;
opacity: 0.4;
}
The opacity definitely brings out the text but also brings out the image from the back.
We need something between the video and the image to keep the image hidden no matter what opacity we use. Above we styled the video
element and that element is wrapped in a div with class video
. Let’s make the video
div absolute, give it a white background, and position it so that it covers the front-page-1
div. Lets also give the video
div the same z-index as the video
element. Since the div contains the video
element, it will automatically be behind the video element.
.front-page-1 .video {
position: absolute;
left: 0px;
right: 0px;
bottom: 0px;
overflow: hidden;
top: 0px;
background-color: #fff;
z-index: -1;
}
That looks much better.
Here’s an animated gif to show it a little better (256KB in size).
Are we done? Well, if you look at the site in an iPad, Android, or iPhone, the video will not automatically run. In these cases we want the image to show. We will use media queries to hide the video container when the device screen are smaller than a certain size.
@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) {
/* all iPads */
.front-page-1 .video {
display: none;
}
}
@media only screen and (max-width: 768px) {
/* tablet or mobile device */
.front-page-1 .video {
display: none;
}
}
Note: The height of the front-page-1
container is determined by a simple javascript. It sets the height by determining window height and subtracting the height of the header. This keeps only the front-page-1
container and the header showing when you first access the page. It also determines the height if the screen size changes. Without this javascript the front-page-1
container would only be as high as the text widget. Click here to see example (98KB).