Seamlessly adaptive HTML5 video playback

Has anyone figured out how to make an HTML5 video in an absolutely positioned <video> element resize to fit the window width and height without ever getting cropped? Many solutions I've come across rely on using the <iframe> tag, which is not an option for me, or only adjust based on width (something I can already do).

Essentially, I want the video to be as large as possible while also ensuring it doesn't get cut off if the window size changes - even in IE9. (Just to clarify: The video needs to keep its original aspect ratio, so black bars are acceptable.)

Here's what I've attempted so far.

/*CSS*/

#player-overlay {
  position: absolute;
  display: none;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: #000        
    z-index:999;
}
<!--HTML-->

<div id="player-overlay">
  <video width="100%" video="100%" style="width:100%, height:100%">
    <source src="../static/video/10s.mp4" />
    <source src="../static/video/10s.webm" type='video/webm; codecs="vp8, vorbis"' />
    <source src="../static/video/10s.ogv" type='video/ogg; codecs="theora, vorbis"' />
  </video>    
</div>

It looks like I might have to resort to writing a JavaScript solution instead.

Answer №1

Applying width and max-height to the <video> element will ensure proper display:

<div id="player-overlay">
    <video>
        <source src="../static/video/10s.mp4" />
        <source src="../static/video/10s.webm" type='video/webm; codecs="vp8, vorbis"' />
        <source src="../static/video/10s.ogv" type='video/ogg; codecs="theora, vorbis"' />
    </video>    
</div>
video {
    width: 100%;
    max-height: 100%;
}

Explore this link for more insights.

Additionally, remember to include a semicolon after background-color. In positioning elements to fill the screen, consider using top, bottom, left, and right properties rather than height and width.

Answer №2

(Although this discussion is from a while back, I'm optimistic that my response will be beneficial to someone in need.)

It seems like you already had the correct solution at hand. The style="width:100%, height:100%" on your <video> tag is effective, but remember to use a semicolon instead of a comma. It's unnecessary to include the redundant width="100%" and height="100%" attributes.

The reason why width: 100%; height: 100% works (with a semicolon) is because even though the <video> element expands, the video itself maintains its aspect ratio, resulting in letterboxing or pillarboxing within the <video> container: .

An advantage of using height: 100% is that the video gets letterboxed precisely in the center, whereas with max-height: 100%, the video aligns to the top of the container.

Additionally, ensure that your <video> tag has display: block set. Otherwise, it defaults to display: inline, leaving white space at the bottom due to font descenders: There is a 4px gap below canvas/video/audio elements in HTML5.

As noted by @gilly3, don't forget to add a semicolon after background-color: #000. And obviously, remove display: none. =)

Here's the complete solution:

/*CSS*/

#player-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: #000;
  z-index: 999;
}

video {
  display: block;
  width: 100%;
  height: 100%;
}
<!--HTML-->

<div id="player-overlay">
  <video controls>
    <source src="http://techslides.com/demos/sample-videos/small.webm" type="video/webm">
    <source src="http://techslides.com/demos/sample-videos/small.ogv"  type="video/ogg">
    <source src="http://techslides.com/demos/sample-videos/small.mp4"  type="video/mp4">
    <source src="http://techslides.com/demos/sample-videos/small.3gp"  type="video/3gp">
  </video>
</div>

View the code snippet in "full page" mode and resize your browser window to observe the letterboxing effect.

By the way, the original sources for your videos weren't working anymore, so I utilized sample videos found here: .

I hope this information proves helpful.

Answer №3

For a great solution, apply this CSS code- By using height: auto;, your container will be properly covered.

video {
  width: 100%;
  height: auto;
}

Answer №4

While searching for information on responsive videos, I unexpectedly discovered this helpful answer. I used a similar approach to create my own responsive video element.

If you're looking to gain a better understanding of the concept, check out this link: Height equals width Pure CSS

Your code implementation could resemble the following:

#player-overlay {
  position: relative;

  &:before {
    content:'';
    display: block;
    padding-top: 50%;  // A 2:1 ratio is achieved with 50%. Check the provided link for more details on ratios.
  }
}

video {
  bottom: 0;
  left: 0;
  position: absolute;
  right: 0;
  top: 0;
  width: 100%;
}

To adjust the ratio, simply modify the padding-top value in the before pseudo-element.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Turn off hover effect using solely CSS

This is my first time posting on stackoverflow, so please excuse me if I overlook something obvious. I tried searching for a solution beforehand but couldn't find one that seemed relevant. In the following jsfiddle example, I have a div that acts as ...

The Yii yiiactiveform function remains undefined when clientValidation is disabled

I am currently using Yii 1.1.14 Instead of using Yii's ajax validation or client validation, I am using a form to capture an email. <?php $form = $this->beginWidget('CActiveForm', array( 'id' => 'form-newsletter ...

Discover how to generate nested dynamic routes in NextJS by linking to MongoDB data using the getStaticProps and getStaticPaths functions

Currently, I am facing a challenge with implementing dynamic paths in NextJS and I'm struggling to find a solution. Let me provide some context for better understanding. I am working on developing an ecommerce application using NextJS, and the folder ...

Implementing asynchronous code when updating state using React hooks

Here's a scenario I'm dealing with: const [loading, setLoading] = useState(false); ... setLoading(true); doSomething(); // <--- at this point, loading remains false. Since setting state is asynchronous, what would be the best approach to ...

Transmitting a sequence of JSON information from php to JavaScript,

I am struggling to fetch a series of JSON data from PHP to my JavaScript file. Initially, I have multiple JSON data stored in an array in PHP, and I am echoing each one by looping through the array in my JavaScript file. <?php $result = array('{ ...

What causes the `d-none` class to toggle on and off repeatedly when the distance between two div elements is less than 10 during window resizing?

My primary objective is to display or hide the icon based on the width of the right container and the rightButtonGroupWrapper. If the difference between these widths falls below 10, the icons should be shown, otherwise hidden. However, I'm facing an i ...

Easy task tracker in Vue.js

I’m currently delving into the world of VueJS and working on a simple to-do list application. The issue I’m facing is that I can't seem to successfully pass an array to the child component responsible for displaying the list: Parent Component < ...

Is utilizing pjax the most effective method for achieving a seamless navigation experience?

I recently delved into the world of implementing pjax on my website in order to enhance user experience by reducing unnecessary HTTP requests and repeated rendering of unchanged HTML. Surprisingly, I found it quite easy to set up and the difference it mad ...

Is there a regular expression that can identify whether a string is included in a numbered list?

Struggling with creating a regular expression to determine if a string is part of a numbered list like those in word processors. Need it to return true only if the string starts with a number, followed by a full stop and a space. Easy for single or doubl ...

Adjust the alignment of cells within a table

Excuse my lack of knowledge, but CSS is still new to me. I'm attempting to align two elements next to each other using display: table. However, the element on the right seems to be lower than the one on the left, and I can't figure out why. . ...

Exploring Image Access with Rails and jQuery

Currently, I am facing an issue with accessing images uploaded to my Rails app using jQuery. Specifically, I want to switch out images and perform similar tasks. The jQuery implementation is quite simple: $('#a1').change(function() { var src = ...

Create a dropdown menu using a PDO query to populate the selectable options

I need to create a Select List that dynamically populates items/information from a Query. I understand the importance of updating the select list every time the database is updated, so JQuery is required for this task. Although I have limited experience wi ...

Generating instances using TypeScript generics

Looking to create a factory for instantiating classes with generics. After checking out the TypeScript docs, everything seems to work as expected. Here's a simplified version of how it can be done: class Person { firstName = 'John'; ...

Passport.js: Navigating Users in the Right

I've been working on integrating passport.js, passport-google-oauth, and nodjes to retrieve a user's profile locally. However, I'm facing an issue with the redirect after logging in. Although the information is successfully loaded (I can acc ...

Locate components within JQLite

I need assistance accessing the JQLite element of a div with the class "dialog" in an angular directive. Unfortunately, I can't use element.find('div') because there is another div in the template. After coming across a similar question (An ...

Selectize Fails to Populate Options Using Ajax

ExpressJS is the platform I am using to develop a management dashboard for a community project. Right now, my main concern is integrating a modal that allows users to add new games to a database. Although I am able to fetch data remotely, I am facing diffi ...

Issues with Javascript code syntax

I have encountered an issue while creating a new literal control from code behind. I am able to add standard HTML into it successfully, however, when I try to insert <%= SomeDiv.ClientID %> into the literal control, it simply prints exactly what is i ...

When a user clicks on a button, AJAX and jQuery work together to initiate a setInterval function that continually

Currently, I have two scripts in place. The first script is responsible for fetching a specific set of child nodes from an XML file through AJAX and using them to create a menu displayed as a list of buttons within #loadMe. What's remarkable about thi ...

Implement consistent styling across several elements within a component

const GreenRow = styled.div` background-color: green; ` const RedRow = styled.div` background-color: red; ` const YellowRow = styled.div` background-color: yellow; ` const GreyRow = styled.div` background-color: grey; ` const MyComponent = () => ...

Harness the power of a NUXT component on a different website

Currently, I have a fully functional NUXT application that consists of numerous pages and components operating in `universal` mode. My challenge now is to render one of these components on a separate static HTML website. Exporting a component from a stand ...