Responsive Video Light-box with Lity

This tutorial shows you how to make an elegant & responsive YouTube pop-up light-box. Instead of just using the standard WordPress block to embed a YouTube video, we’ll use the Lity JavaScript library to pop the video to a fully responsive video player.

You don’t need to add any new plugins to your WordPress site. All you need is a custom child theme so we can add a bit of PHP and JavaScript to make it work.

Basically, we need a PHP file on the server to implement a custom shortcode. We need the open source Lity library (a free download) and we need to create a bit of CSS to polish it off. If you’re not experienced at coding, it might sound like hard work, but…

…all we’re going to do is create a single PHP function, add a couple of CSS definitions, and use the Lity JavaScript library to do all the hard work.

Adventure Motorcycling in Central Mexico

A pop-out video player

Getting Started

We’ll start by sorting-out our files, and we’ll put a placeholder function in there so we can test things. In your custom child theme’s main folder, create a new file called simple-video-lightbox.php and paste the following into it.

<?php

// Block direct access.
if (!defined('WPINC')) {
	exit('Do NOT access this file directly.');
}

function do_shortcode_svl_youtube($params) {
	// We'll replace this with the proper code later.
	$html = '<strong>Light-box in here</strong>';

	return $html;
}
add_shortcode('svl_youtube', 'do_shortcode_svl_youtube');

infoOur function begins with “svl_“, which stands for “Simple Video Light-Box”.

We also need a folder where we can add our supporting files, so make a sub-folder in your custom child theme called simple-video-lightbox. Next, go to the Lity website and download the current version. Extract the zip file and go into the “dist” (distributable) folder and you’ll see several files. We only need the minified JS & CSS files, so copy lity.min.css and lity.min.js into the new simple-video-lightbox sub-folder.

Grab a copy of the YouTube play button SVG file, save it into the sub-folder, and rename it to youtube-play-button.svg.

Create an empty CSS file in the sub-folder called svl-frontend.css.

Finally, we need to tell our custom child theme to use our new code, so open your custom child theme’s functions.php file and add the following into it.

simple video light-box asset files
Asset files for our Simple Video Light-box project
/**
 * Simple Video Light-box shortcode and other assets.
 */
require_once 'simple-video-lightbox.php';

OK, that should be enough to tell WordPress that we’ve created a new shortcode called svl_youtube, so let’s see if it works.

Edit a page or a post, create a shortcode block and add the new shortcode with a “url” parameter pointing to a YouTube video. Save your content and view it. If everything’s working properly, you should see the text “Light-box in here” rendered when you want your video to be.

example video lightbox shortcode
Simple Video Light-box shortcode block

Render the Shortcode

Now the “scaffolding” is in place, we can add the code to render the proper HTML. We’re going to create an outer div container, which will wrap a thumbnail image that we can grab from YouTube (based on the video URL). Update your simple-video-lightbox.php file with the following.

<?php

/**
 * Create a shortcode to render YouTube video thumbnails that pop-out into a
 * responsive video player.
 *
 * https://wp-tutorials.tech/add-functionality/responsive-video-light-box/
 */

// Block direct access.
if (!defined('WPINC')) {
	exit('Do NOT access this file directly.');
}

function do_shortcode_svl_youtube($params) {
	global $svl_have_assets_been_queued;

	$video_url = null;
	$video_ref = null;
	if (isset($params['url']) && !empty($params['url'])) {
		$video_url = $params['url'];

		$url_parts = parse_url($video_url);
		parse_str($url_parts['query'], $query_args);
		if (isset($query_args['v']) && !empty($query_args['v'])) {
			$video_ref = $query_args['v'];
		}
	}

	$image_url = null;
	$image_width = 480;
	$image_height = 360;
	if (!empty($video_ref)) {
		$image_url = sprintf('https://img.youtube.com/vi/%s/0.jpg', $video_ref);
	}

	$alt = null;
	if (isset($params['alt']) && !empty($params['alt'])) {
		$alt = $params['alt'];
	}

	// Render the shortcode.
	$html = '';
	if (!empty($video_ref)) {
		$html .= '<div class="svl-container">';
		$html .= sprintf('<a href="%s" title="%s" data-lity>', esc_url($video_url), esc_attr($alt));
		$html .= sprintf(
			'<img src="%s" width="%d" height="%d" alt="%s" />',
			esc_url($image_url),
			$image_width,
			$image_height,
			esc_attr($alt)
		);
		$html .= '</a>';
		$html .= '</div>'; // .svl-container

		// Add the CSS & JS assets to the footer.
		if (is_null($svl_have_assets_been_queued)) {
			$base_url = get_stylesheet_directory_uri() . '/' . pathinfo(__FILE__, PATHINFO_FILENAME) . '/';
			$theme_version = wp_get_theme()->get('Version');

			// Lity
			wp_enqueue_style('lity', $base_url . 'lity.min.css', null, '2.4.1');
			wp_enqueue_script('lity', $base_url . 'lity.min.js', array('jquery'), '2.4.1', true);

			// Our assets
			wp_enqueue_style('svl-frontend', $base_url . 'svl-frontend.css', null, $theme_version);

			$svl_have_assets_been_queued = true;
		}
	} else {
		// No video ref found, so do nothing.
	}

	return $html;
}
add_shortcode('svl_youtube', 'do_shortcode_svl_youtube');

This might seem like a bit of a chunk but it breaks-down quite nicely. The parameters for our shortcode come through in $params so we need to pull the YouTube URL, and possibly an SEO-friendly image alt tag for our thumbnail image.

  1. Check $params for a “url” parameter. If we find one, look for the YouTube video reference (v=xxxxxxxxxx) and extract it into $video_ref
  2. If $video_ref has something in it then create a URL to fetch the video thumbnail from YouTube, which we can use to render an <img> element
  3. Check $params for an “alt” parameter and extract it, if it exists
  4. Start building-up a string called $html to hold the front-end HTML
    1. Open our <div> container element with the class “svl-container”
    2. Open the <a> element and specify the data-lity prop. This is what makes Lity do its magic for us
    3. Render the video thumbnail <img> element
    4. Close the <a> element
    5. Close the <div> container element
  5. If we haven’t already queued the Lity assets (and our CSS file), queue them now. Notice that Lity depends on jquery.
  6. Return $html so that WordPress can do whatever it needs with it

That should be enough to “make it work”. Save your changes, reload your content and you should see your video thumbnail. Click on it – it should open the video light-box and play 😎

What if it Didn’t Work…

  • If you don’t see a video thumbnail, check your YouTube URL is correct and that the video reference is specified with “v=xxxxxxxxxx”
  • The thumbnail shows OK, but clicking on it takes you to the YouTube page instead of showing the pop-out light-box.
    • Check your browser’s JavaScript console to see if it was unable to load the lity.min.js file for some reason.

Adding Some Style

We’ve now got a working shortcode for playing YouTube videos, but it’s not obvious that the image is a video – it just looks like an image. So let’s put a Play button over the image with some CSS. Paste the following into your svl-frontend.css file..

/**
 * Simple Video Light-box
 */

.svl-container {
	position:  relative;
}

.svl-container > a {
	display:  block;
	border:  1px solid lightgrey;
	box-shadow: 0 0 1.00em rgba( 0, 0, 0, 0.20 );
	border-radius:  0.35em;
	overflow: hidden;
}

.svl-container > a:hover {
	box-shadow: 0 0 1.00em rgba( 0, 0, 0, 0.40 );
}

.svl-container > a img {
	width:  100%;
	object-fit:  cover;
}

.svl-container > a::before {
	content: url( 'youtube-play-button.svg' );
	position:  absolute;
	left:  50%;
	top:  50%;
	width:  4rem;
	height:  3rem;
	transform: translate(-50%, -50%);
	transition: 0.3s;
	opacity: 0.85;
}

.svl-container > a:hover::before {
	opacity: 1.00;
}

The CSS is pretty straightforward – easy to hack it about to suit your needs.

Wrapping it Up

I think it’s nicer to have videos embedded like this, rather than with the oEmbed YouTube stuff, because it avoids using an iFrame. iFrames were a bad idea back in the 2000s, and they’re still a bad idea now. So there.

Now that you’ve got 100% control of the HTML, you can really milk it for SEO. Try extending this code a bit …

  • Set the aria-label property of the <a> element for better accessibility.
  • Add a semi-transparent overlay caption with the title of your video.
  • Sprinkle some custom JavaScript mojo over it to render some cool mouse-over effects.
  • Check out the Lity website for more info too, because it’s not just limited to showing YouTube videos. Our Responsive Masonry Gallery Tutorial also uses Lity to… show a masonry image gallery.

Have fun adding video thumbnails all over your WordPress site! 👍

Leave a Comment

Your email address will not be published. Required fields are marked *