Grow your CSS skills. Land your dream job.

Rundown of Handling Flexible Media

Published by Chris Coyier

When you take the responsive web design route, part of the deal is fluid grids. That is, container elements set in percentage widths. Just one example: an <article> that holds a blog post might be 320px wide on a small screen device and 690px wide on some large screen. Text can be resized and will flow nicely to fill a container. That's not too hard. But media - images, video players, and audio players - demand a bit more attention (e.g. a video that sticks off the edge of the screen == bad). This post is to round up the methods of handling that.

Flexible Images

flexible-images

If you're comfortable with IE 7 and up support. This little beauty will do you fine:

img {
  max-width: 100%;

  /* just in case, to force correct aspect ratio */
  height: auto !important;
}

If you are caring about IE 7 support (I hope not, but I understand there are scenarios in which you must), use this to make sure the images survive the scale-down:

img { 
  -ms-interpolation-mode: bicubic; 
}

See here for more on that.

If you need to care about IE 6 (again...) this Ethan Marcotte article has a JavaScript solution. Kind of a bummer loading extra JavaScript for a browser that is already much slower, but c'est la vie.

A shift in thinking

There was a time in which resizing images was quite the taboo. Browsers sucked at resizing images and bandwidth was being wasted. That attitude is all but gone now mostly because browsers are now pretty good at resizing images and having them look good. In fact, with "retina" displaying becoming a thing, serving too-large-for-container images is kinda good, because scaling them down makes them look all the sharper.

However the bandwidth thing is still a (big) issue. Which is what makes the responsive images thing such a hot issue right now. Point is: when thinking about flexible images, work in some thinking about responsive images too. You can read more up on the current solutions to that here.

Flexible Video

Flexible video is a little more complex than images. If you are using HTML5 <video> directly, the good news is that it holds its aspect ratio just like images do, so the same technique holds:

video {
  max-width: 100%;

  /* just in case, to force correct aspect ratio */
  height: auto !important;
}

However, I'm starting to think it's a pretty bad idea to use HTML5 <video> directly. The required formats have been shifting around for years now and it's not over yet. Add to that the fact that 1) hosting video is bandwidth intensive and expensive 2) streaming is another whole complicated beast 3) maintaining appropriate quality across formats and devices and available bandwidth is hard and 4) skinning consistant controls on the player is hard and ... well ... screw using HTML5 video directly.

Instead, I highly recommend using a video service like YouTube or Vimeo. When you embed videos from these services, you embed an <iframe>. What comes inside the iframe might be HTML5 video, but you don't have to deal with it directly.

All that to say: <iframe>s have an aspect ratio problem.

Thierry Koblentz solved this issue years ago in his A List Apart article Creating Intrinsic Ratios for Video.

The basic idea is that you create a video wrapper div with zero height and a top padding set in percentages. That percentage will actually be a percentage of the width, making it maintain aspect ratio. Then you absolutely position the video inside, which gives you that elusive ability to maintain aspect ratio. We'd be targeting the iframe for absolute position, as again, video doesn't need this but iframes do. The basics:

.video-wrapper {
  height: 0;
  padding-bottom: 56.25%; /* 16:9 */
  position: relative;
}
.video-wrapper iframe {
  position: absolute;
  top: 0; left: 0; right: 0; bottom: 0;
}

Check out the article on that for more nuances and details about older browser support. I also cover all of this and include some homebrew JavaScript solutions (with demos) in my .net mag article Create Fluid Width Videos.

Enough complexity, enter simplicity

If you're using jQuery and you've had enough of the complication surrounding the issue of flexible width video, I invite you to try FitVids.js. I co-authored this little jQuery plugin with Dave Rupert to specifically deal with this problem. It uses the exact same concepts explained above, only it does it automatically. That means 1) no non-semantic wrapper in your authored markup 2) aspect ratios that match the individual video (not all videos are the same).

fitvids

FitVids.js works out of the box with all the major video players and is super easy to extend to work with any player.

Using Sublime Video?

I have a tutorial on how to make their player fluid width.

Using MediaElements.js?

MediaElements.js is a very nice HTML5 video player that alleviates some of the issues I mentioned above with HTML5 video. Namely, it provides a nice consistent player skin and has the ability to fall back to older tech to play videos, like Flash and Silverlight. It's not a total silver bullet as it doesn't save you from the platform wars on mobile (which don't have Flash or Silverlight generally) or help with streaming or quality issues, but it's still nice.

There is a lot of fixed pixel calculation stuff going on in MediaElements.js, but I've been able to force it to be fluid width in the past with some !important overrides:

.mejs-container {
  width: 100% !important;
  height: auto !important;
  padding-top: 57%;
}
.mejs-overlay, .mejs-poster {
  width: 100% !important;
  height: 100% !important;
}
.mejs-mediaelement video {
  position: absolute;
  top: 0; left: 0; right: 0; bottom: 0;
  width: 100% !important;
  height: 100% !important;
}

Responsive Video?

Remember how responsive images is a hot topic because we're trying to be responsible and not serve images that are un-needed-ly large? Video has that same problem only compounded by ... uhm ... as many frames as there are in the entire video (probably a lot).

One half-janky solution is to serve different video sources depending on browser window width. I have a tutorial on that here.

Another solution is to use media attributes on the video sources and just hope that the support gets better and it doesn't get removed.

<video controls> 
   <source src="video-small.mp4" type="video/mp4" media="all and (max-width: 480px)"> 
   <source src="video-small.webm" type="video/webm" media="all and (max-width: 480px)"> 
   <source src="video.mp4" type="video/mp4"> 
   <source src="video.webm" type="video/webm"> 
</video>

The best solution is to use a video service and they'll handle it for you.

Flexible Audio

You only "see" HTML5 audio if you specifically use the controls attribute on the element.

<audio controls src="audio.ogg">
  <p>Fallback.</p>
</audio>

The good news is that you just chuck width: 100%; on that bad boy and it'll be flexy flexy:

audio {
  width: 100%;
}

WebKit browsers are maxing the width of them out at 800px for some reason. But the player remains centered within the space. Opera and Firefox have no such maximum. They all have slightly different players but all do basically the same thing (play the sound and have play and pause buttons and stuff).

The only other very popular embedded sound player right now is the SoundCloud player and it's fluid width by default (go team!).

Comments

  1. Dave Z
    Permalink to comment#

    I don’t necessary believe in the whole grid thing for responsive design. I am working on a personal project now foregoing the grid approach. Its not hard when using default markup as containers with percentage widths. Gridless is an HTML5 & CSS3 boilerplate that takes a similar approach.

    My opinion is whatever time you may save with a grid template is irrelevant when you end up with bloated and non-semantic markup.

    • Permalink to comment#

      I’m not super huge on complex grid frameworks either, thus, [don't overthink it grids.](http://css-tricks.com/dont-overthink-it-grids/) But if you’ve got a main content area 75% wide and a sidebar 25% wide, that’s a grid, and it’s time to start thinking about flexible media.

    • Dave Z
      Permalink to comment#

      I agree and like your article on flexible media. I have been setting my images up this way. I never looked at 2 percentage width content blocks as a grid,but see your point.

      I will definitely check out your other article. Thanks.

    • Kevin L
      Permalink to comment#

      You won’t have bloated and non-semantic markup if you used a CSS Preprocessor like SASS to its highest potential.

      If that happens in result of using a grid, it’s not being implemented correctly. Even the most grid-heavy users, advocators, or companies who know how to use a preprocessor such as SASS would have pursued the way of using their grid without adding much, if not any additional markup in result of it.

      Preprocessors were built to fix such a problem with vanilla CSS, outside of making development with CSS faster, simpler (ultimately), and more easier to read. Including things like placeholder selectors in SASS 3.2, there’s essentially no excuse to have ‘semantically useless classitis’ and being a ‘competent preprocessor user’ in the same sentence.

      Foundation is a framework that uses SASS with a lot of mix-ins to do just that. Bootstrap even allows you to, but most don’t leaverage or bother with LESS to achieve the same (or similar effect). If you try it yourself, you will see you can associate grids to just the classes or ids of your actual content.

      This means no need to have ‘omega3 last’, ‘grid3′ or all sorts of grid class mark-up you’re probably familar with seeing with older grid implementations.

  2. chandler
    Permalink to comment#

    Great post and good resources.

  3. Ralf
    Permalink to comment#

    I have this line added to my flexible img class:

    width: auto\9; /* ie8 */

    I don’t know why, but it should fix some IE bug… now, is this really necessary?

  4. Permalink to comment#

    Two things:

    1. What if you’re working with developers that barely have any clue about HTML5 or even best practices? In my personal case, posts like these although incredibly useful and helpful, there’s no way I’m ever going to use anything mentioned here. FAIL.

    I seriously envy those that can…

    2. Instead of “Bandwidth Media Queries”, shouldn’t it just be “Bandwidth Queries”?

    I mean, Bandwidth really has nothing to do with Media.

    Just saying…

    Thanks for the info Chris.

    • Permalink to comment#

      HTML5 is still, in my opinion, in it’s baby stages. A lot of people want to hop on the band wagon, but a lot of people don’t honestly know what best practices are and what best techniques are. HTML5 is a buzzword, although it comes with a lot of great stuff, it’s still a buzz word. CSS3 on the other hand… Well, let’s just say CSS3 is going to revolutionize the web as we know it.

      On your latter note. I am confused on your statement about Bandwidth Media Queries. You can just say responsive elements. Such as the ones he listed above, such as; Video, Audio, and Images. That’s about it.

      The web is enduring a time where simplicity is making a comeback to combat that of which is the future. Retina Display, Mobile Devices, etc.. We no longer live in a pixel perfect world, and you better get on board because before too long. These practices, or evolved practices, will be something that will be required for a job. Think about it as Tables versus Divs. The battle lasted years, until people realized that Tables suck, and are only truly meant for tabular data.

  5. Permalink to comment#

    Thank you for all of these great tips Chris.

  6. Permalink to comment#

    Just yesterday I worked at making fitvid work for the jwplayer and I couldn’t for the life of me figure out how. Are there docs for it anywhere? It looks like it’s really only for videos coming from popular hosting sites like youtube and vimeo.

  7. Permalink to comment#

    As always, good stuff. I first learned the responsive video trick from Ethan Marcotte during his presentation at An Event Apart.

    An interesting point that was made at said conference is that Responsive Design is nearing the end of its run. Instead of considering it a “fad,” many folks in the developer community are starting to realize that this (responsive design) is just generally a good idea for all projects. Responsive design won’t die – it will simply become part of the standard toolkit for developers.

    Articles like this help further that, and I appreciate the time you took to write it.

  8. Very nice blog post Chris. Always useful to grab further informations about responsive design nowadays.

    I really like the padding method from Thierry Koblentz to keep responsiveness. Very, very clever.

  9. Richard Lewis
    Permalink to comment#

    Nice article, I’m embracing responsive design as we speak :), I am having a problem getting google maps api javascript v3 to play nice. Has anyone succeeded in getting this responsive, to behave just like an img would if you set img{max-width:100%}

    • cnwtx
      Permalink to comment#

      Hmmmm. . . Seems I did that once, although I made it responsive to fill the whole browser window, then embedded that via iframe. It’s been a while since I did that, and I’m not sure exactly how I did it.

    • Permalink to comment#

      There si a jQuery plugin to make Google Maps responsive, but I did’t try myself so i can’t tell you much about it other then the link to the article.

      http://joggink.com/2012/01/responsive-google-maps/

  10. Permalink to comment#

    A good article on responsive design. I have been trying to adopt some of the responsive design techniques in my work and this will be one of them.

  11. Roma Serebryakov
    Permalink to comment#

    Great research and very useful info. Thanks!

  12. Permalink to comment#

    Lot’s of great tips here….especially the tips in regards to those video services….they look great….I am talking about Sublime Video and MediaElements.js …These are new to me…but will give the a try…

    I agree 100% in regards to HTML5 video…pure HTML5 video using the video tag is a major pain….just use a video service and call it done….for most clients this solution will work well…

  13. Permalink to comment#

    @Dave Z: I recently wrote an article about a nice way to work with grids. It’s about Neat and you don’t need that unsemantic HTML: http://stefanvermaas.nl/html-css/designing-html5-pretty-neat-huh/

    Thanks Chris for sharing these useful tips!

  14. Permalink to comment#

    Chris- Does fitvids.js support Google Maps’ iframes? If not could you add support?

  15. Permalink to comment#

    This post covers just about everything you need. =] I’ve been working on a base responsive stylesheet that has much of this in it, including video wrapper helper classes like class=rwd-wrap-16:9 and class=rwd-wrap-4:3

  16. dory
    Permalink to comment#

    Hi there,
    thanks a lot for this. I am working with the responsive vid embed from youtube. specifically I am embedding a playlist.
    Oddly enough, embedded responsively, the playlist doesn’t play further than the first video. Embedded with the default code supplied by youtube however, the videos cycle through the playlist like a charm. Seems odd that ‘width:100%’ should keep the videos from playing, but can’t find any other bug. Do you maybe have a hunch?

  17. william
    Permalink to comment#

    Currently running into an issue where IE 9 will resize the width of an image element that references an svg file (<img src="logo.svg">) but the height will not scale, even with height: auto; :’(

  18. Madeleine
    Permalink to comment#

    I really needed a simple way to make Vimeo videos responsive, so I’m super glad I’ve found your article. Thanks a million for the tips, Chris!

  19. Great post Chris, as always. There’s a typo: aspet (aspect) ratio (2 times).

  20. benny
    Permalink to comment#

    hi, i’m new here, but really love css-tricks.com. i have some question.

    i used to hide image using display none for responsive page, but how do i dynamically prevent the image/object from loading, if user screen is small?

    can you give a tip? using a script maybe?

    thanks!!

  21. @benny, if it’s okay to NOT load images without JavaScript (and that is a pretty big caveat), then you can create an element with data-image="imagesrc" and then use JS to modify the element.

    E.g., use this HTML: <a href="foo" rel="nofollow"></a>

    And this JS (this assumes jQuery):

    $('a[data-image]').addResponsiveImage();
    
    $.fn.addResponsiveImage = function() {
      return this.each(function() {
        $(this)
          .addClass('image')
          .html('')  
        })
    }
    

    You’ll first need to check if your screen is the right width, but hopefully that gets you on the right track. I used this technique @ http://arvadacenter.org.

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".