Video icon 64
Want to be a web designer? Skill up fast with video courses from Tuts+. Start your free trial.
Advertisement

Skin Orman Clark's Video Interface Using jPlayer and CSS

by
Student iconAre you a student? Get a yearly Tuts+ subscription for $45 →
This post is part of a series called Bringing Premium Pixels to Life.
Quick Tip: Give Orman's Navigation the :target Treatment
Menu Notification Badges Using HTML5 Data-Attributes

Coding up Orman Clark's Premium Pixel designs is great fun, this time we'll have a look at his Video Player Interface! We'll build it using an awesome HTML5 video library called jPlayer along with some HTML and CSS.


Step 1: HTML5 Base Markup

We'll start off by throwing together a blank HTML5 document, while remembering to source jQuery in the head (I'm using jQuery hosted by Google). I'll also link to the latest HTML shiv which will ensure Internet Explorer interprets and styles HTML5 elements correctly.

One last thing, you'll note that I've linked to a stylesheet too, we'll add the CSS later on in the tutorial.

<!DOCTYPE>
<html>
	<head>

		<!--Meta tags-->
		<meta charset="utf-8">

		<!--Title-->
		<title></title>
		
		<!--Stylesheets-->
		<link rel="stylesheet" href="css/styles.css">

		<!--jQuery-->
		<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
		
		<!--[if lt IE 9]>
        	<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
    	<![endif]-->
	
	</head>
<body>

</body>
</html>

Step 2: Download jPlayer

Next we'll need to download jPlayer "The jQuery HTML5 Audio / Video Library". Head on over to jplayer.org and download the current release.

jPlayer Files

Go ahead and create a folder named "javascript" or "js" (or whatever you're accustomed to) in your web folder and copy jquery.jplayer.min.js into it. Next you'll need to link to this in your HTML, so add the following in your <head> section (remembering to change the path as appropriate).

<!--jPlayer-->
<script src="js/jquery.jplayer.min.js"></script>

Step 3: Player Markup

We'll now add the markup we need to create the player. Don't worry if it appears overwhelming, most of this is taken from demos on the jplayer.org site and I'll explain all that's necessary later on.

<!--container for everything-->
<div id="jp_container_1" class="jp-video jp-video-360p">

	<!--container in which our video will be played-->
	<div id="jquery_jplayer_1" class="jp-jplayer"></div>
	
	<!--main containers for our controls-->
	<div class="jp-gui">
		<div class="jp-interface">
			<div class="jp-controls-holder">
			
	
			
			</div><!--end jp-controls-holder-->
		</div><!--end jp-interface-->
	</div><!--end jp-gui-->
	
	<!--unsupported message-->
	<div class="jp-no-solution">
		<span>Update Required</span>
		Here's a message which will appear if the video isn't supported. A Flash alternative can be used here if you fancy it.
	</div>
	
</div><!--end jp_container_1-->

Firstly, you'll see a main container for everything. We'll apply some global styles to that. Then there's the div "#jquery_jplayer_1" which the jPlayer script will target and add the video to (you'll see this id referenced in the jQuery function when we add that).

You really only need to concern yourself with whatever's inside the <div class="jp-gui"> tags. This is the main section which will contain the video controls. We'll create another couple of containers within it which all help with resizing depending on whether full screen is on or off.


Step 4: Controls Markup

Now for the good stuff..

<!--play and pause buttons-->
<a href="javascript:;" class="jp-play" tabindex="1">play</a>
<a href="javascript:;" class="jp-pause" tabindex="1">pause</a>
<span class="separator sep-1"></span>

<!--progress bar-->
<div class="jp-progress">
    <div class="jp-seek-bar">
        <div class="jp-play-bar"><span></span></div>
    </div>
</div>

<!--time notifications-->
<div class="jp-current-time"></div>
<span class="time-sep">/</span>
<div class="jp-duration"></div>
<span class="separator sep-2"></span>

<!--mute / unmute toggle-->
<a href="javascript:;" class="jp-mute" tabindex="2" title="mute">mute</a>
<a href="javascript:;" class="jp-unmute" tabindex="2" title="unmute">unmute</a>

<!--volume bar-->
<div class="jp-volume-bar">
    <div class="jp-volume-bar-value"><span class="handle"></span></div>
</div>
<span class="separator sep-2"></span>

<!--full screen toggle-->
<a href="javascript:;" class="jp-full-screen" tabindex="3" title="full screen">full screen</a>
<a href="javascript:;" class="jp-restore-screen" tabindex="3" title="restore screen">restore screen</a>

Here we've added our controls, all commented for clarity. To kick off, our play button followed by the pause button. These are both given suitable class names for styling later on. Next, we have a span with a class of 'separator'. Orman used some nifty little separators in the design, since these are separators with a gradient on them we'll use an image for these (though feel free to use CSS3 gradients if you're confident).

Next we create the progress bar and there are a few elements which go in to building this. First we have 'jp-progress' which is the base of the progress bar. Next we have 'jp-play-bar'. This is the cool red bar which scrolls across signifying progress of the video. Note we also use a span with a class of 'handle' here to create the little knob shown in the design.

Now for the current time and duration of the video. We'll create these once again using divs, with the classes 'jp-current-time' and 'jp-duration'. Note we also used another span class again, this time to create another separator but using a forward slash so no images will be used here. After that lot you'll see we have another separator, same as previously.

The volume buttons and bar then need to be made. First we'll create two buttons, 'jp-mute' and 'jp-unmute'. Only one of these will be displayed at a time, the other will be hidden with jPlayer. The volume bar has the same principles as the progress bar, same structure (though different class names, obviously).

If you view the file in the browser you won't see too much happening yet.

jPlayer Markup

Step 5: Adding a Video

Now the main part, we'll add a video! For full functionality and cross-browser support you'll need your video available in multiple formats. HTML5 media formats supported by jPlayer are:

  • mp3
  • mp4 (AAC/H.264)
  • ogg (Vorbis/Theora)
  • webm (Vorbis/VP8)
  • wav

Various browsers support different video formats; the relevant format will be selected depending on the browser providing it's been made available. Check out caniuse.com for more information on who, what and where.

We'll also need a .png file which acts as a poster for when the movie isn't playing.

For the purpose of this tutorial I'm using a movie trailer downloaded from http://trailers.apple.com. I then converted it into the correct formats (there are plenty of free online resources to help you out here, Google away..)

So once you've converted them and created your .png poster place them somewhere appropriate in your project. After that we'll need to add an instantiation snippet to get jPlayer up and running.

Add the following to the foot of your document remembering to change the file paths to reflect your own. You'll see that we're pointing jPlayer to the "#jquery_jplayer_1" element.

<!--instantiate-->
<script type="text/javascript">
$(document).ready(function(){

	$("#jquery_jplayer_1").jPlayer({
		ready: function () {
			$(this).jPlayer("setMedia", {
				m4v: "mi4.m4v",
				ogv: "mi4.ogv",
				webmv: "mi4.webm",
				poster: "mi4.png"
			});
		},
		swfPath: "js",
		supplied: "webmv, ogv, m4v",
		size: {
			width: "570px",
			height: "340px",
			cssClass: "jp-video-360p"
		}
	});

});
</script>

Check out the jPlayer documentation for more options and attributes. OK, you should have something similar to this:

Video Added

Step 6: Video Base CSS

Before we get into adding some CSS for the control interface we'll add a background, fonts etc. to the body and also the styles for the base of the video. Go ahead and create a stylesheet, remembering to link to it in the head section of your webpage. I've also thrown in a reset just incase your browser decides to add some margins and whatnot!

After the reset rules I've added a background with an image. Next I've targeted the whole player (the video and controls), I've given it a font-family and added some box-shadows (while remembering to use the browser prefixes!). We've then given it styles for when the player is in full screen mode.

html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,and,address,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video,input,textarea,select{background:transparent;border:0;font-size:100%;margin:0;outline:0;padding:0;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}abbr[title],dfn[title]{border-bottom:1px dotted;cursor:help}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:none}del{text-decoration:line-through}hr{background:transparent;border:0;clear:both;color:transparent;height:1px;margin:0;padding:0}mark{background-color:#ffffb3;font-style:italic}input,select{vertical-align:middle}ins{background-color:red;color:white;text-decoration:none}ol,ul{list-style:none}table{border-collapse:collapse;border-spacing:0}a{text-decoration:none;}

body {
	margin:0;
	padding:0;
	background:url("bg.jpg") repeat;
}

.jp-video {
	font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;
	position:relative;

	-webkit-box-shadow:0px 0px 20px rgba(0,0,0,.3);
	-moz-box-shadow:0px 0px 20px rgba(0,0,0,.3);
	box-shadow:0px 0px 20px rgba(0,0,0,.3);
}
.jp-video-360p {
	width:570px;
	margin: 100px auto;
}
.jp-video-full {
	width:480px;
	height:270px;
	position:static !important; 
	position:relative
}
.jp-video-full .jp-jplayer {
	top: 0;
	left: 0;
	position: fixed !important; position: relative; /* Rules for IE6 (full-screen) */
	overflow: hidden;
	z-index:1000;
}

.jp-video-full .jp-gui {
	position: fixed !important; position: static; /* Rules for IE6 (full-screen) */
	top: 0;
	left: 0;
	width:100%;
	height:100%;
	z-index:1000;
}
.jp-video-full .jp-interface {
	position: absolute !important; position: relative; /* Rules for IE6 (full-screen) */
	bottom: 0;
	left: 0;
	z-index:1000;
}

You should now have something similar to the following:

Video Base CSS

Step 7: Basic Controls Styling

Time to start styling up the controls section! We'll first style the base gray part. We'll use a fluid-width of 100%, this is used so it'll stretch to full width when in full screen mode. I've also added a fixed height of 35px. Next we'll use a gradient for the background, I went ahead and created this using GradientApp and then cleaned it up using the Prefixr API.

Finally I've added a box-shadow to create the inset shadows, once again remembering to use the browser prefixes. I've next added some styles for the controls holder (basically a container), allowing us to center the control panel when in full screen mode. You'll see how this works later on. I've used a fixed width of 570px and centered it using margin: 0 auto;

.jp-interface {
	position: relative;
	width:100%;
	height: 35px;

	background-image: -webkit-linear-gradient(top, rgb(242, 242, 242), rgb(209, 209, 209));
	background-image: -moz-linear-gradient(top, rgb(242, 242, 242), rgb(209, 209, 209));
	background-image: -o-linear-gradient(top, rgb(242, 242, 242), rgb(209, 209, 209));
	background-image: -ms-linear-gradient(top, rgb(242, 242, 242), rgb(209, 209, 209));
	background-image: linear-gradient(top, rgb(242, 242, 242), rgb(209, 209, 209));
	filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#f2f2f2', EndColorStr='#d1d1d1');

	-webkit-box-shadow:
		inset 0px 1px 0px #f7f7f7,
		inset 0px -1px 0px #e2e2e2;
	-moz-box-shadow:
		inset 0px 1px 0px #f7f7f7,
		inset 0px -1px 0px #e2e2e2;
	box-shadow:
		inset 0px 1px 0px #f7f7f7,
		inset 0px -1px 0px #e2e2e2;
}

div.jp-controls-holder {
	clear: both;
	width:570px;
	margin: 0 auto;
	
	position: relative;
	overflow:hidden;
}

You shouldn't see much change since the last step except for the gradient background we've just added:

Controls Base Styling

Step 8: Play and Pause Buttons

Next we'll add the play and pause buttons, along with the separator. I'll be using a sprite for all the buttons, which you can grab in the source files.

I've first defined a width and height for both the pause and play buttons, they'll both have the same dimensions. Next I've added a text-indent to push any text within the anchor links off the screen as we don't need them, we'll be using the sprite image. Finally we'll use outline:none; which will fix a problem when clicking, preventing some browsers showing a horrid blue glow around the button.

a.jp-play,
a.jp-pause {
	width:40px;
	height:35px;
	float:left;
	text-indent:-9999px;
	outline:none;
}

a.jp-play {
	background: url("sprite.png") 0 0 no-repeat;
}

a.jp-pause {
	background: url("sprite.png") -40px 0 no-repeat;
	display: none;
}

.separator {
	background-image:url("separator.png");
	background-repeat:no-repeat;
	width: 2px;
	height: 35px;
	float:left;
	margin-top: 7px;
	margin-right: 10px;
}

Step 9: Progress Bar

Okay, first we'll target the progress bar base. We'll give it a solid background, add a border-radius of 5px (with the prefixes), two box-shadows, a drop shadow and an inset shadow. Next we'll add some widths and heights, both fixed. We'll then add some margin-top just to center it within the whole interface.

Next we'll add some styles for the seeking bar which shows how much the video has loaded. We'll apply a width of 0px because jPlayer will handle the actual width dynamically, and a height of 100% so it will inherit the progress bar height, filling it all up. We'll also give it the border radius of 5px and a background.

Lastly we'll create the progress bar which moves as the video plays. I'll be using an image and repeating it on the y-axis. Once again, as previously we'll add a width of 0px and jPlayer will handle the rest. Next, remember that span tag we created? This will be used for the handle. We'll be using an image for this too, and position it absolutely. We'll need to use right:XXpx; to ensure it moves along with the play bar.

.jp-progress {
	background: #706d6d;

	-webkit-border-radius:5px;
	-moz-border-radius:5px;
	border-radius:5px;

	-webkit-box-shadow:
		inset 0px 1px 4px rgba(0,0,0,.4),
		0px 1px 0px rgba(255,255,255,.4);
	-moz-box-shadow:
		inset 0px 1px 4px rgba(0,0,0,.4),
		0px 1px 0px rgba(255,255,255,.4);
	box-shadow:
		inset 0px 1px 4px rgba(0,0,0,.4),
		0px 1px 0px rgba(255,255,255,.4);

	width:280px;
	height:10px;
	float:left;
	margin-top: 13px;
}

.jp-seek-bar {
	width:0px;
	height:100%;
	cursor: pointer;
}

.jp-seeking-bg {
	background:#575555;
	-webkit-border-radius:5px;
	-moz-border-radius:5px;
	border-radius:5px;
}

.jp-play-bar {
	background: url("play-bar.png") left repeat-x;
	width:0px;
	height:10px;
	position:relative;
	z-index: 9999;
	
	-webkit-border-radius:5px;
	-moz-border-radius:5px;
	border-radius:5px;
}

.jp-play-bar span {
	position:absolute;
	top: -3px;
	right: -12px;

	background:url("handle.png") no-repeat center;
	width: 16px;
	height: 17px;
}
Progress Bar

Step 10: Current Time / Duration

Time to do time (snigger) Seriously though, let's style up the current time and duration. We'll target them both first to apply some styles they'll share. The rest is basic stuff like margins.

.jp-current-time,
.jp-duration {
	font-size:11px;
	font-family:Arial;
	color:#444444;
	margin-top: 12px;
	float:left;
}
.jp-current-time {
	float: left;
	display:inline;
}
.jp-duration {
	float: left;
	display:inline;
	text-align: right;
}
.jp-video .jp-current-time {
	margin-left:10px;
}
.jp-video .jp-duration {
	margin-right:10px;
}
.time-sep {
	float:left;
	margin: 13px 3px 0 3px;

	font-size:11px;
	font-family:Arial;
	color:#444444;
}

Step 11: Volume Buttons and Bar

We're not far from completion now, so let's handle the volume section. We'll need two buttons, the mute and unmute. We'll apply some styling to both and then the sprite to each one individually.

Note we've used outline:none; again to avoid that problematic active state. To create the volume bar we'll use a similar process to the progress bar. We'll apply a fixed width and height, give it a background, some box shadows and a border radius of 5px. The volume bar itself is transparent so we won't apply a background to it. Next we have another knob; using a span again we'll apply a background image, use position:absolute; and position it to the right so it'll move correctly.

.jp-video a.jp-mute,
.jp-video a.jp-unmute {
	text-indent:-9999px;
	float:left;
	
	height: 35px;
	outline:none;
}

.jp-mute {
	float:left;
	background: url(../images/sprite.png) -80px 0 no-repeat;
	margin-top: 1px;
	margin-left: -10px;
	width: 35px;
}

a.jp-unmute {
	background: url(../images/sprite.png) -115px 0 no-repeat;
	margin-top: 1px;
	margin-left: -13px;
	display: none;
	width: 38px;
}

.jp-volume-bar {
	float:left;
	margin-top: 13px;
	margin-right: 10px;
	overflow:hidden;
	width:70px;
	height:10px;
	cursor: pointer;

	background: #706d6d;

	-webkit-border-radius:5px;
	-moz-border-radius:5px;
	border-radius:5px;

	-webkit-box-shadow:
		inset 0px 1px 4px rgba(0,0,0,.4),
		0px 1px 0px rgba(255,255,255,.4);
	-moz-box-shadow:
		inset 0px 1px 4px rgba(0,0,0,.4),
		0px 1px 0px rgba(255,255,255,.4);
	box-shadow:
		inset 0px 1px 4px rgba(0,0,0,.4),
		0px 1px 0px rgba(255,255,255,.4);
}

.jp-volume-bar-value {
	background: transparent;
	width:0px;
	height:10px;
	position: relative;
}

.jp-volume-bar-value span {
	position:absolute;
	top: 0px;
	right: 0px;

	background:url(../images/volume.png) no-repeat center;
	width: 11px;
	height: 10px;
}

Step 12: Full Screen Button

We're on the last step now! All we have left is the full screen button. Using similar steps as before, we'll apply the sprite again, use text-indent to hide the text (also known as pushing-it-off-the-screen). And remembering to use outline:none; again (which admittedly could be applied to all anchors at the beginning of the stylesheet).

.jp-full-screen {
	background: url(../images/sprite.png) -150px 0 no-repeat;
	float:left;
	width: 40px;
	height: 35px;
	text-indent:-9999px;
	margin-left: -15px;
	outline:none;
}

.jp-restore-screen {
	background: url(../images/sprite.png) -150px 0 no-repeat;
	float:left;
	width: 40px;
	height: 35px;
	text-indent:-9999px;
	margin-left: -15px;
	outline:none;
}

And our video player is complete!

Completed Normal Screen Size

Go ahead and try the full screen feature, it's awesome!

Completed Full Screen Size

Conclusion

By using the jPlayer plugin and Orman's delightful design, we've coded up a pixel perfect video player interface. Don't forget, jPlayer has many more tricks up its sleeve, so make sure you check out the demos and documentation. I hope you enjoyed this tutorial, thanks for reading.

Completed Normal Screen Size
Advertisement