Adding CSS Styles
Because the <video>
element is standard HTML, you can modify its appearance and behavior using CSS styles. You can modify the opacity, add a border, position the element dynamically on the page, and much more. You can also use CSS styles to enhance elements that interact with audio or video, such as custom controllers and progress bars. In addition, you can listen for media events in JavaScript and change the properties of other website elements in response.
This chapter illustrates some methods of adding CSS styles to video, as well as how to modify the style of non-video elements in response to media events. For more information on using CSS styles in Safari, see Safari CSS Visual Effects Guide, Safari Graphics, Media, and Visual Effects Coding How-To's, and Safari CSS Reference.
Changing Styles in Response to Media Events
You can use JavaScript to modify the style of website elements in response to media events. For example, you could update a music playlist and highlight the name of the song currently being played. The example in Listing 5-1 changes the webpage styles when a movie is playing—darkening the background and fading the rest of the webpage by making it partly transparent—then restores things when the movie is paused or completes. Figures III-1 and III-2 show the webpage with the movie playing and paused.
The example listens for the playing
, pause
, and ended
events. When the playing
event fires, a function stores the current background color, sets the background color to black, and sets the opacity of the rest of the page to 0.25. When the pause
or ended
event fires, a second function restores the background color and sets the opacity to 1.
Note that the <style>
section of the page sets the webkit-transition-property
and webkit-transition-duration
for the background color and opacity, so these properties change smoothly over a few seconds instead of changing abruptly. The background color and opacity change work in any HTML5-compliant browser, but the gradual state change happens only in Safari and other WebKit-based browsers.
Alternatively, you could set a JavaScript timer and darken the background and reduce the page opacity incrementally over several steps.
Listing 5-1 Dim the lights
<!doctype html> |
<html> |
<head> |
<title>Dim the Lights</title> |
<script type="text/javascript"> |
var restoreColor; |
function dimLights() { |
restoreColor = document.body.style.backgroundColor; |
var theBody = document.body; |
theBody.style.backgroundColor = "black"; |
var theRest = document.getElementById("restofpage"); |
theRest.style.opacity = 0.25; |
} |
function lightsUp() { |
var theBody = document.body; |
theBody.style.backgroundColor = restoreColor; |
var theRest = document.getElementById("restofpage"); |
theRest.style.opacity = 1; |
} |
function addListener() { |
var myVideo = document.getElementsByTagName('video')[0]; |
myVideo.addEventListener('playing', dimLights, false); |
myVideo.addEventListener('pause', lightsUp, false); |
myVideo.addEventListener('ended', lightsUp, false); |
} |
</script> |
<style> |
body { |
background-color: #888888; |
color: #ffdddd; |
text-shadow: 0.1em 0.1em #333; |
-webkit-transition-property: background-color; |
-webkit-transition-duration: 4s; |
} |
#restofpage { |
color: #ffffff; |
width: 640px; |
-webkit-transition-property: opacity; |
-webkit-transition-duration: 4s; |
} |
</style> |
</head> |
<body onload="addListener()"> |
<div align="center"> |
<h1>Dim the Lights, Please</h1> |
<video id="player" controls |
src="http://homepage.mac.com/qt4web/myMovie.m4v"> |
</video> |
<div id="restofpage"> |
<h3 style="color:#ffdddd;" > |
This webpage uses HTML5 video, JavaScript, DOM events, and CSS. |
</h3> |
<p> |
When the video starts playing, a DOM event is fired, and a JavaScript |
function "dims the lights" by fading the webpage background color |
to black and lowering the opacity of the rest of the page. |
</p> |
<p> |
When the video pauses or ends, another event is fired and a second |
JavaScript function brings the lights back up. |
</p> |
<p> |
Try it! |
</p> |
</div> |
</div> |
</body> |
</html> |
Adding CSS Styles to Video
You can use CSS to apply styles to the video element itself. For example, you can change the video opacity, position the video on top of another element, or add a border.
Example: Setting Opacity
To allow elements under the video to show through, set the opacity of the video. Opacity has a range from 0 (completely transparent) to 1 (completely opaque). You can set opacity directly in CSS—applying it to video generally, or to a class of video, or to a particular video element:
Declaring the opacity of the video
element: video { opacity: 0.5 }
Declaring the opacity of a class: .seeThroughVideo { opacity: 0.3 }
Declaring the opacity of an element using its ID: #theVideo { opacity: 0.7 }
To change video opacity dynamically, use JavaScript. You can address the video element by ID or tag name, and you can set the opacity property either directly or by changing the element’s class name to a class with a style applied to it.
The following code snippet declares the opacity of a class. The snippet then defines a JavaScript function that sets a video element’s classname to the declared class. A second JavaScript function illustrates setting the opacity of a video element directly, instead of changing the classname.
<style> |
.seeThroughVideo { opacity: 0.3 } |
</style> |
<script type="text/javascript"> |
function makeSeeThrough() { |
document.getElementById("theVideo").className = "seeThroughVideo"; |
} |
function setOpacityDirectly (val) { |
document.getElementsByTagName("video")[0].style.opacity = val; |
} |
</script> |
Using WebKit Properties
In addition to the standard CSS properties, you can apply WebKit properties to video in Safari or other WebKit-based browsers. WebKit properties are prefixed with -webkit-
. Many CSS properties begin as WebKit properties, are proposed as CSS standards, and go through review before becoming standardized. When and if a WebKit property becomes a standard property, -webkit-
is dropped from the name. The -webkit-
prefixed version is maintained for backward compatibility, however.
You can safely add CSS properties that have the -webkit-
prefix to your webpages. WebKit-based browsers, such as Safari and Chrome, recognize these prefixed properties. Other browsers just ignore them. Use CSS properties with the -webkit-
prefix to enhance general websites, but verify that your site still looks good using other browsers, unless your site is Safari-specific or designed solely for iOS devices.
Four noteworthy WebKit properties are filters, masks, reflections, and 3D rotation. These CSS properties are available to other HTML elements as well, not just videos.
Adding a Filter
Safari 6 and later supports CSS filters, or special visual effects, that you can apply to many elements, including videos (see Figure 5-3). These hardware-accelerated filters (such as brightness, contrast, saturation, and blur) can be stacked on top of and animated against one another. Read CSS Property Functions in Safari CSS Reference to find out more about CSS filters.
The video above has a hue-rotation and saturation, as described in Listing 5-2.
Listing 5-2 Applying CSS filters to HTML elements
<!doctype html> |
<html> |
<head> |
<title>Filters</title> |
<style> |
video { |
float: left; |
width: 50%; |
} |
.filtered { |
-webkit-filter: hue-rotate(180deg) |
saturate(200%); |
} |
</style> |
</head> |
<body> |
<h1>Video with and without CSS filters</h1> |
<p>The video on the left does not have CSS filters applied, while the video on the right does.</p> |
<p>These videos are playing from the same source file.</p> |
<video src="shuttle.m4v" autoplay></video> |
<video src="shuttle.m4v" autoplay class="filtered"></video> |
</body> |
</html> |
Adding a Mask
You can make a video element appear non-rectangular or discontinuous by masking part of the video out using -webkit-mask-box-image
. Specify an image to use as a mask. The mask image should have the same dimensions as the video, be opaque where you want the video to show, and be transparent where you want the video to be hidden. Making areas of the mask semi-opaque makes the corresponding areas of the video proportionally semi-transparent.
The following example uses CSS to position a video over the image of a porthole, then masks the video with a circular image so the movie appears to be seen through the porthole.
<!doctype html> |
<html> |
<head> |
<title>porthole</title> |
</head> |
<body> |
<h1>Video with Filters</h1> |
<p> |
Video is saturated and blurred with CSS filters. |
</p> |
<img src="porthole.jpg" width="430" height="365"> |
<video src="myMovie.m4v" autoplay |
style="position:relative; top:-325px; |
-webkit-mask-box-image: url(portholemask.png);"> |
</video> |
</body> |
</html> |
Adding a Reflection
Add a reflection of a video using the -webkit-box-reflect
property. Specify whether the reflection should appear on the left, right, above, or below the video, and specify any offset space between the video and the reflection. The following snippet adds a reflection immediately below the video.
<video src="myMovie.m4v" autoplay style="-webkit-box-reflect: below 0px;"> |
If you set the controls
attribute, the video controls will also appear mirrored in the reflection. Since the mirrored controls are backwards and nonfunctional, this is not usually what you want. Video reflections are best used with a JavaScript controller.
You can mask out part of the reflection by including the url of a mask image. The following example adds a masked reflection below the video.
<!doctype html> |
<html> |
<head> |
<title>Reflection with Mask</title> |
<script type="text/javascript"> |
function playPause() { |
var myVideo = document.getElementById('theVideo'); |
if (myVideo.paused) |
myVideo.play(); |
else myVideo.pause(); |
} |
</script> |
</head> |
<body align="center" style = "background-color: 404040"> |
<h1 style="color:#ffeeee"> |
Reflection with Mask |
</h1> |
<input type="button" value="Play/Pause" onclick="playPause()"> |
<BR><BR> |
<video src = "myMovie.m4v" id = "theVideo" |
style = "-webkit-box-reflect: below 0px url(mask.png);"> |
</video> |
</body> |
</html> |
You can specify a gradient instead of an image to mask the reflection. The following snippet creates a gradient that fades to transparency.
<video style="-webkit-box-reflect: below 0px
-webkit-gradient(linear, left top, left bottom, from(transparent), to(black));">
Because the gradient is reflected, it is specified from transparent to black—its reflection goes from black to transparent. Because the gradient is a mask, only its opacity matters. It could also be specified from transparent to white.
The following snippet adds a color-stop to the gradient, causing it to reach transparency at four-tenths of its length.
<video style="-webkit-box-reflect: below 0px
-webkit-gradient(linear, left top, left bottom, from(transparent), to(black),
color-stop(0.4, transparent));">
Rotating Video in 3D
You can use WebKit CSS properties to rotate video around the x or y axis. Rotating the video 180° allows the user to see it playing from “behind”. Rotating the video 90° causes it to play edge-on, making it invisible and revealing whatever is behind it. Rotation can be set statically using CSS or dynamically using JavaScript. The following snippet sets the video rotation at 45° about the y axis.
<video style="-webkit-transform: rotateY(45deg);" src="myVideo.m4v" controls>
Dynamic rotation is best used in conjunction with the webkit-transition
property. Setting webkit-transition
causes the video element to rotate smoothly over a specified duration, without having to set JavaScript timers or stepper functions. You set the transition property, specify the duration, and any time you change the specified property, the change is animated smoothly over the specified duration. The property to animate for rotation is -webkit-transform
. When the animation completes, a webkitTransitionEnd
event is fired.
The following snippet sets the transition property to -webkit-transform
and sets the animation duration to 4 seconds.
<video src="myVideo.m4v" controls |
style="-webkit-transition-property: -webkit-transform; |
-webkit-transition-duration: 4s"> |
You can add perspective to the rotation, so that parts of the video element closer to the viewer along the z axis appear larger, and parts further away appear smaller. To add perspective, set the -webkit-perspective
property of one of the video element’s parents, such as a parent div
or the document body.
Listing 5-3 dynamically flips a playing video 180° around its y axis, intermittently revealing the text behind the video. The video has perspective when it rotates, due to the -webkit-perspective
property of the body
element.
Listing 5-3 3D rotation with perspective
<!doctype html> |
<html> |
<head> |
<title>Video Flipper</title> |
<style> |
video { |
-webkit-transition-property: -webkit-transform; |
-webkit-transition-duration: 4s; |
} |
body { -webkit-perspective: 500; } |
</style> |
<script type="text/javascript"> |
var flipped = 0; |
function flipper() { |
if (flipped) |
myVideo.style.webkitTransform = "rotateY(0deg)"; |
else |
myVideo.style.webkitTransform = "rotateY(180deg)"; |
flipped = !flipped ; |
} |
</script> |
</head> |
<body> |
<h1>Video Flipper</h1> |
<p>Text hidden behind the video.</p> |
<div style="position:relative; top:-40px;"> |
<video src="myMovie.m4v" id="myVideo" autoplay controls> |
</video> |
<input type="button" value="Flip Video" onclick="flipper()"> |
</div> |
</body> |
</html> |
Copyright © 2012 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2012-12-13