Displaying Alternate Content With Media Queries

By: Daniel Imbellino
Updated: Feb 28, 2013

Use Media Queries To Display Alternate Content Depending on Rules You Define in Your CSS

Scenario: You decide to use media queries to design your site for a multitude of LCD screen sizes and aspect ratios, however, Some of the applications you plan to embed don't appear properly at alternate resolutions. What do you do? This is a complicated situation.

Let's say you have a video for instance, and you need that video to render at different sizes depending on the resolution, LCD screen size, etc. However, media queires do not hide elements, even if they're not declared! The elements will still show up on the page, albeit, with no style information, most likely appearing at the top left corner of the screen. Here we're going to create a few sets of media queries, incorporating our fictitious video, and all elements using CSS ID's. We will then use the "display: none;" property to force our video to appear at a certain resolution depending on the media query being used.

So here's our media queries:

@media screen and (device-width: 1280px) and (device-height: 1024px) {
#videolarge {width: 640px; height: 480px; position: absolute; left: 30%; top: 40%; }
}

@media screen and (device-width: 1024px) and (device-height: 768px) {
#videosmall {width: 440px; height: 440px; position: absolute; left: 30%; top: 40%; }
}

So we have two sets of media queries that will be used to reference the same flash video in our pages, albeit, at different resolutions as stated above. Notice we used a CSS ID to reference our elements and assign them names. The problem here is that regardless of the width and height you specify, a flash video or game will just stretch beyond the allocated resolution you set in your media query, in order to achieve the size specified in your HTML itself. So this code is entirely ineffective!

Now we're going to create the same media queries, but add an additional ID element to each in order to reference our 2 alternate video sizes within our HTML:

@media screen and (device-width: 1280px) and (device-height: 1024px) {
#videolarge {width: 640px; height: 480px; position: absolute; left: 30%; top: 40%; }
#videosmall {width: 440px; height: 480px; position: absolute; left: 30%; top: 40%; }
}

@media screen and (device-width: 1024px) and (device-height: 768px) {
#videolarge {width: 640px; height: 480px; position: absolute; left: 30%; top: 40%; }
#videosmall {width: 440px; height: 480px; position: absolute; left: 30%; top: 40%; }
}

Now that we have two ID's (one for each resolution) for each media query, we now need to hide one element in each query using the "display: none;" property:

@media screen and (device-width: 1280px) and (device-height: 1024px) {
#videolarge {width: 640px; height: 480px; position: absolute; left: 30%; top: 40%; }
#videosmall {display: none; width: 440px; height: 480px; position: absolute; left: 30%; top: 40%; }
}

@media screen and (device-width: 1024px) and (device-height: 768px) {
#videolarge {display: none; width: 640px; height: 480px; position: absolute; left: 30%; top: 40%; }
#videosmall {width: 440px; height: 480px; position: absolute; left: 30%; top: 40%; }
}

Keep in mind each video is the same video, just being displayed using different resolutions within our HTML itself. Now we need to reference these videos within our HTML:

<html>
<head>
<title></title>
</head>
<body>
<div id="videolarge"> <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,16,0" width="640" height="480"> <param name="movie" value="large-video.swf"> <param name="quality" value="high"> <param name="play" value="true"> <embed src="large-video.swf" width="640px" height="480px" play="true" loop="false" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash"> </embed> </object> </div>

<div id="videosmall"> <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,16,0" width="440" height="440"> <param name="movie" value="video-small.swf"> <param name="quality" value="high"> <param name="play" value="true"> <embed src="small-video.swf" width="440px" height="440px" play="true" loop="false" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash"> </embed>
</object>
</div>
</body>
</html>
</div>

Notice we now have two "div's" we created, one for each video (one for each resolution). Now screens measuring 1280x1024 will render the larger video only, while as the screens measuring 1024x768 will render the smaller video only. Obviously the video being displayed at 640x480 resolution on the smaller screen will take up too much space, and likewise the smaller video at 440x440 would be too small, effectively not taking up enough space on the larger resolution. We have now effectively done away with this problem altogether! You could even use 3 sets of videos or more if you wanted too, all tailored to render at a specific resolution.

NOTE: Don't use the "display: hidden;" property, search engines don't like this! If they think you are hiding text, links, etc, they may get mad and penalize you! Instead, stick with the "display: none;" property. "display: none;" doesn't actually hide an element, instead it doesn't render the element altogether, just the opposite of "display: hidden;". The "display: hidden;" property still renders the element within the page flow, although you don't actually see it, it is still there, so stick to "display: none;" and everything will be fine.

We could also use this same approach for any given element really, not just flash games or videos. You could use an alternate banner for each resolution, both may look exactly the same, but each one scales to the appropriate screen size accordingly.

You don't have to use "device-width:" or "device-height:" either. You can use "min-width:", "min-height:", "max-width:", or "max-height:", etc. There is still limited support in major browsers though for using aspect ratios directly. Using "aspect-ratio: 4/3", etc, may cause problems. It's best to stick with "device-height:", "device-width:", "height:", "width:", "max-height: or width:", etc. Note here, when we state a height or width, or max on min height or width, we are referring to the size of the browser window as measured in pixels, and not the size of the screens resolution. On the other hand, the "device-height:", "device-width:", "max-device-height:", "min-device-width:", etc, actually refers to the screens native resolution itself, and not the size of the browser window that is displaying the code.

You might be thinking, how come I need to reference multiple videos and use the "display: none;" property at all, when I can just specify the height and width of my games or videos directly in my CSS? As we stated before, Flash games, videos, and many other video and multi-media protocols will scale to the size specified within your HTML regardless of the size of the container specified in your CSS. Also, many flash games, videos, etc, are encoded using a fixed height and width when they were originally encoded, so their is no way to specify the height or width for these elements either in your HTML or CSS entirely!

You could even use this technique to display say an image at one size on deskop and laptop LCD screens, and display an alternate size of the image on smaller mobile device screens, such as smart phones and tablet PC's. Or you could use this technique to show alternative elements depending on the resolution of the screen rendering the content. You could have completely different content (textual, multi-media, etc), return depending on screens resolution, browser dimensions, etc. Although you shouldn;t use Media Queries to design in this matter as search engines like Google frown upon sites that don't return the same content to all users. It is however justifiable for returning the same elements in various sizes, since you are still effectively returning the same content to all viewers including search engines.