This post has moved. Updated location: Finding the true dimensions of an HTML5 video’s active area
Recently I needed to find the true pixel dimensions of an HTML5 video on a webpage. Easy, right? Well, not exactly. Let me clarify a bit:
- We’re not looking for the width and height of the video element (
video.width
andvideo.height
). Unlike images, videos do not skew. So if you specifywidth: 500pt; height: 100pt;
, unless your video is actually that (highly unusual!) aspect ratio, you’re going to have thick “borders” (They’re not actual CSS borders, so their color is set with thebackground-color
CSS property). This is especially common when your video is full-screen. Theelement will take the whole width and height, but unless the video’s aspect ratio matches that of the display perfectly, there will be borders at either the top and bottom, or at the sides.
- We’re also not looking for the video’s “native” resolution, that is, the dimensions it has when it is not scaled at all. This can be found with
video.videoWidth
andvideo.videoHeight
. These values are’t set until after the video metadata loads, so you may want to listen for that event.
So what are we looking for?
We’re looking for the area within the element that displays the video. The area not including the borders.
Let’s take a look at what the HTML5 specification says about this:
In the absence of style rules to the contrary, video content should be rendered inside the element’s playback area such that the video content is shown centered in the playback area at the largest possible size that fits completely within it, with the video content’s aspect ratio being preserved. Thus, if the aspect ratio of the playback area does not match the aspect ratio of the video, the video will be shown letterboxed or pillarboxed. Areas of the element’s playback area that do not contain the video represent nothing.
Well, that gives us something to work with. If we assume “the absence of style rules to the contrary,” all we have to do is calculate “the largest possible size that fits completely within [the video element].” First, we figure out the video’s aspect ratio: video.videoWidth/video.videoHeight
. Then we work out the aspect ratio of the video element: video.width/video.height
. Given this information, and the dimensions of the element, we can calculate the dimensions of the active area.
The spec goes on to say that the fitting of the video in its element may be changed via CSS.
Explaining how to calculate it is simple in JavaScript, but terribly wordy in English. So I’ll simply present you a straightforward JavaScript function I wrote that takes a video element and returns the dimensions of the active area:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function videoDimensions(video) { | |
// Ratio of the video's intrisic dimensions | |
var videoRatio = video.videoWidth / video.videoHeight; | |
// The width and height of the video element | |
var width = video.offsetWidth, height = video.offsetHeight; | |
// The ratio of the element's width to its height | |
var elementRatio = width/height; | |
// If the video element is short and wide | |
if(elementRatio > videoRatio) width = height * videoRatio; | |
// It must be tall and thin, or exactly equal to the original ratio | |
else height = width / videoRatio; | |
return { | |
width: width, | |
height: height | |
}; | |
} |
I’ve been using this code, and it reliably returns the width and height of the video whether the bars on on the sides or the top and bottom. I wasn’t able to find any other solution to this problem, but I’d be interested to hear if you know of another solution, or potential issues with the one I found. Feel free to chime in in the comments.