Tag: Video

The New CSS-Tricks Video Intro by dina Amin

You know we do video screencasts, right? It’s not, like, super regular, but I have done them for a long time, still like doing them, and plan to keep doing them. I publish them here, but you can subscribe over on YouTube as well.

I’ve had a couple of different custom video intro animations over the years, always done by someone far more handy with that kind of thing than I am. When I asked around in May this year, I got some good leads, but none better than Matthias paging Marc, and then Marc helping me out with an introduction to dina Amin.

One look at dina’s work and it’s an obvious: yes! She does stop-motion and a lot of breakin’ stuff:

Just one small example, check out the show reel too!

We chatted back and forth, scoping out the project. She says:

I worked together with Assem Kamal on a new intro for CSS-Tricks YouTube channel. We wanted to make something very short yet interesting so that audiences on YouTube don’t skip the intro or get bored if they watch a couple of CSS-Tricks videos back to back.

She researched and asked a bunch of questions. I like how she was very aware of the role an intro like this plays in a video, especially tutorials. Can’t be too long. Can’t be annoying in any way. It has to have enough detail that it’s almost fun to see multiple times.

The old video started with a keyboard:

We started with an Apple keyboard, because we wanted to keep something from the original intro that Chris’ audience would relate to, and most importantly because I wanted to take the keyboard apart!

“Did we cut up that keyboard?!” Yes, we did. It was too easy to find multiple broken Apple keyboards, it’s a very well-engineered product and it all comes together beautifully with minimum parts, but only Apple can fix this product. You can’t just get your screw kit out and open this up and fix one flawed button connection. So a lot of these keyboards are thrown away because it’s too expensive to fix in countries like Egypt. We got our hands on three keyboards and we cut up one as we animated and used different keyboard buttons from the other two to make the buttons stretch.

It was fun seeing some behind-the-scenes stuff in her Instagram Stories:

And another connection from the original is the idea of websites as components and building out layouts. That was just referenced in the original with some background sketches and now comes to life with paper prototypes in this version.

We thought of showing the ‘how to make a website’ process in very abstract steps where each step quickly transitions and transforms into the other. Starting with keyboard clicks that turn into code, then design blocks that make up a website, which scrolls to reveal the CSS-Tricks logo.

It’s all done quite literally with stop motion! Hand moving bits around, taking photos, and making those into video.

Once we got the concept approved and our props ready, we spent hours and hours moving little pieces to make all this magic.

Check out a time lapse of the creation!

Ultimately, I got a number of versions in different aspect ratios and sizes, which is wonderful as I can switch it up and use different ones that might be more appropriate in different scenarios. Here’s the main one!

I’ve already been putting these on the start and end of videos like this one.

Thanks, dina and Assam!

The post The New CSS-Tricks Video Intro by dina Amin appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.


, , , ,

Some Innocent Fun With HTML Video and Progress

The idea came while watching a mandatory training video on bullying in the workplace. I can just hear High School Geoff LOL-ing about a wimp like me have to watch that thing.

But here we are.

The video UI was actually lovely, but it was the progress bar that really caught my attention – or rather the [progress].value. It was a simple gradient going from green to blue that grew as the video continued playing.

If only I had this advice in high school…

I already know it’s possible to create the same sort gradient on the <progress> element. Pankaj Parashar demonstrated that in a CSS-Tricks post back in 2016.

I really wanted to mock up something similar but haven’t played around with video all that much. I’m also no expert in JavaScript. But how hard can that actually be? I mean, all I want to do is get know how far we are in the video and use that to update the progress value. Right?

My inner bully made so much fun of me that I decided to give it a shot. It’s not the most complicated thing in the world, but I had some fun with it and wanted to share how I set it up in this demo.

The markup

HTML5 all the way, baby!

<figure>   <video id="video" src="http://html5videoformatconverter.com/data/images/happyfit2.mp4"></video>   <figcaption>     <button id="play" aria-label="Play" role="button">►</button>     <progress id="progress" max="100" value="0">Progress</progress>     </figcaotion> </figure>

The key line is this:

<progress id="progress" max="100" value="0">Progress</progress>

The max attribute tells us we’re working with 100 as the highest value while the value attribute is starting us out at zero. That makes sense since it allows us to think of the video’s progress in terms of a percentage, where 0% is the start and 100% is the end, and where our initial starting point is 0%.


I’m definitely not going to get deep into the process of styling the <progress> element in CSS. The Pankaj post I linked up earlier already does a phenomenal job of that. The CSS we need to paint a gradient on the progress value looks like this:

/* Fallback stuff */ progress[value] {   appearance: none; /* Needed for Safari */   border: none; /* Needed for Firefox */   color: #e52e71; /* Fallback to a solid color */ }  /* WebKit styles */ progress[value]::-webkit-progress-value {   background-image: linear-gradient(     to right,     #ff8a00, #e52e71   );   transition: width 1s linear; }  /* Firefox styles */ progress[value]::-moz-progress-bar {   background-image: -moz-linear-gradient(     to right,     #ff8a00, #e52e71   ); }

The trick is to pay attention to the various nuances that make it cross-browser compatible. Both WebKit and Mozilla browsers have their own particular ways of handling progress elements. That makes the styling a little verbose but, hey, what can you do?

Getting the progress value from a video

I knew there would be some math involved if I wanted to get the current time of the video and display it as a value expressed as a percentage. And if you thought that being a nerd in high school gained me mathematical superpowers, well, sorry to disappoint.

I had to write down an outline of what I thought needed to happen:

  • Get the current time of the video. We have to know where the video is at if we want to display it as the progress value.
  • Get the video duration. Knowing the video’s length will help express the current time as a percent.
  • Calculate the progress value. Again, we’re working in percents. My dusty algebra textbook tells me the formula is part / whole = % / 100. In the context of the video, we can re-write that as currentTime / duration = progress value.

That gives us all the marching orders we need to get started. In fact, we can start creating variables for the elements we need to select and figure out which properties we need to work with to fill in the equation.

// Variables const progress = document.getElementById( "progress" );  // Properties // progress.value = The calculated progress value as a percent of 100 // video.currentTime = The current time of the video in seconds // video.duration = The length of the video in seconds

Not bad, not bad. Now we need to calculate the progress value by plugging those things into our equation.

function progressLoop() {   setInterval(function () {     document.getElementById("progress").value = Math.round(       (video.currentTime / video.duration) * 100     );   }); }

I’ll admit: I forgot that the equation would result to decimal values. That’s where Math.round() comes into play to update those to the nearest whole integer.

That actually gets the gradient progress bar to animate as the video plays!

I thought I could call this a win and walk away happy. Buuuut, there were a couple of things bugging me. Plus, I was getting errors in the console. No bueno.

Showing the current time

Not a big deal, but certainly a nice-to-have. We can chuck a timer next to the progress bar and count seconds as we go. We already have the data to do it, so all we need is the markup and to hook it up.

Let’s add a wrap the time in a <label> since the <progress> element can have one.

<figure>   <video controls id="video" src="http://html5videoformatconverter.com/data/images/happyfit2.mp4"></video>   <figcaption>     <label id="timer" for="progress" role="timer"></label>     <progress id="progress" max="100" value="0">Progress</progress>     </figcaotion> </figure>

Now we can hook it up. We’ll assign it a variable and use innerHTML to print the current value inside the label.

const progress = document.getElementById("progress"); const timer = document.getElementById( "timer" );  function progressLoop() {   setInterval(function () {     progress.value = Math.round((video.currentTime / video.duration) * 100);     timer.innerHTML = Math.round(video.currentTime) + " seconds";   }); }  progressLoop();

Hey, that works!

Extra credit would involve converting the timer to display in HH:MM:SS format.

Adding a play button

The fact there there were two UIs going on at the same time sure bugged me. the <video> element has a controls attribute that, when used, shows the video controls, like play, progress, skip, volume, and such. Let’s leave that out.

But that means we need — at the very minimum — to provide a way to start and stop the video. Let’s button that up.

First, add it to the HTML:

<figure>   <video id="video" src="http://html5videoformatconverter.com/data/images/happyfit2.mp4"></video>   <figcaption>     <label id="timer" for="progress" role="timer"></label>     <button id="play" aria-label="Play" role="button">►</button>     <progress id="progress" max="100" value="0">Progress</progress>     </figcaotion> </figure>

Then, hook it up with a function that toggles the video between play and pause on click.

button = document.getElementById( "play" );  function playPause() {    if ( video.paused ) {     video.play();     button.innerHTML = "❙❙";   }   else  {     video.pause();      button.innerHTML = "►";   } }  button.addEventListener( "click", playPause ); video.addEventListener("play", progressLoop);

Hey, it’s still working!

I know it seems weird to take out the rich set of controls that HTML5 offers right out of the box. I probably wouldn’t do that on a real project, but we’re just playing around here.

Cleaning up my ugly spaghetti code

I really want to thank my buddy Neal Fennimore. He took time to look at this with me and offer advice that not only makes the code more legible, but does a much, much better job defining states…

// States const PAUSED = 'paused'; const PLAYING = 'playing';  // Initial state let state = PAUSED;

…doing a proper check for the state before triggering the progress function while listening for the play, pause and click events…

// Animation loop function progressLoop() {   if(state === PLAYING) {     progress.value = Math.round( ( video.currentTime / video.duration ) * 100 );     timer.innerHTML = Math.round( video.currentTime ) + ' seconds';     requestAnimationFrame(progressLoop);   } }  video.addEventListener('play', onPlay); video.addEventListener('pause', onPause); button.addEventListener('click', onClick);

…and even making the animation more performant by replacing setInterval with requestAnimationFrame as you can see highlighted in that same snippet.

Here it is in all its glory!

Oh, and yes: I was working on this while “watching” the training video. And, I aced the quiz at the end, thank you very much. 🤓

The post Some Innocent Fun With HTML Video and Progress appeared first on CSS-Tricks.


, , , ,

What Does `playsinline` Mean in Web Video?

I got myself confused about this the other day, went around searching for an answer and came up empty on finding something clear. The answer actually is quite clear and I feel a little silly for not knowing it.

With it in place, like this:

<video src="..." controls playsinline></video>

Mobile browsers, will play the video right where it is instead of the default, which is to open it up fullscreen while it plays.

Here’s what it looks like without playsinline:

Here’s what it looks like with playsinline:

(If you’re like me, you tried to play that video from the play button on the video in the video, only to realize it’s not a real play button. 🤯)

(While we’re getting meta, I’m making sure those videos above have playsinline on them right here in this blog post.)

Note that the user still has the ability to go fullscreen with the video even in the playsinline scenario, so I’d say it’s probably a smart default choice. It’s not literally the default — you have to add it, but you know what I mean.

One of the places this shows up regularly is in the attribute soup that is required to make video be a GIF-replacement:

<video autoplay loop muted playsinline src="..."></video>

If you have all four of those attributes, the video will actually autoplay (and loop) on mobile browsers, just like a GIF would, only with far better performance. You can skip loop if you don’t want that, but all the other three are required if you want the autoplay attribute to work.

I also learned that the (only?) way to get a thumbnail to show up on mobile (at least for iOS) is to use a poster attribute. Even if you preload, you don’t see anything but blank white unless you have a poster.

Without a poster:

With a poster:

<video   src="movie.mov"   poster="thumbnail.jpg"    controls ></video>mo

If you can’t be troubled to deal with a poster, you might wanna toss a border or something on video elements to sort of visually block off that area. Otherwise, the floating play button is a little awkward.

The post What Does `playsinline` Mean in Web Video? appeared first on CSS-Tricks.


, ,

Fluid Width Video

IN A WORLD of responsive and fluid layouts on the web, ONE MEDIA TYPE stands in the way of perfect harmony: video. There are lots of ways in which video can be displayed on your site. You might be self-hosting the video and presenting it via the HTML5 <video> tag. You might be using YouTube, Vimeo, or some other video provider that provides <iframe> code to display videos. Let’s cover how to make them all fluid width while maintaining an appropriate height based on their aspect ratio.

In each of these video-embedding scenarios, it is very common for a static width and height to be declared.

<video width="400" height="300" controls ... ></video>  <iframe width="400" height="300" ... ></iframe>  <!-- maybe even super old school --> <object width="400" height="300" ... /> <embed width="400" height="300" ... />

Guess what? Declaring static widths isn’t a good idea in fluid width environments. What if the parent container for that video shrinks narrower than the declared 400px? It will bust out and probably look ridiculous and embarrassing.

Simple and contrived, but still ridiculous and embarassing.

So can’t we just do this?

<video width="100%" ... ></video>

Well, yep, you can! If you are using standard HTML5 video, that will make the video fit the width of the container. It’s important that you remove the height declaration when you do this so that the aspect ratio of the video is maintained as it grows and shrinks, lest you get awkward “bars” to fill the empty space (unlike images, the actual video maintains it’s aspect ratio regardless of the size of the element).

You can get there via CSS (and not worry about what’s declared in the HTML) like this:

video {   /* override other styles to make responsive */   width: 100%    !important;   height: auto   !important; }

<iframe> Video (YouTube, Vimeo, etc.)

Our little trick from above isn’t going to help us when dealing with video that is delivered via <iframe>. Forcing the width to 100% is effective, but when we set height: auto, we end up with a static height of 150px1, which is far too squat for most video and makes for more R&E (Ridiculous and Embarrassing).

Fortunately, there are a couple of possible solutions here. One of them was pioneered by Thierry Koblentz and presented on A List Apart in 2009: Creating Intrinsic Ratios for Video. With this technique, you wrap the video in another element which has an intrinsic aspect ratio, then absolute position the video within that. That gives us fluid width with a reasonable height we can count on.

<div class="videoWrapper">   <!-- Copy & Pasted from YouTube -->   <iframe width="560" height="349" src="http://www.youtube.com/embed/n_dZNLr2cME?rel=0&hd=1" frameborder="0" allowfullscreen></iframe> </div>
.videoWrapper {   position: relative;   padding-bottom: 56.25%; /* 16:9 */   height: 0; } .videoWrapper iframe {   position: absolute;   top: 0;   left: 0;   width: 100%;   height: 100%; }

There is a clever adaptation of this that allows you to adjust the aspect ratio right from the HTML, like:

<div class="videoWrapper" style="--aspect-ratio: 3 / 4;">   <iframe ...>
.videoWrapper {   ...   /* falls back to 16/9, but otherwise uses ratio from HTML */   padding-bottom: calc(var(--aspect-ratio, .5625) * 100%);  }

Some old school video embedding uses <object> and <embed> tags, so if you’re trying to be comprehensive, update that wrapper selector to:

.videoWrapper iframe, .videoWrapper embed, .videoWrapper object { }

But, but… aspect ratios, legacy content, non-tech users, etc.

The above technique is awesome, but it has several possible limitations:

  1. It requires a wrapper element, so just straight up copy-and-pasting code from YouTube is out. Users will need to be a bit savvier.
  2. If you have legacy content and are redesigning to be fluid, all old videos need HTML adjustments.
  3. All videos need to be the same aspect ratio. Otherwise, they’ll be forced into a different aspect ratio and you’ll get the “bars”. Or, you’ll need a toolbox of class names you can apply to adjust it which is an additional complication.

If either of these limitations applies to you, you might consider a JavaScript solution.

Imagine this: when the page loads all videos are looked at and their aspect ratio is saved. Once right away, and whenever the window is resized, all the videos are resized to fill the available width and maintain their aspect ratio. Using the jQuery JavaScript Library, that looks like this:

// Find all YouTube videos // Expand that selector for Vimeo and whatever else var $ allVideos = $ ("iframe[src^='//www.youtube.com']"),    // The element that is fluid width   $ fluidEl = $ ("body");  // Figure out and save aspect ratio for each video $ allVideos.each(function() {    $ (this)     .data('aspectRatio', this.height / this.width)      // and remove the hard coded width/height     .removeAttr('height')     .removeAttr('width');  });  // When the window is resized $ (window).resize(function() {    var newWidth = $ fluidEl.width();    // Resize all videos according to their own aspect ratio   $ allVideos.each(function() {      var $ el = $ (this);     $ el       .width(newWidth)       .height(newWidth * $ el.data('aspectRatio'));    });  // Kick off one resize to fix all videos on page load }).resize();

That’s sorta what became FitVids.js

Except rather than deal with all that resizing business, FitVids.js loops over all the videos and adds the aspect-ratio enabling HTML wrapper and CSS necessary. That’s way more efficient than needing to bind to a window resize handler!

Plain JavaScript instead

jQuery is rather out of favor these days. Fortunately, Dave has a Vanilla version (that is BYO CSS):

  1. Literally all browsers will render iframe, canvas, embed, and object tags as 300px × 150px if not otherwise declared. Even if this isn’t present in the UA stylesheet.

The post Fluid Width Video appeared first on CSS-Tricks.


, ,

Improving Video Accessibility with WebVTT

“The power of the Web is in its universality. Access by everyone regardless of disability is an essential aspect.”
– Tim Berners-Lee

Accessibility is an important element of web development, and with the ever-growing prevalence of video content, the necessity for captioned content is growing as well. WebVTT is a technology that solves helps with captioned content as a subtitle format that integrates easily with already-existing web APIs.

That’s what we’re going to look at here in this article. Sure, WebVTT is captioning at its most basic, but there are ways to implement it to make videos (and the captioned content itself) more accessible for users.

See the Pen
by Geoff Graham (@geoffgraham)
on CodePen.

Hi, meet the WebVTT format

First and foremost: WebVTT is a type of file that contains the text “WebVTT” and lines of captions with timestamps. Here’s an example:

WEBVTT  00:00:00.000 --> 00:00:03.000 - [Birds chirping] - It's a beautiful day!  00:00:04.000 --> 00:00:07.000 - [Creek trickling] - It is indeed!  00:00:08.000 --> 00:00:10.000 - Hello there!

A little weird, but makes pretty good sense, right? As you can see, the first line is “WEBVTT” and it is followed by a time range (in this case, 0 to 3 seconds) on Line 3. The time range is required. Otherwise, the WEBVTT file will not work at all and it won’t even display or log errors to let you know. Finally, each line below a time range represents captions contained in the range.

Note that you can have multiple captions in a single time range. Hyphens may be used to indicate the start of a line, though it’s not required and more stylistic than anything else.

The time range can be one of two formats: hh:mm:ss.tt or mm:ss.tt. Each part follows certain rules:

  • Hours (hh): Minimum of two digits
  • Minutes (mm): Between 00 and 59, inclusive
  • Seconds (ss): Between 00 and 59, inclusive
  • Milliseconds (tt): Between 000 and 999, inclusive

This may seem rather daunting at first. You’re probably wondering how anyone can be expected to type and tweak this all by hand. Luckily, there are tools to make this easier. For example, YouTube can automatically caption videos for you with speech recognition in addition to allowing you to download the caption as a VTT file as well! But that’s not it. WebVTT can also be used with YouTube as well by uploading your VTT file to your YouTube video.

Once we have this file created, we can then embed it into an HTML5 video element.

<!DOCTYPE HTML> <html>   <body>     <video controls autoplay>       <source src="your_video.mp4" type="video/mp4"/>       <track default kind="captions" srclang="en" label="English" src="your_caption_file.vtt"/>     </video>   </body> </html>

The <track> tag is sort of like a script that “plays” along with the video. We can use multiple tracks in the same video element. The default attribute indicates that a the track will be enabled automatically.

Let’s run down all the <track> attributes while we’re at it:

  • srclang indicates what language the track is in.
  • kind represents the type of track it is and there are five kinds:
    • subtitles are usually translations and descriptions of different parts of a video.
    • descriptions help unsighted users understand what is happening in a video.
    • captions provide un-hearing users an alternative to audio.
    • metadata is a track that is used by scripts and cannot be seen by users.
    • chapters assist in navigating video content.
  • label is a title for the text track that appears in the caption track
  • src is the source file for the track. It cannot come from a cross-origin source unless crossorigin is specified.

While WebVTT is designed specifically for video, you can still use it with audio by placing an audio file within a <video> element.

Digging into the structure of a WebVTT file

MDN has great documentation and outlines the body structure of a WebVTT file, which consists of up to six components. Here’s how MDN breaks it down:

  • An optional byte order mark (BOM)
  • The string “WEBVTT
  • An optional text header to the right of WEBVTT.
    • There must be at least one space after WEBVTT.
    • You could use this to add a description to the file.
    • You may use anything in the text header except newlines or the string “-->“.
  • A blank line, which is equivalent to two consecutive newlines.
  • Zero or more cues or comments.
  • Zero or more blank lines.

Note: a BOM is a unicode character that indicates the unicode encoding of the text file.

Bold, italic, and underline — oh my!

We can absolutely use some inline HTML formatting in WebVTT files! These are the ones that everyone is familiar with: <b>, <i>, and <u>. You use them exactly as you would in HTML.

WEBVTT  00:00:00.000 --> 00:00:03.000 align:start This is bold text  00:00:03.000 --> 00:00:06.000 align:middle This is italic text  00:00:06.000 --> 00:00:09.000 vertical:rl align:middle This is <u>underlined  text</u>

Cue settings

Cue settings are optional strings of text used to control the position of a caption. It’s sort of like positioning elements in CSS, like being able to place captions on the video.

For example, we could place captions to the right of a cue timing, control whether a caption is displayed horizontally or vertically, and define both the alignment and vertical position of the caption.

Here are the settings that are available to us.

Setting 1: Line

line controls the positioning of the caption on the y-axis. If vertical is specified (which we’ll look at next), then line will instead indicate where the caption will be displayed on the x-axis.

When specifying the line value, integers and percentages are perfectly acceptable units. In the case of using an integer, the distance per line will be equal to the height (from a horizontal perspective) of the first line. So, for example, let’s say the height of the first line of the caption is equal to 50px, the line value specified is 2, and the caption’s direction is horizontal. That means the caption will be positioned 100px (50px times 2) down from the top, up to a maximum equal to coordinates of the boundaries of the video. If we use a negative integer, it will move upward from the bottom as the value decreases (or, in the case of vertical:lr being specified, we will move from right-to-left and vice-versa). Be careful here, as it’s possible to position the captions off-screen in addition to the positioning being inconsistent across browsers. With great power comes great responsibility!

In the case of a percentage, the value must be between 0-100%, inclusive (sorry, no 200% mega values here). Higher values will move the caption from top-to-bottom, unless vertical:lr or vertical:rl is specified, in which case the caption will move along the x-axis accordingly.

As the value increases, the caption will appear further down the video boundaries. As the value decreases (including into the negatives), the caption will appear further up.

Tough picture this without examples, right? Here’s how this translates into code:

00:00:00.000 --> 00:00:03.000 line:50% This caption should be positioned horizontally in the approximate center of the screen.
00:00:03.000 --> 00:00:06.000 vertical:lr line:50% This caption should be positioned vertically in the approximate center of the screen.
00:00:06.000 --> 00:00:09.000 vertical:rl line:-1 This caption should be positioned vertically along the left side of the video.
00:00:09.000 --> 00:00:12.000 line:0 The caption should be positioned horizontally at the top of the screen.

Setting 2: Vertical

vertical indicates the caption will be displayed vertically and move in the direction specified by the line setting. Some languages are not displayed left-to-right and instead need a top-to-bottom display.

  00:00:00.000 --> 00:00:03.000 vertical:rl This caption should be vertical.
00:00:00.000 --> 00:00:03.000 vertical:lr This caption should be vertical.

Setting 3: Position

position specifies where the caption will be displayed along the x-axis. If vertical is specified, the position will instead specify where the caption will be displayed on the y-axis. It must be an integer value between 0% and 100%, inclusive.

00:00:00.000 --> 00:00:03.000 vertical:rl position:100% This caption will be vertical and toward the bottom.  00:00:03.000 --> 00:00:06.000 vertical:rl position:0% This caption will be vertical and toward the top.

At this point, you may notice that line and position are similar to the CSS flexbox properties for align-items and justify-content, and that vertical behaves a lot like flex-direction. A trick for remembering WebVTT directions is that line specifies a position perpendicular to the flow of the text, whereas position specifies the position parallel to the flow of the text. That’s why line suddenly moves along the horizontal axis, and position moves along the vertical axis if we specify vertical.

Setting 4: Size

size specifies the width of the caption. If vertical is specified, then it will set the height of the caption instead. Like other settings, it must be an integer between 0% and 100%, inclusive.

00:00:00.000 --> 00:00:03.000 vertical:rl size:50% This caption will fill half the screen vertically.
00:00:03.000 --> 00:00:06.000 position:0% This caption will fill the entire screen horizontally.

Setting 5: Align

align specifies where the text will appear horizontally. If vertical is specified, then it will control the vertical alignment instead.

The values we’ve got are: start, middle, end, left and right. Without vertical specified, the alignments are exactly what they sound like. If vertical is specified, they effectively become top, middle (vertically), and bottom. Using start and end as opposed to left and right, respectively, is a more flexible way of allowing the alignment to be based on the unicode-bidi CSS property’s plaintext value.

Note that align is not unaffected by vertical:lr or vertical:rl.

WEBVTT  00:00:00.000 --> 00:00:03.000 align:start This caption will be on the left side of the screen.  00:00:03.000 --> 00:00:06.000 align:middle This caption will be horizontally in the middle of the screen.  00:00:06.000 --> 00:00:09.000 vertical:rl align:middle This caption will be vertically in the middle of the screen.  00:00:09.000 --> 00:00:12.000 vertical:rl align:end This caption will be vertically at the bottom right of the screen regardless of vertical:lr or vertical:rl orientation.  00:00:12.000 --> 00:00:15.000 vertical:lr align:end This caption will be vertically at the bottom of the screen, regardless of the vertical:lr or vertical:rl orientation.  00:00:12.000 --> 00:00:15.000 align:left This caption will appear on the left side of the screen.  00:00:12.000 --> 00:00:15.000 align:right This caption will appear on the right side of the screen.

WebVTT Comments

WebVTT comments are strings of text that are only visible when reading the source text of the file, the same way we think of comments in HTML, CSS, JavaScript and any other language. Comments may contain a new line, but not a blank line (which is essentially two new lines).

WEBVTT  00:00:00.000 --> 00:00:03.000 - [Birds chirping] - It's a beautiful day!  NOTE This is a comment. It will not be visible to anyone viewing the caption.  00:00:04.000 --> 00:00:07.000 - [Creek trickling] - It is indeed!  00:00:08.000 --> 00:00:10.000 - Hello there!

When the caption file is parsed and rendered, the highlighted line above will be completely hidden from users. Comments can be multi-line as well.

There are three very important characters/strings to take note of that may not be used in comments: <, &, and -->. As an alternative, you can use escaped characters instead.

Not Allowed Alternative
NOTE 5 < 7 NOTE 5 &lt; 7
NOTE puppy --> dog NOTE puppy --&gt; do

A few other interesting WebVTT features

We’re going to take a quick look at some really neat ways we can customize and control captions, but that are lacking consistent browser support, at least at the time of this writing.

Yes, we can style captions!

WebVTT captions can, in fact, be styled. For example, to style the background of a caption to be red, set the background property on the ::cue pseudo-element:

video::cue {   background: red; }

Remember how we can use some inline HTML formatting in the WebVTT file? Well, we can select those as well. For example, to select and italic (<i>) element:

video::cue(i) {   color: yellow; }

Turns out WebVTT files support a style block, a lot like the way HTML files do:

WEBVTT  STYLE ::cue {   color: blue;   font-family: "Source Sans Pro", sans-serif; }

Elements can also be accessed via their cue identifiers. Note that cue identifiers use the same escaping mechanism as HTML.

WEBVTT  STYLE ::cue(#middle cue identifier) {   text-decoration: underline; } ::cue(#cue identifier ) {   font-weight: bold;   color: red; }  first cue identifier 00:00:00.000 --> 00:00:02.000 Hello, world!  middle cue identifier 00:00:02.000 --> 00:00:04.000 This cue identifier will have an underline!  cue identifier 3 00:00:04.000 --> 00:00:06.000 This one won't be affected, just like the first one!

Different types of tags

Many tags can be used to format captions. There is a caveat. These tags cannot be used in a <track> element where kind attribute is chapters. Here are some formatting tags you can use.

The class tag

We can define classes in the WebVTT markup using a class tag that can be selected with CSS. Let’s say we have a class, .yellowish that makes text yellow. We can use the tag <c.yellowish> in a caption. We can control lots of styling this way, like the font, the font color, and background color.

/* Our CSS file */ .yellowish {   color: yellow; } .redcolor {   color: red; }
WEBVTT  00:00:00.000 --> 00:00:03.000 <c.yellowish>This text should be yellow.</c> This text will be the default color.  00:00:03.000 --> 00:00:06.000 <c.redcolor>This text should be red.</c> This text will be the default color.

The timestamp tag

If you want to make captions appear at specific times, then you will want to use timestamp tags. They’re like fine-tuning captions to exact moments in time. The tag’s time must be within the given time range of the caption, and each timestamp tag must be later than the previous.

WEBVTT  00:00:00.000 --> 00:00:07.000 This <00:00:01.000>text <00:00:02.000>will <00:00:03.000>appear <00:00:04.000>over <00:00:05.000>6 <00:00:06.000>seconds.

The voice tag

Voice tags are neat in that they help identify who is speaking.

WEBVTT  00:00:00.000 --> 00:00:03.000 <v Alice>How was your day, Bob?  00:00:03.000 --> 00:00:06.000 <v Bob>Great, yours?

The ruby tag

The ruby tag is a way to display small, annotative characters above the caption.

WEBVTT  00:00:00.000 --> 00:00:05.000 <ruby>This caption will have text above it<rt>This text will appear above the caption.


And that about wraps it up for WebVTT! It’s an extremely useful technology and presents an opportunity to improve your site’s accessibility a great deal, particularly if you are working with video. Try some of your own captions out yourself to get a better feel for it!


, , ,

Native Video on the Web

TIL about the HLS video format:

HLS stands for HTTP Live Streaming. It’s an adaptive bitrate streaming protocol developed by Apple. One of those sentences to casually drop at any party. Äh. Back on track: HLS allows you to specify a playlist with multiple video sources in different resolutions. Based on available bandwidth these video sources can be switched and allow adaptive playback.

This is an interesting journey where the engineering team behind Kitchen Stories wanted to switch away from the Vimeo player (160 kB), but still use Vimeo as a video host because they provide direct video links with a Pro plan. Instead, they are using the native <video> element, a library for handling HLS, and a wrapper element to give them a little bonus UX.

This video stuff is hard to keep up with! There is another new format called AV1 that is apparently a big deal as YouTube and Netflix are both embracing it. Andrey Sitnik wrote about it here:

Even though AV1 codec is still considered experimental, you can already leverage its high-quality, low-bitrate features for a sizable chunk for your web audience (users with current versions of Chrome and Firefox). Of course, you would not want to leave users for other browsers hanging, but the attributes for <video> and <source> tags make implementing this logic easy, and in pure HTML, you don’t need to go at length to detect user agents with JavaScript.

That doesn’t even mention HLS, but I suppose that’s because HSL is a streaming protocol, which still needs to stream in some sort of format.

Direct Link to ArticlePermalink

The post Native Video on the Web appeared first on CSS-Tricks.