Responsive Ads
Our prototype responsive ads allow you to design one ad for every screen.
The problem with ads on the web
Web advertisements haven’t quite kept up with the web’s shift to responsive design. Mobile ads exist, yes, but they exist as separate entities from desktop ads. A campaign may include a handful of ads that work on set screen sizes (phone, tablet, desktop), but they aren’t truly fluid and responsive. Additionally, if a designer needs to edit the content of an ad, it has to be changed on each ad size being delivered. Lastly, while HTML ads do exist, they can be heavy on file size.
Here’s our solution
We’ve prototyped an implementation of responsive ads that’s completely fluid, lightweight, and built using web standards. Because they’re just embedded webpages, editing content is as easy as firing up a text editor. Styles, scripts and all, our ads average about 15K in size, while still being fully animated. And best of all, an ad server need not determine what ad to send to the client based on the device—one ad will work on any screen. Here are the core features in our proof-of-concept:
Features
Fluid, responsive ad units
We took a handful of core sizes for web advertisements—the rectangle, leaderboard, skyscraper and billboard—and made them responsive. That medrect may be 300x250 by default, but it will scale down proportionally as far as it needs to go. A leaderboard will maintain its standard height but stretch horizontally, and the contents of the ad will change based on the available space. But our biggest trick is the leaderboard that switches orientation on larger screens, becoming a skyscraper. Try resizing your browser window (if you can) and watch the ad to your right change.
Rectangle
Scales proportionally
Leaderboard
Scales fluidly
Flexible unit
Changes orientation
Easy animation
We built a simple tool in Sass that allows us to quickly assemble a series of animations into a timeline. This lets us define a style of animation, along with a duration, easing function, and a gap of time to wait before the next animation plays. The result is a seamless chain of animations like the ones you see below (and don’t worry, it looks great on browsers that don’t support animation):
How does it work?
The ads themselves are inserted using the humble iframe. This gains us one immediate benefit: a media query inside an iframe essentially functions as the fabled element query. This means the ad’s content can change purely based on its own dimensions, not the dimensions of its parent window.
The markup looks something like this:
<div class="ad medium rectangle"> <iframe data-ad data-href="http://www.zurb.com" data-src="ad2.html"></iframe> </div>
To keep pages loading fast, the ads are loaded asynchronously, after the rest of the page is done loading.
The div around the iframe allows us to maintain a rectangular aspect ratio on the unit as it scales up and down. We use this same trick for the flex video component of Foundation, which keeps embedded videos at the right aspect ratio as they resize.
The technical bits: working cross-domain
Most all web advertisements are delivered by external services. This means a website displaying ads will exist on one domain, while the ads themselves will exist on another, perhaps controlled by an ad agency. For security reasons, web browsers are careful about what sort of interactions can take place between content from different domains. A web page cannot manipulate, or even view, the underlying JavaScript of an iframe if it’s not in the same domain. Likewise, the iframe cannot access its parent window. This presents a problem for us, because we need the page to communicate with its ads. For example, an ad’s animations should not begin playing until the window scrolls past it.
Thankfully, there’s a fairly painless solution called postMessage. Although we can’t access the window object of any ads, we can call .postMessage()
on them to send a message.
var ad = document.getElementById("#ad"); ad.contentWindow.postMessage("Hello? Can you hear me?", "*");
The asterisk in the above code indicates that this message can be sent to an iframe from any domain. However, it’s considered more secure to actually specify an allowed domain (i.e., the domain of an ad network’s server). The iframe can then pick up the message and react to it by listening for the message
event:
window.addEventListener("message", function(event) { // event.data contains the message });
This works in all browsers, and even goes back to Internet Explorer 8!
Example: activating animation
Our prototype will keep the animations inside an ad paused until the user’s browser scrolls down to the ad. Whenever the user scrolls their window, the JavaScript calculates if any ad units have become visible. If they are, the page sends the ad a message that says “startAnimation”. The ad picks up this message and then activates animations on itself.
An even bigger problem: Mobile Safari and iframes
Mobile Safari, the primary browser on the iPhone, iPad and iPod Touch, has a few major issues when it comes to displaying iframes properly. The biggest is that Mobile Safari completely ignores any height declarations set on an iframe. Instead, it just looks at the height of all the content in the iframe, and expands the frame out so you can see all the content.
It’s confusing, yes, but there’s an easy workaround: just wrap the iframe in a container and give it the CSS style overflow: scroll
. The result is a scrollable box for viewing the iframe in. Easy, right? Well, unfortunately for us, we ran into a much more obscure and complex problem.
The rectangular ad units maintain a 6:5 aspect ratio. The iframe inside simply resizes itself to fit the available space. Thankfully we weren’t encountering these strange height issues on Mobile Safari with our ad units—until we added in animation.
We never found an explanation for this quirk, but when an ad unit contained animated elements, the height of the iframe would expand from around 250px like it should be, to over 2000px, despite there not being 2000px of content in the frame. As soon as the animation ended the frame would collapse back up to its correct height. Through extensive testing we found that even paused animations would trigger this strange bug. The only way to get rid of it was to remove the animation properties from all elements.
Although we never found a way to fix this specific issue, we did settle on a simple workaround: add another aspect ratio container. We’re already using one aspect ratio container around the iframe to constrain its proportions. So we added a second aspect ratio container inside the ad. The iframe is still 2000px tall for whatever reason, but the actual content of the ad stays the proper size, so you can’t see the difference.
Score an awesome product engineering or design job
Thoughts?
Let us know what you think about our ideas for responsive advertising in the comments for our blog post about this Playground piece.
Stay up to date
We'll keep you informed on our responsive ad project as it develops.
Browser Support
We tested our prototype on a range of devices, and the core functionality is working in:
- Chrome
- Animation in iOS7 is somewhat buggy (especially when paired with scrolling), so it's been disabled for this demo in Mobile Safari.
- Firefox
- Safari
- Internet Explorer 9–11
- IE9 doesn't have animation support, so the ads display a static version of themselves instead.
- iOS 7
- Android 4.4