How to Use Google DFP and Adsense on a Responsive Website


This article shows how to mix Adsense and direct campaigns using Google DFP and get it all working on a responsive website.

Google also offer Adsense Direct which allows the publisher to negotiate an ad deal that will be served through adsense.

The Challenge

There is no one-size-fits-all solution for a responsive website.

RWD continues to evolve with an increasing number of design patterns. In the advertising world things are also continuously changing.

Every site is unique and it is that particular site’s design, content, and UX that will govern how media breakpoints are set and where ad units are displayed – not any cookie-cutter approach.

Mobile web usage is growing rapidly – our site went from 12% mobile traffic to 44% mobile in exactly 2 years. That’s 430% growth.

The main goals are this:

  • Allow some ad slots to serve different sized creative depending on the viewport size.
  • Allow some ad slots to be hidden on different viewports (e.g. a wide layout might have 3 adslots, in mobile only a single ad).

Solution 1: Using CSS and jQuery to choose different DFP Ad Units

This is what we are doing at the moment (props to levo).

Twitter Bootstrap has some handy CSS classes that allow you to show and hide DIV blocks depending on the viewport size. The CSS below is for desktop size (this is from Bootstrap 2 – a little outdated).


.visible-phone { display: none !important; }
.visible-tablet { display: none !important; }
.hidden-phone { }
.hidden-tablet { }
.hidden-desktop { display: none !important; }
.visible-desktop { display: inherit !important; }

Our mobile media query looks like this:

@media screen and (max-width: 650px) {
	.hidden-desktop { display: inherit !important; }
	.visible-desktop { display: none !important; }
	.visible-phone { display: inherit !important; }
	.hidden-phone { display: none !important; }

This allows us to set any DIV to show or hide depending on the viewport size.

<div class="hidden-phone">
	This information will only appear on desktop layouts.

Adding the DFP Ad Units

Let’s say we have a sidebar that should show a 300×250 ad to desktop, and a 250×250 to tablet. We set up two DIVs like this:

<div class="adslot visible-desktop" id="div-gpt-ad-1325545340561-0" style="width: 300px; height: 250px;" data-dfp="Adunit_300x250" data-cids="7956726685"></div> 
<div class="adslot visible-tablet" id="div-gpt-ad-1325545340561-1" style="width: 250px; height: 250px;" data-dfp="Adunit_250x250" data-cids="5374604278"></div>

Then in our Javascript we do the following (you must use the Google Publisher Tag – GPT, and be using jQuery).

Firstly the GPT call.

<script type="text/javascript">// <
var googletag = googletag || {};
googletag.cmd = googletag.cmd || [];
(function() {
	var gads = document.createElement('script');
	gads.async = true;
	gads.type = 'text/javascript';
	gads.src = '';
	var node = document.getElementsByTagName('script')[0];
	node.parentNode.insertBefore(gads, node);


Then after this:

	var dfpslots=$("#wrapper").find(".adslot").filter(":visible"),
	slot= new Array();

	if (dfpslots.length) {
		googletag.cmd.push(function() {
				slot[i] = googletag.defineSlot('/9999999/'+$(this).attr('data-dfp'), [$(this).width(), $(this).height()], 	$(this).attr('id')).addService(googletag.pubads());
				if ($(this).attr('data-cids')) slot[i].set("adsense_channel_ids", $(this).attr('data-cids'));

			//googletag.pubads().enableSingleRequest(); // Breaks channel reporting


This code iterates through all visible ad slot DIVs, then creates DFP Ad Slots for each one (replace 9999999 with your dfp id), incorporates AdSense channels with the data-cids attribute.

After setting up each slot, the display method is called for each one.

To check your DFP implementation append ?google_console to your page’s URL and refresh. Then hit Fn-Ctrl-F10 (or Ctrl-F10 on Windows).

Ad Units with Multiple Sizes

If you have an ad unit where you want to serve more than one size (for example a 300×250 and a 300×600) you will need to alter the code.

Firstly the ad call (this might be in a sidebar):

<div id="div-gpt-ad-1325545340561-0" class="visible-desktop" data-sizes='[[300,250],[300,600]]' data-dfp="Adunit_Sidebar" data-cids="7956726685"></div> 

Remove the hard-coded width and height.
Add in a new attribute called data-sizes, and include an array of different ad sizes.

Now on the setup code:

			 if ($(this).attr('data-sizes')) {
				 var sizes = $(this).data('sizes');
				 for (var i=0; i < sizes.length; i++){
			 } else {
				 var sizes = [$(this).width(), $(this).height()];

			 slot[i] = googletag.defineSlot('/1084798/'+$(this).attr('data-dfp'), sizes, $(this).attr('id')).addService(googletag.pubads());
				if ($(this).attr('data-cids')) slot[i].set("adsense_channel_ids", $(this).attr('data-cids'));

We’ve added some new code to test if the data-sizes attribute exists. If it does, then extract out the sizes. If not, then look for the normal hard-coded width and height.

Then in defining the adslot we put in our sizes array. This will then pass the multiple sizes for DFP to do with as it pleases. Make sure your DFP ad unit is set to the multiple sizes also.

Solution 2: Showing / Hiding Ad Slots Without CSS

In the above solution we used the CSS styles (hidden-phone etc) to show or hide the relevant ad slots. This could be done in JavaScript instead.

<script type="text/javascript">// <![CDATA[
googletag.cmd.push(function() {

var width = window.innerWidth || document.documentElement.clientWidth;

if (width >= 768) {
	googletag.defineSlot('/9999999/myadunit_bottom_728x90', [728, 90], 'div-gpt-ad-3248237498728-2').addService(googletag.pubads());
else if ((width >= 300) && (width < 768)) {
	googletag.defineSlot('/9999999/myadunit_mobile_only', [300, 250], 'div-gpt-ad-3248237498728-1').addService(googletag.pubads());
// ]]></script>

With this approach the setting of the appropriate ad slots happens on page load only. Tablets and Desktops get a leaderboard, and Smartphones get a 300×250 instead of this.

Solution 3: DFP Responsive Ad Units

Google DFP have rolled out responsive mappings. Here you can set a series of preferred ad sizes based on browser size.

It’s a little complex, but once it is all working, it’s a good way of offering multiple creative sizes to a single ad slot based on viewport size.

  1. Include the GPT script
  2. Create a mapping for each creative size

Example – Leaderboard ad for all Screen Sizes

googletag.cmd.push(function() {
	var mapLeader = googletag.sizeMapping().
		addSize([320, 400], [320, 50]).
		addSize([320, 700], [300, 75]).
		addSize([480, 200], [468, 60]).
		addSize([768, 200], [728, 90]).
		addSize([1000, 200], [970,90]).
	window.LeaderSlot= googletag.defineSlot('/1084798/Test_Multi_Width', [320,50], 'div-gpt-ad-1393979881710-0').



Further on our ad slot declaration is standard DFP:

<div id="div-gpt-ad-1393979881710-0" class="wide-ad"><script type="text/javascript">
googletag.cmd.push(function() {googletag.display('div-gpt-ad-1393979881710-0'); });

Here’s how it works

  • Each addSize command matches a viewport size [width,height] followed by a creative size [width,height]
  • The viewport size works like min-width in CSS media queries.
  • Example addSize([320, 400], [320, 50]). – where the viewport width is >= (greater than or equal to) 320 pixels serve an ad with creative size of 320×50 (mobile leaderboard).
  • Our example will serve all primary leaderboard sizes for all different size viewports. Typically these would match your CSS media breakpoints.
  • There is one extra bit here: We will serve a 300×75 where the viewport is 320px wide AND the viewport height is >= 700px (e.g. a tall smartphone).

We would assign one (or many line items) to the ad unit, ensuring we have creatives set-up for everything we have listed in our mapping. If you have AdSense setup as backfill, AdSense plays nicely and will also serve the matching creatives that we have specified.

This is a powerful solution as we setup a single ad slot on our page, and serve multiple different sized ads to AND allow them to compete with AdSense backfill that also serves responsively sized creative.

In my testing I’ve noticed that using collapseEmptyDivs() seems to prevent the mappings from working properly.

You’ll notice I’ve set the Ad Unit size to [0,0] on the display call. I found that if the viewport was ever less than our mapping (e.g. less than 320px, DFP would display the creative size listed on display call – so by setting it to size 0 – nothing is displayed).

Refreshing Ads
It is possible to code for viewport resize – something like this works:

This adds an event listener for the resize event, and only fires it after 250ms (otherwise we have continuous refreshes).

We then pass the adslot variable to the DFP refresh method to redo the ad calls for that ad slot.

Go check out my working example here – it uses the code above.

Targeting DFP Ads

It is possible to have line items show up only on certain pages on your site.

Google Anchor Ads

Google now have a new ad unit called an Anchor Ad.

This is for mobile devices and the ad will stay fixed at the bottom of the user’s screen, even as the user scrolls up or down.

I have tested these, they work well although they are disruptive if you have forms on your page. It also seems they don’t seem to pay as well as normal ads of the same size.

I’m not convinced yet.

Other Solutions

There is an interesting script called LazyAds that allows you to wrap the ad calls in comments, and will only execute the tags if matching a media query.

UPDATE: Sep 13 – New Anchor Ads.
UPDATE: Oct 13 – New DFP responsive code.
UPDATE: Mar 14 – Complete overhaul.
UPDATE: Nov 14 – How to target URLs

Hi, I'm James, and for the last decade I've made a living by making my own blogs and websites.
Updated: September 15, 2016

1 Comment

Add a Comment