Skip to main content

Mobile advertising using responsive ads

Online advertising is a beast that is inherently un-responsive. Ad blocks with set dimensions are served from a 3rd party provider, making it is as inflexible as a concrete post. So when someone starts talking about responsive ads everyone will always go a little quiet, until someone in the room mutters something like “you can have responsive ads, providing all ad slots on the page are 300 wide”.

Despite that seemingly common attitude, after a little thought it’s really not that difficult to get your head around the concept of responsive ads: An ad provider serves our website three different ad sizes, one for each screen size we’re targeting. We then use a little JS and CSS media query love to show and hide each ad slot depending on the client’s device. Pretty straightforward right?

 

by jack.taranto /

The challenge

CSS media queries can easily be used to show and hide elements on a page based on a device’s screen width. So lets start with that. We’ve got our three different ad slots, say a Bellyband (900x125), a Leaderboard (728x90), and a Mrec (300x250), and we’re serving these to a desktop, tablet & mobile device, respectively. So after a little hard work we craft up three media queries and a little bit of display:none action, and low and behold our ads are responsive. The desktop ads are showing for desktops, the tablet ads are showing on tablets, and the mobile ads are showing on mobiles. Time to pack up and go home.

So tomorrow morning we come back in, and awaiting us is an email from our ad department. It says something about the impression rate of all the ad sizes being exactly the same. Something’s up. The different devices are still recording impressions for all ads as a simple CSS show/hide is not enough to tell our ad provider not to record an impression. We need to stop them from rendering in the first place.

The players

Now, it’s a little bit of a tricky thing to stop an ad from rendering based on a user’s device. And it’s something which is obviously going to require a dose of Javascript.

We still need CSS Media Queries

As in the example above these little bad boys, being the most important organ of the responsive body, are still the core behind our method of rendering responsive ads. They are just going to be used a little less directly.

Enter modernizr.js

This beauty of a script is designed to allow backwards compatibility for websites implementing fancy new CSS3 or HTML5 techniques. Forget all that, we’re just going to be compiling the version of modernizr.js that allows CSS Media Queries in javascript.

And the big boy: Google DFP

Google Doubleclick for Publishers was the ad platform we last used to implement our responsive ads. Google DFP has no built in pro-responsive abilities however, it’s just a solid platform for serving ads, and that’s why it was chosen. The only important thing to realise here about DFP, is that all the examples in this article revolve around DFP’s JS calls. However with a little love and patience, I’m sure you’ll be able to convert these examples to work on the ad platform of your choice.

The bit parts & stand ins

Naturally jQuery will have it’s own part to play and there’ll also be a custom jQuery plugin that does a fair whack of the work.

The fundamentals

Firstly, we need to add some HTML for the ad to appear in:

<div id="adblock-mrec" style="width:300px;height:250px"></div>

<div id="adblock-leaderboard" style="width:728px;height:90px"></div>

<div id="adblock-bellyband" style="width:900px;height:125px"></div>

Since we’re using DFP we also need to add some JS to the head of the page which will “setup” our ads so they can be rendered in the body later on:

<script type="text/javascript">
googletag.cmd.push(function() {   
googletag.defineSlot("/xxxx", [300, 250], "adblock-mrec").addService(googletag.pubads());    
googletag.defineSlot("/xxxx", [728, 90], "adblock-leaderboard").addService(googletag.pubads());   
googletag.defineSlot("/xxxx", [900, 125], "adblock-bellyband").addService(googletag.pubads());   
googletag.pubads();    
googletag.enableServices();
});
</script>

Now our ad blocks are ready to be embedded into their respective divs. This is just a matter of adding the below code inside it’s appropriate div tag from above, so that it becomes something like this:

<div id="adblock-mrec" style="width:300px;height:250px">
<script type="text/javascript">googletag.cmd.push(function() { googletag.display("adlock-mrec"); });</script>
</div>

Here come our media queries. Let’s define these in a very simple manner:

/* For mobiles */
@media only screen and (min-width:320px) and (max-width:480px) {
    #adblock-mrec {display:block}
  #adblock-leaderboard {display:none}
    #adblock-bellyband {display:none}
}

/* For tablets in portrait mode */
@media only screen and (min-width:768px) and (max-width:1024px) {
    #adblock-mrec {display:none}
    #adblock-leaderboard {display:block}
    #adblock-bellyband {display:none}
}

/* For tablets in landscape and desktops */
@media only screen and (min-width:1024px) {
    #adblock-mrec {display:none}
    #adblock-leaderboard {display:none}
    #adblock-bellyband {display:block}
}

The above media queries are just enough to provide us with the basics of our mechanics and a failsafe: Our three ad blocks will now all render and record equal impressions, but as we view the site on different devices, the correct ad blocks will show and hide depending on the resolution of the device.

The main course

Now it’s time to solve the little issue of the incorrect impression count. To achieve this we’re going to use modernizer.js to allow the ad to embed only if it’s media query is satisfied. And we’re only going to do this once when the page is first loaded (so sadly there won’t be any fancy-ness where different ad’s load as certain tricky user’s resize their browser window to test the responsive-ness of our ads...).

As you’re probably going to have somewhere between 50 and 500 ad blocks on any given page, we’re going to use a jQuery plugin to make this mechanism smooth and simple to call on many different ad blocks. It will look something like this:

$("#adblock-mrec").responsiveAd({screenSize: "mobile"});

You’ll need to call responsiveAd() for every ad block on the page, passing in “mobile”, “tablet”, “desktop”, “all” or a combination of the first three. Like so:

$("#adblock-mrec").responsiveAd({screenSize: "mobile,tablet,desktop"});

You’ll also need to remove the script tag that previously displayed the ad from within it’s div. So all your ad divs will look like this again:

<div id="adblock-mrec" style="width:300px;height:250px"></div>

Now here comes our jQuery plugin, first in full:

(function($){
   $.fn.responsiveAd = function(options) {

     var opts = $.extend({
       screenSize: 'all'          
     },options);

     this.placeAds = function(screenSize) {

       var obj = this;

       var deviceSize = '';
       if (Modernizr.mq('only screen and (min-width:1024px)')==true) {
         deviceSize = 'desktop';
       }             
       else if (Modernizr.mq('only screen and (min-width:768px) and (max-width:1024px)')==true) {
         deviceSize = 'tablet';
       }       
       else if (Modernizr.mq('only screen and (min-width:320px) and (max-width:480px)')==true) {
         deviceSize = 'mobile';
       }

       var placeAd = false;
       if (opts.screenSize.search('all') != '-1') {
         placeAd = true;
       }
       else if (screenSize.search(deviceSize) != '-1') {
         placeAd = true;
       }

       if (placeAd == true) {
         script = document.createElement("script");
         script.type  = "text/javascript";
         script.text = 'googletag.cmd.push(function() { googletag.display("'+obj.attr('id')+'"); });';
         
         id = obj.attr('id');
         document.getElementById(id).appendChild(script);
       }     
     }        
     
     return this.placeAds(opts.screenSize);
   };
})(jQuery);

I’ll break this down for you so you’re clear on all aspects of the script.

$.fn.responsiveAd = function(options) { 

var opts = $.extend({
  screenSize: 'all'          
 },options);

 this.placeAds = function(screenSize) {

  var obj = this;

These first few lines declare our plugin, set up a default for the screenSize option, and declare the object that we’ll be working on (our div).

var deviceSize = '';
if (Modernizr.mq('only screen and (min-width:1024px)')==true) {
deviceSize = 'desktop';
}             
else if (Modernizr.mq('only screen and (min-width:768px) and (max-width: 1024px)')==true) {
deviceSize = 'tablet';
}       
else if (Modernizr.mq('only screen and (min-width:320px) and (max-width: 480px)')==true) {
deviceSize = 'mobile';
}

Here we test for the media queries (which are exactly the same as the ones we have used in our CSS above). For this to work properly we must have Modernizr loaded and compiled with it’s media query component. We are also declaring the screen sizes available to us - “mobile”, “tablet”, etc. It’s quite easy to extend these options, by adding additional media queries and specifying additional deviceSize values.

var placeAd = false;
if (opts.screenSize.search('all') != '-1') {
placeAd = true;
}
else if (screenSize.search(deviceSize) != '-1') {
placeAd = true;
}

Now we have a bit of search() action where we compare the active deviceSize with the screenSize value(s) that are passed into the plugin. This method allows us to specify “all” so we can have the ad render regardless of the device, and it also allows us to specify multiple screen sizes so some ad blocks can show on multiple devices.

if (placeAd == true) {
  script = document.createElement("script");
 script.type  = "text/javascript";
  script.text = 'googletag.cmd.push(function() { googletag.display("'+obj.attr('id')+'"); });';
         
 id = obj.attr('id');
  document.getElementById(id).appendChild(script);
 }
}  

And finally we use an awesome bit of classic JS, the document.createElement() function to build the script tag that embeds the ad - providing the appropriate media query has been satisfied.

The real world

Seeing as we’ve used JS to render the ad based on the user’s device, the ad will not record an impression if it’s not rendered. And we’ve done this using CSS Media Queries, instead of some convoluted jQuery or Javascript based checking of browser dimensions. Add to that a CSS failsafe, so tricky users like you and me can resize the browser window to our heart’s content without the wrong ad size turning up.

If you want to see this exact method in action, head on over to NovaFM. There we have a plethora of ad sizes working on a variety of different screen sizes. And in addition to that we also have billions of potential dynamic ad tags that allow Nova’s ad managers to assign a different campaign to every single page & ad slot on the site - if they want to...

I’ll leave it up to you to devise similar methods of dynamic embedding, and indeed to convert this method over to another ad platform, however regardless of what platform you are using the concept is the same.

Posted by jack.taranto
Front end developer

Dated

Comments

Comment by Rudolf

Dated

Thanks for the great work - i have been searching for some time now to use google dfp with a responsive design and somehow stumbled on your website - i am busy testing it at the moment and sort of got it going but have some issues - i will mail you to seek some assistance

thanks again for doing most of the work already

Comment by Robert Barnes

Dated

Hi - Just wanted to say thanks for such a detailed post, (hopefully) solving the exact problem I'm having. Great to see it's from a fellow Aussie too! I'm mid development at the moment, but if you don't hear from me again then it worked.

Cheers, Rob

Comment by jack.taranto

Dated

@Rudolf and @Rob thanks guys, feel free to post any questions here.

Comment by Frank

Dated

Jack,

This has been incredibly helpful, it's saved me a ton of time getting a responsive redesign up and running. I have the code up and running on a test WordPress site, but I'm having some trouble getting the mobile ads to render. For some reason the desktop ads work fine but mobile is a problem (I'm only using 2 sizes). Basically the ad never loads on the mobile site. Think there could be some sort of JS conflict with the rest of the code on the site?

Comment by jack.taranto

Dated

@Frank, thanks that's great!

If the ads aren't rendering for you the first thing I would check is the HTML. See if the actual ad markup is being added to the page (in Google DFP these are iframes) if it is, the plugin is doing it's job and it's possible the ad only has a flash version and hence is showing up as blank (you'll need to make sure all adds have gif/jpgs versions to work on mobile).

If the markup isn't being generated, then the fault lies with the plugin. I would check your media query (inside the plugin) and make sure it's evaluated as true for your mobile device.

Comment by Conn Prosser

Dated

Word up aussie developer! This fully works. Thank you for posting this. I can't believe the solution to this problem is not more commonly known.

Comment by Frank

Dated

Thanks, I'll give it a shot. The mobile ads are kind of hit or miss, it may just be that they're not showing up consistently in my test environment because it's not a well-known public site (yet).

Comment by Ben

Dated

The big issue with this approach is that you are still loading all ads, although you disabled the tracking and hiding them with CSS. If I out-comment CSS hiding all ads are still loaded. If you have multiple ad sets each 3 versions, this solution would be ultra heavy on mobile. Also CSS hiding of ads is against Google TOS.

Remember CSS hiding does not prevent ads from being loaded.

A solution like this, where only the needed ad is actually loaded sounds much better:
http://www.labnol.org/internet/google-adsense-responsive-design/25252/

Comment by jack.taranto

Dated

Hey @Ben I'm not sure you understand the approach. The jQuery plugin is actually preventing the loading of the ad - so the ad tag never makes it onto the page unless the media query is satisfied. The CSS that hides the ads is only there as a failsafe in case the browser is resized after the page and correct ads have been displayed.

The approach you have linked to is actually very similar - it is checking the device width and choosing which ad size to render. Keep in mind that this approach does not use media queries in javascript so isn't quite as elegant.

Comment by Brad

Dated

I can confirm this works. Very nice tutorial, and thanks for the demo package as well. I can really maximize DFP's ad size potential on mobile devices with my personal clients.

Comment by Ian

Dated

Hi Jack,

I've been working this weekend on a responsive design. I've created one additional query for a 480 banner but when I load some of the pages, I'm getting multiple banners where there should just be one.

var deviceSize = '';
if (Modernizr.mq('only screen and (min-width:1024px)')==true) {
deviceSize = 'desktop';
}
else if (Modernizr.mq('only screen and (min-width:768px) and (max-width: 1024px)')==true) {
deviceSize = 'tablet';
}
else if (Modernizr.mq('only screen and (min-width:481px) and (max-width: 767px)')==true) {
deviceSize = 'smalltablet';
}
else if (Modernizr.mq('only screen and (min-width:320px) and (max-width: 480px)')==true) {
deviceSize = 'mobile';
}

And in my test page, here's the stuff at the bottom:

$('#adblock-mrec').responsiveAd({screenSize:'mobile,tablet,desktop'});
$('#adblock-ldr').responsiveAd({screenSize:'tablet,desktop'});
$('#adblock-small').responsiveAd({screenSize:'smalltablet'});
$('#adblock-mldr').responsiveAd({screenSize:'mobile'});

The mrec is in every size. That's intended. Just before writing this comment I reloaded a page at 400px. Both mldr and small fired. I looked at generated source in Firefox and both of their divs had the google dfp code inserted. Anything else I should be looking for?

Comment by Troy

Dated

Just a heads up on this guys, to use this you must take out the googletag.pubads().enableSingleRequest(); line. Caused me a lot of trouble, so I thought I'd share a quick fix with anyone who wants it. :)

Comment by jack.taranto

Dated

Thanks for that Troy! The code example's I have used above for DFP should work okay - providing there isn't anything added or missing in there.

@Ian - I've had a look at your code and it looks fine. You have added the extra display in the same manner as the others so I don't see any reason why it would be rendering for the incorrect media query. Try putting some debug code inside the else if statement for the small tablet to see what Modernizr is doing. Let me know how you go with it.

Comment by Dave

Dated

@Jack This is awesome. Thanks so much for sharing. There's one part I have a question about. Does this override the googletag.pubads().collapseEmptyDivs(); option that hides the ad unit if an ad isn't served? I realized after implementing this approach that my empty units aren't collapsing.

Comment by jack.taranto

Dated

@Dave - you can still use the collapse empty divs option.

Comment by james

Dated

This is great! It has saved me a lot of hassle. Thanks!
It wasn't working for me initially as it was still generating all ads despite travelling through the responsiveAd function for each. After a bit of hair pulling I realised it was all my fault as I had created an extra breakpoint called smallTablet and as it contains 'all' it was being flagged as being shown on all devices. Rookie error!
Anyway, Thanks again :)

Comment by Steve

Dated

Nice article, this is what I was leaning towards as a solution, but hadn't seen any real world examples so was a little hesitant.

Have there been any changes in DFP that have made implementations like this any easier that you're aware of?

Comment by Sidd

Dated

Hello experts! I am publisher currently working on finalising my website to facilitate online trading. Thought I'll ask this question to all you experts out there, whats the best third party platform to facilitate banner advertisement on the website as I am trying to build some traffic and generate some revenue through banner ads. The aim is to use a third party banner ad platform and eventually custom design to ficilate the advertisement inhouse

Cheers
Sidd

Pagination