Fixing Opera’s media.css to Scale Videos Properly

In Opera, when you visit a .webm or .ogv file, the video is vertically and horizontally centered. This is accomplished by the styles in styles/media.css in Opera's program files directory and a <video> element inside a <div> that's inside the <body> on the page.


@charset "utf-8";
/* Stylesheet for the Opera media viewer */
/* Copyright 2011 Opera Software */
html {
background-color: hsl(0,0%,98%);
width: 100%;
height: 100%;
display: table;
}
body {
margin: 0;
height: 100%;
display: table-row;
}
div {
vertical-align: middle;
height: 100%;
display: table-cell;
}
video, audio {
margin: auto;
display: block;
}
@media projection, tv, handheld {
html {background-color: black;}
body {background-color: hsl(0,0%,39%);}
video, audio {background-color: hsl(0,0%,98%);}
}
@media tv, handheld and (max-width: 300px) {
html {
margin: auto;
width: 246px;
max-width: 100%;
}
video, audio {
margin: 10px auto;
max-width: 100%;
}
}

As you can see, the width and height of the html element are set to 100% of the viewport. And, it's set to act as a table.

For the body, the default 8px margin is turned off, the height is set to 100% of the html element and it's set to act like a table row.

The div is set to 100% of the body and it's set to act like a table cell. And, it's set to vertically align its contents, which will vertically align the video element that's in it.

The video element is set to a block element so that 'margin: auto' works to horizontally center the video element inside the div. The video could be left as an inline-block and 'text-align: center' could be added to the div, but that's not considered the right way to do it.

That all makes the video centered inside the viewport. But, there's a problem. If the viewport is smaller than the video (like when watching a 1920 x 1080 video at a resolution of 1366 x 768), the video will show full size and cause major scrolling where you can't see the whole video at once.

The ideal situation in this case is to scale videos that are too big down to the size of the viewport while keeping the aspect ratio of the video where no scrollbars are shown at all. And, videos that are smaller than the viewport should show at the original size and not scale up (as they'd get distorted).

To fix this, the thing to do would be to add 'max-width: 100%; max-height: 100%' for the video element. But, this only works half-way. The part that doesn't work is max-width. If the video is bigger than the viewport, Opera will limit the video width to 100%, but the table (the html element) gets expanded to the intrinsic width of the video.

There doesn't seem to be a way to work around this with only css while keeping the video centered vertically. It can be fixed like this though:


@charset "utf-8";
/* Stylesheet for the Opera media viewer */
/* Copyright 2011 Opera Software */
html {
background-color: hsl(0,0%,98%);
width: 100%;
height: 100%;
}
body {
margin: 0;
width: 100%;
height: 100%;
}
div {
margin: 0;
width: 100%;
height: 100%;
}
video, audio {
display: block;
margin: auto;
max-width: 100%;
max-height: 100%;
}
@media projection, tv, handheld {
html {background-color: black;}
body {background-color: hsl(0,0%,39%);}
video, audio {background-color: hsl(0,0%,98%);}
}
@media tv, handheld and (max-width: 300px) {
html {
margin: auto;
width: 246px;
max-width: 100%;
}
video, audio {
margin: 10px auto;
max-width: 100%;
}
}

, but then videos will be top-aligned, which really isn't all that bad and is a lot better than what Opera does now.

However, I'd rather it work right and be vertically centered. So, since userjs works on video pages in Opera, I created media.js to fix the default media.css that Opera comes with. In short, it gets the width and height of the viewport, checks if the video is bigger than that (by looking at the video's videoWidth and videoHeight properties) and if it is, it scales the video down to the size of the viewport while keeping the aspect ratio of the video. It leaves videos that are not bigger than the viewport alone. This is all done onload on onresize. (The aspect ratio adjust code *might* be buggy, but it seems to work O.K. for me.)

Now, if you visit an audio-only file (like an ogv without video or an oga vorbis file), Opera will still use a &tl;video> element where the controls are only shown when you hover over the video (which will be pretty small, like 300 x 150). The page looks blank otherwise. Because of this, in this situation, media.js sets the video element's width and height to 100% so that hovering anywhere on the page will show the controls. This will also make the controls show at the bottom though, which has its pros and cons. But, at least the seek bar will be big where you can do more precise seeking.

But, what I'd like to see is a css-only solution that keeps the vertical centering. If anyone can solve this with just css, that'd be cool.

It would also be cool though if Opera would use <audio> for oga files so that the bar is always shown, or implement some way to always show the bar with <video> and shrink the video area to 0 width and height when there's only audio. I didn't try to hack this in with userjs as I'd have to wait for the video's metadata to load and then replace the video element with an audio element. It'd be annoying as a user to see that happen.

Another thing I'd like to see for the video pages in Opera, once this is all fixed, is an *option* to switch to scale videos that area smaller than the viewport to 100% of the viewport while keeping the aspect ratio. In Media Player Classic, this is called "touch window from inside". Maybe the fit-to-width button can be special for video pages where it has this option, and an option to show the video at full size (with scrolling) for certain times when you want to see a *part* of the video at full size.

Now, I did check other browsers to see what they do when visiting webm videos directly (even IE with the webm codecs installed). They don't do anything special at all and just show the video left-aligned, at the top, at full size.

2 Replies to “Fixing Opera’s media.css to Scale Videos Properly”

  1. Firefox (latest trunk at least) now scales down videos that are larger than the viewport and centers the video. Firefox has made a whole bunch of other improvements for too.

Leave a Reply

Your email address will not be published. Required fields are marked *