Safari Reference Library Apple Developer
Search

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 reflection, rotate the video in three dimensions, 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.

Note: You may want to create your own stylish movie controller‚Äîincluding a progress bar and a time scrubber‚Äîthat slides smoothly out of the way when not in use. To see an example of just that, download the ConcertDemo sample code from http://developer.apple.com/safari/library/samplecode/HTML5VideoPlayer/index.html. The sample code contains complete HTML, JavaScript, CSS, and video.

This chapter illustrates some methods of adding CSS styles to video, as well as how to add a styled progress bar and play/pause button. 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.

Adding CSS Styles to Video

The example in Listing 3-1 shows how to rotate video in three dimensions, hide and reveal content underlying the video, and change the opacity to composite video over a background. All the changes can be applied dynamically while the video is playing. The example uses a combination of HTML, CSS, and JavaScript to achieve these effects. Each part is explained individually in the following sections.

The Example HTML Code

In the body of the document, the example first defines content to go under the video:

       <div id="back">
       <p style="position:relative;top:50%;" align="center">
       This is hidden behind the video
       </p>
       </div>

The content is a div element just a little smaller than the video with text centered horizontally and vertically.

The example then adds the video, inside a div element named “overlay”:

       <div id="overlay" >
       <video class="video-player" id="player"
              height="348" width="680" controls
              src="myMov.mp4"
        >
       </video>

Because the overlay is declared after the background, CSS naturally puts it in the layer above the background if they overlap later.

Finally, the example adds buttons to flip the video, reveal the hidden content, and fade the video in or out by changing its opacity, along with a button that displays the current opacity:

     <input type=button value="flip backward" onclick="flipVideo()"
                       id="flipflop">
     <input type=button value="show back" onclick="toggleBack()"
                       id="backer">
     <input type=button value="fade out" onclick="fadeTo(0)">
     <input type=button value="fade mid" onclick="fadeTo(.5)">
     <input type=button value="fade in" onclick="fadeTo(1)">
     <input type=button value="opacity: 100%" id="showfade">
     </div>

The “overlay” div element is then closed—it includes the buttons and the video, so the buttons stay with the video when they are repositioned.

The Example CSS Styles

In the style section of the head, the example sets the background content to the size of the video, gives it a background color, and makes it hidden:

    #back{
      height:330px;
      width:670px;
      background-color:gray;
      visibility:hidden; }

The example then positions the div containing the video and buttons at the top of the page (with a 5-pixel pad for aesthetics), covering the background content:

    #overlay{
     position:absolute;
     top:5px; }

Finally, the example adds styles to the video itself. First it adds a background color. Then it specifies that any change in the webkit-transform or opacity properties should be animated by specifying them in webkit-transition-property. The animation timing is set to start gradually (ease in) and take one second to complete:

    #player {
     background-color:black;
     -webkit-transition-property: -webkit-transform, opacity;
     -webkit-transition-timing-function: ease-in;
     -webkit-transition-duration: 1s; }

The CSS style declarations begin with # because they are each applied to a single element, based on its unique id attribute. Style declarations that begin with a dot (for example .back) are applied based on the class attribute, which multiple elements may share.

The Example JavaScript Functions

The JavaScript section of the head defines three functions: flipVideo(), toggleBack(), and fadetTo(val).

The flipVideo() function rotates the video in 3D, flipping it 180° around the vertical axis by setting the style.webkitTransform property to rotateY(0deg), or rotateY(180deg). Because the function is a toggle, it checks the button text to see what it should do—flip forward or flip backward—then changes the text of the button to show what it does next time.

         function flipVideo() {
           var myVideo = document.getElementById('player');
           var myButton = document.getElementById('flipflop');
           if (myButton.value=="flip backward"){
             myVideo.style.webkitTransform = "rotateY(180deg)";
             myButton.value="flip forward";
           }else{
             myVideo.style.webkitTransform = "rotateY(0deg)";
             myButton.value="flip backward";
     } }

The toggleBack() function also rotates the video in 3D, this time 90° around the vertical axis, so it is edge-on to the viewer and therefore invisible. It also changes the style.visibility property of the background content from hidden to visible. Because the function is a toggle, it then changes the text of the button from “show back” to “hide back”. When called again, it resets the Y rotation to 0° and sets the background content back to hidden:

         function toggleBack() {
           if (myButton.value=="show back"){
             myVideo.style.webkitTransform = "rotateY(90deg)";
             myButton.value="hide back";
             backContent.style.visibility="visible";
            }else{
             myVideo.style.webkitTransform = "rotateY(0deg)";
             myButton.value="show back";
             backContent.style.visibility="hidden";
          } }

The fadeTo(opacityVal) function takes one parameter: the desired opacity value. It sets the video’s style.opacity property to that value and changes the text in a button to display the current opacity as a percent.:

          function fadeTo(opacityVal) {
            document.getElementById('player').style.opacity=opacityVal;
            var showPercent= ("opacity "+ (opacityVal * 100) + "%");
            document.getElementById('showfade').value= showPercent;
          }

Notice that JavaScript is not used to animate the effects on the video. JavaScript just changes the style property values. The animation parameters are specified in CSS and the effects are rendered automatically.

Code Example: Adding Style to Video

Listing 3-1 is a complete working example, incorporating all the material in the previous three section, illustrating how to combine HTML, CSS, and JavaScript to add style to video dynamically.

Listing 3-1  Adding dynamic 3D rotation, hiding, and opacity to video

<!DOCTYPE html>
<html>
  <head>
    <title>Flipping and Fading Video</title>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
 
    <style>
 
    #back{
      height:330px;
      width:670px;
      background-color:gray;
      visibility:hidden;
      }
 
    #overlay{
     position:absolute;
     top:5px;
     }
 
    #player {
     background-color:black;
     -webkit-transform:rotateY(0deg);
     -webkit-transition-property: -webkit-transform, opacity;
     -webkit-transition-duration: 1s;
     -webkit-transition-timing-function: ease-in;
     }
 
    </style>
 
    <script type="text/javascript">
 
         function flipVideo() {
           var myVideo = document.getElementById('player');
           var myButton = document.getElementById('flipflop');
           if (myButton.value=="flip backward"){
             myVideo.style.webkitTransform = "rotateY(180deg)";
             myButton.value="flip forward";
           }else{
             myVideo.style.webkitTransform = "rotateY(0deg)";
             myButton.value="flip backward";
           }
         }
 
         function toggleBack() {
           var backContent=document.getElementById('back');
           var myVideo = document.getElementById('player');
           var myButton = document.getElementById('backer');
           if (myButton.value=="show back"){
             myVideo.style.webkitTransform = "rotateY(90deg)";
             myButton.value="hide back";
             backContent.style.visibility="visible";
            }else{
             myVideo.style.webkitTransform = "rotateY(0deg)";
             myButton.value="show back";
             backContent.style.visibility="hidden";
            }
           }
 
          function fadeTo(opacityVal) {
            document.getElementById('player').style.opacity=opacityVal;
            var showPercent= ("opacity "+ (opacityVal * 100) + "%");
            document.getElementById('showfade').value= showPercent;
          }
 
    </script>
 
  </head>
  <body style="background-color:#C0C0C0;">
       <div id="back">
       <p style="position:relative;top:50%;" align="center">
       This is hidden behind the video
       </p>
       </div>
       <div id="overlay">
       <video id="player"
              height="348" width="680" controls
              src="myMov.m4v"
        >
       </video>
       <br>
     <input type=button value="flip backward" onclick="flipVideo()"
                       id="flipflop">
     <input type=button value="show back" onclick="toggleBack()"
                       id="backer">
     <input type=button value="fade out" onclick="fadeTo(0)">
     <input type=button value="fade mid" onclick="fadeTo(.5)">
     <input type=button value="fade in" onclick="fadeTo(1)">
     <input type=button value="opacity: 100%" id="showfade">
     </div>
  </body>
</html>

Adding a Styled Progress Bar

As shown in “Using DOM Events to Monitor Load Progress,” it’s fairly easy to monitor the movie loading process and show what percentage has downloaded using JavaScript alone. By integrating CSS styles, you can create a real progress bar.

The following example, Listing 3-2, creates a div element named video-player whose height is the height of the video plus the progress bar. It puts the video element inside the video-player, then adds a background bar by creating a nested div element and styling it with a size, color, and shadow. Inside the bar it adds a partly transparent progress indicator, positioning it on top of the background bar but setting its width to 0%. Because the bar and progress indicator are inside the video-player element, they inherit its width. That way when the progress indicator’s width goes from 0 to 100%, it grows to the width of the video. The progress indicator is translucent, so the background bar shows through.

A listener function on the progress event updates the width property of the progress indicator. An installer function installs the listener and is called on page load.

Listing 3-2  Adding a styled progress bar

<!DOCTYPE html>
<html>
  <head>
    <title>Styled Progress Bar</title>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
 
    <style>
    #video-player {
     width: 680px;
     height: 366px;
     background-color: black;
     }
    #background-bar {
     height: 18px;
     width: 680px;
     background-color: #D4D4D4;
    -webkit-box-shadow: 0px 2px 4px rgba(0,0,0,0.8);
    }
    #loader {
    height: 18px;
    width: 1%;
    opacity:.25;
    background-color: blue;
    }
    </style>
 
    <script type="text/javascript">
    function showLoad() {
    var myVideo = document.getElementsByTagName('video')[0];
    var soFar = parseInt(((myVideo.buffered.end(0) / myVideo.duration) * 100));
    myLoader=document.getElementById("loader");
    myLoader.style.width=(soFar + '%');
    }
 
    function myAddListener() {
    var myVideo = document.getElementsByTagName('video')[0];
    myVideo.addEventListener('progress',showLoad,false);
    }
 
    function playVideo() {
    var myVideo = document.getElementsByTagName('video')[0];
    myVideo.play();
    }
 
    </script>
 
  </head>
  <body onload="myAddListener()" >
      <div id="video-player">
       <video height="348" width="680" autoplay
        src="http://homepage.mac.com/qt4web/myMovie.m4v"
        >
       </video>
       <br>
       <div id="background-bar">
         <div id="loader">
         </div>
       </div>
     <div>
       <p> </p>
       <input type="button" value="play" onclick="playVideo()">
     </div>
  </body>
</html>

Note that the previous example includes a simple JavaScript play button. If the controls attribute is omitted and no JavaScript controls are provided, a user on the iPad has no way to play the movie.

Adding A Styled Play/Pause Button

The final example, Listing 3-3, creates a video-player element that surrounds the video with a black background and puts a play/pause button under the video, centered horizontally. The play/pause button is styled with 24-point white text on a dark grey background, at 50% opacity.

When the user presses the play/pause button, it plays or pauses the movie. It also toggles the button’s value between “>” and “||”. The opacity is set to 50% when the video is paused and 20% when it’s playing, so the button is less distracting from the playing video.

Finally, a call to reset the play/pause button is added as an event listener to the video element’s ended event.

Listing 3-3  Adding a styled play/pause button

<!DOCTYPE html>
<html>
  <head>
    <title>Styled Play/Pause Button</title>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
 
    <style>
    #video-player {
     width:50%;
     margin-left:25%;
     margin-right:25%;
     background-color: black;
     }
 
   #videobutton {
    line-height: 24pt;
    border: 3px solid white;
    -webkit-border-radius: 16px;
    opacity: 0.5;
    font-size: 24pt;
    color: white;
    background-color: #404040;
    cursor: pointer;
    text-align: center;
    z-index: 1;
    opacity:.5;
    }
 </style>
 
 <script type="text/javascript">
 
         function pauseButton() {
             var myButton = document.getElementById("videobutton");
                myButton.value = "||";
                myButton.style.opacity=".2";
            }
 
         function playButton() {
             var myButton = document.getElementById("videobutton");
                myButton.value = ">";
                myButton.style.opacity=".5";
            }
 
         function playPause() {
              var myVideo = document.getElementsByTagName('video')[0];
              if (myVideo.paused) {
                myVideo.play();
                pauseButton();
              }else{
             myVideo.pause();
             playButton();
            }
         }
 
         function myAddListener() {
         var myVideo = document.getElementsByTagName('video')[0];
         myVideo.addEventListener('ended',playButton,false);
         }
 
</script>
</head>
 
<body onload="myAddListener()">
  <div id="video-player">
     <video src="http://homepage.mac.com/qt4web/myMovie.m4v"
            height="270" width="480">
     </video>
     <P align=center>
     <input id="videobutton" type=button onclick="playPause()" value="&gt;">
     </p>
  </div>
  </body>
</html>



Last updated: 2010-03-18

Did this document help you? Yes It's good, but... Not helpful...