<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ravelrumba by Rob Flaherty</title>
	<atom:link href="http://www.ravelrumba.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ravelrumba.com</link>
	<description>web design &#38; development</description>
	<lastBuildDate>Sun, 19 Feb 2012 20:41:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Responsive Ads in the Real World: Ad Server Implementation</title>
		<link>http://www.ravelrumba.com/blog/responsive-ads-real-world-ad-server-implementation/</link>
		<comments>http://www.ravelrumba.com/blog/responsive-ads-real-world-ad-server-implementation/#comments</comments>
		<pubDate>Sun, 19 Feb 2012 15:27:29 +0000</pubDate>
		<dc:creator>Rob Flaherty</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[eMedia]]></category>
		<category><![CDATA[General Web]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[advertising]]></category>
		<category><![CDATA[media queries]]></category>
		<category><![CDATA[responsive advertising]]></category>
		<category><![CDATA[responsive design]]></category>

		<guid isPermaLink="false">http://www.ravelrumba.com/?p=1543</guid>
		<description><![CDATA[The last time I wrote about responsive design + advertising I put together a few examples demonstrating how an ad unit could respond to its environment. The demos were fun but in the real world, ads need to integrate with an ad server. This is a slightly greater challenge but I&#8217;ve had a few thoughts [...]]]></description>
			<content:encoded><![CDATA[<p>The last time I wrote about responsive design + advertising I <a href="/blog/responsive-ad-demos/">put together a few examples</a> demonstrating how an ad unit could respond to its environment. The demos were fun but in the real world, ads need to integrate with an ad server. This is a slightly greater challenge but I&#8217;ve had a few thoughts on it lately and I think it&#8217;s not as difficult as I&#8217;d originally imagined. So that&#8217;s what this post is about.</p>
<p>I&#8217;m guessing that most developers have not worked closely with ad servers and many may not be familiar with the technology behind web advertising at all. So before I get into it I&#8217;ll say a few <strong>brief</strong> things about the advertising ecosystem and how ad servers generally work.</p>
<h5>Ads are hard</h5>
<p><img src="http://s.ravelrumba.com/uploads/2012/02/advertising-ecosystem1.png" alt="" title="advertising-ecosystem" width="300" height="384" class="alignright size-full wp-image-1554" /></p>
<p>The thing about web advertising is that it&#8217;s not a simple two-party handshake. The process is full of intermediary parties and technologies, a summary of which is shown in the adjacent graphic. (Here&#8217;s a more <a href="http://www.cogmap.com/blog/wp-content/uploads/2010/10/LUMA-Display-Ad-Tech-Landscape-for-AdExchanger.jpg" target="_blank">detailed illustration</a> of the ad ecosystem&#8230; but be warned, it may hurt your eyes a bit.)</p>
<p>See, the challenge with responsive ad models isn&#8217;t with media queries or JavaScript, it&#8217;s introducing a solution that works for all these parties. There&#8217;s a timing element too that makes it more challenging. Responsive advertising is not something a publisher can wade into—the only way it works is for the publisher to have a complete set of &#8220;responsive compatible&#8221; campaigns. No sane publisher is going to sacrifice ad revenue for responsiveness, so whatever solution appears has to, in a sense, <strong>work all at once</strong>.</p>
<p>It&#8217;s not an insurmountable problem—ad vendors and start-ups will soon figure it out—but it requires a higher level of cooperation than the average innovation, meaning its introduction into the ecosystem will need to follow a different path.</p>
<h5>How ad servers work</h5>
<p>Publishers that sell display advertising manage ad campaigns through an ad server, which is basically <strong>a CMS for ads</strong>. Positions or zones for each ad unit are defined on the page and then campaigns are set up in the ad server and configured to flow into the positions based on a number of variables. The rest goes like this:</p>
<p>Usually the publisher (e.g., CNN.com) does not receive the ad directly from the advertiser (e.g., IBM) but from an agency (e.g., Blahblah Interactive Inc.) representing the advertiser. In addition, the ad itself (called a &#8220;creative&#8221;) is usually not given directly to the publisher but is instead uploaded to a third-party ad server (e.g., DoubleClick). The third-party ad server provides JavaScipt/Iframe &#8220;tags&#8221; that the publisher then loads into <strong>its</strong> ad server. Finally, the publisher&#8217;s ad server has its own set of tags that get implemented into the site templates, at last delivering the well-journeyed advertisement to its audience.</p>
<p>There&#8217;s another piece to the pie that involves ad networks and realtime-bidding demand-side platforms, but let&#8217;s leave that to the side for now. </p>
<p>The major players in the first-party ad server world include products like Google&#8217;s DART for Publishers, OpenX, Zedo, and 24/7 Real Media&#8217;s Open AdStream. The last is the one I&#8217;ve worked with the most and one I&#8217;m going to use for this article&#8217;s example.</p>
<p>So here&#8217;s an example of how ads make it onto the page using Open AdStream. We define the site, page, and list of ad units. There&#8217;s an optional <code>query</code> variable that we&#8217;ll use later. This is an <a href="/blog/cleaning-up-ad-server-scripts/">optimized implementation</a> of the ad server&#8217;s initial set-up code:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>script<span style="color: #339933;">&gt;</span>
<span style="color: #006600; font-style: italic;">//Ad set-up for RealMedia OAS ad server</span>
<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #003366; font-weight: bold;">var</span> url <span style="color: #339933;">=</span> <span style="color: #3366CC;">'http://ads.yoursite.com/RealMedia/ads/adstream_mjx.ads/'</span><span style="color: #339933;">,</span>
  pagetag <span style="color: #339933;">=</span> <span style="color: #3366CC;">'www.yoursite.com/'</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">,</span>
  listpos <span style="color: #339933;">=</span> <span style="color: #3366CC;">'Top, Bottom, Right1, Right2'</span><span style="color: #339933;">,</span>
  query <span style="color: #339933;">=</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">,</span>
  rns <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>Math.<span style="color: #660066;">random</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">substring</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">11</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 document.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&lt;script src=&quot;'</span> <span style="color: #339933;">+</span> url <span style="color: #339933;">+</span> pagetag <span style="color: #339933;">+</span> <span style="color: #3366CC;">'/1'</span> <span style="color: #339933;">+</span> rns <span style="color: #339933;">+</span> <span style="color: #3366CC;">'@'</span> <span style="color: #339933;">+</span> listpos <span style="color: #339933;">+</span> <span style="color: #3366CC;">'?'</span> <span style="color: #339933;">+</span> query <span style="color: #339933;">+</span> <span style="color: #3366CC;">'&quot;&gt;&lt;<span style="color: #000099; font-weight: bold;">\/</span>script&gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span></pre></div></div>

<p>Later in the page, the individual ad units are called in their places with this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>script<span style="color: #339933;">&gt;</span>OAS_RICH<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Top'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;&lt;/</span>script<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>script<span style="color: #339933;">&gt;</span>OAS_RICH<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Bottom'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;&lt;/</span>script<span style="color: #339933;">&gt;</span>
...</pre></div></div>

<h5>Responsive-ize it</h5>
<p>First let&#8217;s mention a few techniques that are <strong>not</strong> valid solutions. One is always loading the same number of units but hiding certain units for smaller screens. For reporting accuracy and to ensure that advertisers are not being charged for invisible impressions, it&#8217;s important that the page only requests ad units that are actually displayed.</p>
<p>Another is user agent sniffing to detect mobile/tablet devices as a way of requesting different ads or modifying layout. On its own, UA-based device detection isn&#8217;t necessarily a bad thing but I think most would agree it&#8217;s not a natural part of a responsive strategy. Responsive design is the alternative to UA-based device-specific sites. (Although, Luke Wroblewski does make an interesting case for combining the two <a href="http://www.lukew.com/ff/entry.asp?1392" target="_blank">here</a>.)</p>
<p>Oh, and I should mention that the problem we&#8217;re trying to solve concerns ad-based sites running multiple standard IAB ad units: 728&#215;90 leaderboards, 300&#215;250 medium rectangles, etc. That is, a site like Smashing Magazine that combines advertising and a responsive layout is not an example solution to our problem.</p>
<h6>Stop resizing your window</h6>
<p>I&#8217;ll break the bad news to you up front: you have to stop worrying about what happens when people resize their browser. First of all, <strong>no one does this</strong>. Yes, YOU like to resize your browser and watch DOM elements bend to your will—and so do I—but real-life regular people users don&#8217;t. And of course it&#8217;s not even possible on mobile and tablet devices.</p>
<p>This whole responsive thing isn&#8217;t about passing a CSS fluidity test. So let&#8217;s let it go.</p>
<p>The reason this matters is that page views and ad impressions (per unit) are expected to share a 1-to-1 relationship. An advertiser expects to be charged for an impression on a page view event, not a browser resize event. This synchronicity will eventually fade as we move to more AJAX-based content delivery, but for now it&#8217;s still firmly in place.</p>
<p>So this technique assumes that ads will be requested once per page load and will be determined by the size of the viewport <strong>at the time the page is loaded</strong>.</p>
<h5>Code: The Set-up</h5>
<p>The idea behind this is that we&#8217;re going to define a few contexts—mobile, tablet, desktop—and then conditionally serve a set of ads for each context. We start by assigning a list of ad positions and breakpoints based on common device screen sizes:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Define config</span>
<span style="color: #003366; font-weight: bold;">var</span> pageConfig <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
  mobile<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
    positions<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'Top'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
    breakpoint<span style="color: #339933;">:</span> <span style="color: #CC0000;">480</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
  tablet<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
    positions<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'Top'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Right1'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
    breakpoint<span style="color: #339933;">:</span> <span style="color: #CC0000;">728</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
  desktop<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
    positions<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'Top'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Bottom'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Right1'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Right2'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
    breakpoint<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>We&#8217;ll use JavaScript to determine the width of the screen. In the previous responsive ad demos I used <code>matchMedia()</code> but this time I&#8217;m going to use <code>document.documentElement.clientWidth</code>.</p>
<p>We&#8217;ll pass the width to a function that will evaluate it against our breakpoints and determine a context.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Function to determine screen context</span>
<span style="color: #003366; font-weight: bold;">function</span> setContext<span style="color: #009900;">&#40;</span>screenWidth<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> mobile <span style="color: #339933;">=</span> pageConfig.<span style="color: #660066;">mobile</span>.<span style="color: #660066;">breakpoint</span><span style="color: #339933;">,</span>
    tablet <span style="color: #339933;">=</span> pageConfig.<span style="color: #660066;">tablet</span>.<span style="color: #660066;">breakpoint</span><span style="color: #339933;">,</span>
    type<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>screenWidth <span style="color: #339933;">&lt;=</span> mobile<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    type <span style="color: #339933;">=</span> <span style="color: #3366CC;">'mobile'</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>screenWidth <span style="color: #339933;">&gt;</span> mobile <span style="color: #339933;">&amp;&amp;</span> screenWidth <span style="color: #339933;">&lt;=</span> tablet<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    type <span style="color: #339933;">=</span> <span style="color: #3366CC;">'tablet'</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
    type <span style="color: #339933;">=</span> <span style="color: #3366CC;">'desktop'</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000066; font-weight: bold;">return</span> type<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Get screen width</span>
<span style="color: #003366; font-weight: bold;">var</span> screenWidth <span style="color: #339933;">=</span> document.<span style="color: #660066;">documentElement</span>.<span style="color: #660066;">clientWidth</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Set screen context</span>
<span style="color: #003366; font-weight: bold;">var</span> screenContext <span style="color: #339933;">=</span> setContext<span style="color: #009900;">&#40;</span>screenWidth<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Now we can pass what we know to the ad server set-up code. First we turn the list of positions into a string and give that value to the <code>listpos</code> variable. We also set the <code>query</code> value to the context type. This allows us to repurpose the same ad position names for each context.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Set list of positions</span>
<span style="color: #003366; font-weight: bold;">var</span> adPositions <span style="color: #339933;">=</span> pageConfig<span style="color: #009900;">&#91;</span>screenContext<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'positions'</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">join</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">','</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// OAS set-up code</span>
<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #003366; font-weight: bold;">var</span> url <span style="color: #339933;">=</span> <span style="color: #3366CC;">'http://ads.yoursite.com/RealMedia/ads/adstream_mjx.ads/'</span><span style="color: #339933;">,</span>
  pagetag <span style="color: #339933;">=</span> <span style="color: #3366CC;">'www.yoursite.com/'</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">,</span>
  listpos <span style="color: #339933;">=</span> adPositions<span style="color: #339933;">,</span>
  query <span style="color: #339933;">=</span> screenContext<span style="color: #339933;">,</span>
  rns <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>Math.<span style="color: #660066;">random</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">substring</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">11</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 document.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&lt;script src=&quot;'</span> <span style="color: #339933;">+</span> url <span style="color: #339933;">+</span> pagetag <span style="color: #339933;">+</span> <span style="color: #3366CC;">'/1'</span> <span style="color: #339933;">+</span> rns <span style="color: #339933;">+</span> <span style="color: #3366CC;">'@'</span> <span style="color: #339933;">+</span> listpos <span style="color: #339933;">+</span> <span style="color: #3366CC;">'?'</span> <span style="color: #339933;">+</span> query <span style="color: #339933;">+</span> <span style="color: #3366CC;">'&quot;&gt;&lt;<span style="color: #000099; font-weight: bold;">\/</span>script&gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>That&#8217;s all the code we need to conditionally request ads based on screen size. Note that this code must go in the <code>head</code> and should be executed as soon as possible.</p>
<h5>Ad positioning</h5>
<p>Now that we&#8217;ve requested the right batch of ads we have to position them appropriately on the page. In almost every case I think this can be handled with CSS alone. Unused ad units can be hidden safely with <code>display:none</code> because the unused ad units were never returned from the ad server. And units can be floated or absolutely positioned to accommodate different layouts.</p>
<p>But what if CSS isn&#8217;t enough? For example, what if a mobile layout requires an ad unit to be placed somewhere else in the DOM structure? Well we can use JavaScript to move an ad from one location to another. But it comes with an important caveat: JavaScript containing <code>document.write</code> cannot be moved around the DOM. The JavaScript will re-execute when inserted into the DOM and the <code>document.write</code> call will flush the page.</p>
<p>You can only reposition the <strong>HTML contents generated by the JavaScript</strong>. This requires some cooperation with the code coming from the ad server. If you&#8217;re hosting the ad creative (i.e., not using third-party tags) this shouldn&#8217;t be a problem. Within the ad server you can wrap the creative in a div and your JavaScript will just grab that div. But if the creative is served via a third-party server you&#8217;ll need the same cooperation on the client&#8217;s end&#8230; which can be difficult. And there may be cases where the ad contents cannot be isolated from its deployment code.</p>
<p>The good news is that mobile creatives are much simpler than Desktop creatives (no Flash) and so if we&#8217;re doing this for the mobile context it may not be a problem. Assuming we&#8217;ve cleared those hurdles we can proceed as follows.</p>
<p>First, give each ad unit a class and then within your mobile media query block set that class to <code>display:none</code>. This will hide all ads in the mobile context by default.</p>
<p>Second, insert a placeholder div into your HTML wherever you want the mobile unit to appear. Set this to <code>display:none</code> for all contexts.</p>
<p>Next we&#8217;ll use JavaScript to move the ad from its original desktop/tablet placement to the mobile-only placeholder div. The previous code was done with plain &#8216;ole JavaScript but for this I&#8217;m going to use jQuery to keep the example from getting too verbose.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// Reference to the new location</span>
  <span style="color: #003366; font-weight: bold;">var</span> $newPosition <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#mobile-ad-placeholder'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Reference to the CONTENTS of the original ad placement</span>
    $originalAd <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#ad-top .ad-contents'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// Move the ad to the placeholder</span>
  $newPosition.<span style="color: #660066;">append</span><span style="color: #009900;">&#40;</span>$originalAd<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">show</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// Remove the original ad from the DOM</span>
  $originalAd.<span style="color: #660066;">remove</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Pretty simple, right?</p>
<h5>Wrap-up</h5>
<p>Clearly this isn&#8217;t a blanket solution for all responsive advertising scenarios; it&#8217;s only a possible solution for a particular ad server. And it&#8217;s only solving the problem of execution on the front end. But I think it lays the groundwork for approaching the general problem of getting responsive design and advertising to play nicely together.</p>
<p>To review:</p>
<ul>
<li>Define a set of contexts and associate each context with a breakpoint and a list of advertising units.</li>
<li>Using JavaScript, use <a href="https://developer.mozilla.org/en/DOM/window.matchMedia" target="_blank">window.matchMedia</a> or <a href="http://tripleodeon.com/2011/12/first-understand-your-screen/" target="_blank">one of the many available properties</a> to detect client screen width and determine the context.</li>
<li>Modify the request(s) to the ad server to only include the ads needed for the current context.</li>
<li>The context is determined by the size of the screen at the time of page load. Forget about what happens when the browser is resized. It doesn&#8217;t matter.</li>
<li>If you&#8217;re smart about your mark-up structure, repositioning and hiding ads can be handled with CSS. If you must relocate an ad in the DOM it can be done with JavaScript—with the stipulation that you can access the contents of the creative independent of any implementation code that uses <code>document.write</code>.</li>
</ul>
<p><strong>Thoughts?</strong> Ping me on Twitter at <a href="https://twitter.com/#!/robflaherty" target="_blank">@robflaherty</a>, discuss on <a href="http://news.ycombinator.com/item?id=3609558" target="_blank">Hacker News</a>, or leave a comment below.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ravelrumba.com/blog/responsive-ads-real-world-ad-server-implementation/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Simple CSS/JS Concatenation and Versioning with PHP</title>
		<link>http://www.ravelrumba.com/blog/css-js-concatenation-versioning-php/</link>
		<comments>http://www.ravelrumba.com/blog/css-js-concatenation-versioning-php/#comments</comments>
		<pubDate>Sun, 12 Feb 2012 22:42:31 +0000</pubDate>
		<dc:creator>Rob Flaherty</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[General Web]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Performance]]></category>

		<guid isPermaLink="false">http://www.ravelrumba.com/?p=1500</guid>
		<description><![CDATA[Here&#8217;s a quick and easy way way to concatenate stylesheets and JavaScript using PHP. I&#8217;ll also show how to layer on file versioning so you can use far future expires headers for optimal client side caching. There are many ways to combine files to reduce HTTP requests&#8211;you can use a build tool to prepare static [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a quick and easy way way to concatenate stylesheets and JavaScript using PHP. I&#8217;ll also show how to layer on file versioning so you can use far future expires headers for optimal client side caching.</p>
<p>There are many ways to combine files to reduce HTTP requests&#8211;you can use a build tool to prepare static assets as part of a build process or you can combine files on-the-fly using Apache mods, Server Side Includes (SSI), or other server side solutions, including CMS plugins. The right solution of course depends on your project, team, and environment. If a build step is not the right fit for your project and you want to implement something lightweight without having to fiddle with Apache too much, you may find this useful.</p>
<p>I&#8217;ll mention that this is a very simple technique and something that developers have been doing for years. I&#8217;m simply documenting it so that it has a place in our collective performance toolkit.</p>
<h5>all.js.php</h5>
<p>To get started we create a PHP file called <code>all.js.php</code> and then:</p>
<ol>
<li>Set the Content-type header to specify either JS or CSS</li>
<li>List our scripts/stylesheets in the order we want them included</li>
<li>Loop through the array and include each file</li>
</ol>
<p>The code looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Content-type: application/javascript'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$files</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
  <span style="color: #666666; font-style: italic;">//Plugins</span>
  <span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/plugins/jquery.hoverIntent.min.js'</span><span style="color: #339933;">,</span>
  <span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/plugins/jquery.placeholder.min.js'</span><span style="color: #339933;">,</span>
  <span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/plugins/jquery.tweet.min.js'</span><span style="color: #339933;">,</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">//Core scripts</span>
  <span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/core.js'</span><span style="color: #339933;">,</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">//Other scripts</span>
  <span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/main.js'</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$files</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$file</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">include</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Then you just reference the <code>all.js.php</code> file in your document and it returns all of your JS as a single script.</p>
<p>The obvious advantage of concatenating on-the-fly is that you don&#8217;t have to add a build step to your workflow. The benefits of using PHP over server side includes are that (a) it&#8217;s likely to be more accessible to developers on your team and (b) you can make use of application variables in your asset list. This is very handy for pulling in shared files (e.g., libraries and plugins) from a centralized location.</p>
<p>Is performance a concern? It depends. If you have an under-provisioned server and you&#8217;re trying to concatenate dozens of big files under heavy traffic load, it&#8217;s possible you&#8217;ll experience some performance degradation. But in most cases I don&#8217;t see it being an issue. PHP is fast. Regarding response time, ApacheBench tests I&#8217;ve done in the past revealed no significant difference between a pre-concatenated file and one concatenated on-the-fly with PHP. </p>
<p>But here&#8217;s the main reason I don&#8217;t think performance is an issue: if performance and load are concerns for your site, you&#8217;ll already have some layer of caching in place. Maybe it’s memcache, maybe it’s Varnish, maybe it’s a CDN. There’s no reason your concatenated file would be generated with each request &#8212; it’s going to end up sitting in a cache anyway.</p>
<h5>Cache headers and versioning</h5>
<p>When you dynamically combine files you can run into problems with behavior based on the file&#8217;s last modified date. For instance if you&#8217;re using Server Side Includes, by default Apache <a href="http://httpd.apache.org/docs/current/howto/ssi.html#configuring" target="_blank">does not send the last modified header</a>.</p>
<p>To get around this we can use expires headers to give the combined file an explicit expiration date. Even better, we can use far future expiration dates so that browsers continue to use a cached copy of the file until we make changes. All we have to do is implement some form of file versioning to let clients know when to request a new copy of the file.</p>
<p>There are two parts to it: the PHP in your templates that adds a version number to each CSS and JS file reference, and an Apache rewrite rule that rewrites the versioned the filename to the canonical filename. It&#8217;s really simple.</p>
<p>(I&#8217;m not going to cover how to set cache control expires headers since it&#8217;s well documented elsewhere. If you need a reference, I recommend looking at HTML5Boilerplate&#8217;s <a href="https://github.com/h5bp/html5-boilerplate/blob/master/.htaccess" target_"blank">.htaccess file</a>.)</p>
<h5>Adding version numbers to CSS/JS references</h5>
<p>Either in your main layout file or wherever in your app you store global config, declare a variable that represents the current version number for your static assets:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$static_version</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'1'</span><span style="color: #339933;">;</span></pre></div></div>

<p>Also in your main layout file or wherever you store global functions, add this function that accepts a file path and injects a version number before the file extension:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> version_stamp<span style="color: #009900;">&#40;</span><span style="color: #000088;">$url</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$name</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'.'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$url</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$lastext</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_pop</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #990000;">array_push</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #339933;">,</span> <span style="color: #000088;">$static_version</span><span style="color: #339933;">,</span> <span style="color: #000088;">$lastext</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">return</span> <span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'.'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This will turn <code>all.js.php</code> references into <code>all.js.1.php</code>. The reason the version number is built into the filename as opposed to being append as a query parameter is that some proxies <a href="http://code.google.com/speed/page-speed/docs/caching.html#LeverageProxyCaching" target="_blank">will not cache files containing query strings</a>.</p>
<p>Then we modify our JS and CSS references to include the version stamp function like this:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;script src=&quot;&lt;?php echo version_stamp('/_assets/js/all.js.php') ?&gt;&quot;&gt;&lt;/script&gt;</pre></div></div>

<h5>Adding Apache rewrite</h5>
<p>Adding the following rewrite rule to <code>.htaccess</code> or <code>httpd.conf</code> will route requests for <code>all.js.1.php</code> to <code>all.js.php</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;"><span style="color: #adadad; font-style: italic;"># File versioning</span>
<span style="color: #00007f;">RewriteRule</span> ^(.+)\.(js|css).([<span style="color: #ff0000;">0</span>-<span style="color: #ff0000;">9</span>]+)\.(php)$ $1.$2.$4</pre></div></div>

<p>Then whenever you make JS or CSS updates you just increment the version number in the <code>$static_version</code> variable and browsers will know to request the fresh copy.</p>
<h5>Is this the right solution?</h5>
<p>If a build process makes sense for your workflow and if you can integrate a build process without incurring the overhead of something like Ant, I think a build tool is often the better solution. If a build step is inconvenient for your workflow, the various on-the-fly options are probably equal. (I&#8217;m sure someone will comment that concatenating with Apache is faster than PHP, and while that may be technically true, practically speaking it may be an over optimization. And as I mentioned above, a proper caching layer renders the argument moot.)</p>
<p>The advantages to this method are that it&#8217;s simple, easy to implement, and all done in PHP (aside from the apache rewrite rule).</p>
<p>Lastly, if you&#8217;re interested in this stuff make sure to read Robert Nyman&#8217;s <a href="http://robertnyman.com/2010/01/19/tools-for-concatenating-and-minifying-css-and-javascript-files-in-different-development-environments/" target="_blank">Tools For Concatenating And Minifying CSS And JavaScript Files In Different Development Environments</a>. It&#8217;s a great round-up of tools in a variety of languages and frameworks.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ravelrumba.com/blog/css-js-concatenation-versioning-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Watch and Compile LESS From the Command Line</title>
		<link>http://www.ravelrumba.com/blog/watch-compile-less-command-line/</link>
		<comments>http://www.ravelrumba.com/blog/watch-compile-less-command-line/#comments</comments>
		<pubDate>Sun, 05 Feb 2012 17:30:31 +0000</pubDate>
		<dc:creator>Rob Flaherty</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Server]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[command line]]></category>
		<category><![CDATA[compile]]></category>
		<category><![CDATA[inotify-tools]]></category>
		<category><![CDATA[LESS]]></category>
		<category><![CDATA[watchr]]></category>

		<guid isPermaLink="false">http://www.ravelrumba.com/?p=1474</guid>
		<description><![CDATA[Unlike SASS and Stylus, the command line compiler that comes with LESS does not include a watch option to automatically compile LESS files whenever changes are made. There are several GUI apps that provide watch functionality but if GUIs aren&#8217;t your thing or if you need something that can run on a server, you&#8217;ll want a way [...]]]></description>
			<content:encoded><![CDATA[<p>Unlike <a href="http://sass-lang.com/" target="_blank">SASS</a> and <a href="http://learnboost.github.com/stylus/" target="_blank">Stylus</a>, the command line compiler that comes with <a href="http://lesscss.org/" target="_blank">LESS</a> <strong>does not include a watch option</strong> to automatically compile LESS files whenever changes are made. There are several GUI apps that provide watch functionality but if GUIs aren&#8217;t your thing or if you need something that can run on a server, you&#8217;ll want a way to do this from the command line. Here&#8217;s an easy way.</p>
<p>Install <a href="https://github.com/mynyml/watchr" target="_blank">watchr</a>, which is a Ruby tool for monitoring directories and files. With watchr and LESS installed you can watch-compile directories and sub-directories with a single command:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">watchr <span style="color: #660033;">-e</span> <span style="color: #ff0000;">'watch(&quot;.*\.less$&quot;) { |f| system(&quot;lessc #{f[0]} &gt; #{f[0]}.css&quot;) }'</span></pre></div></div>

<p>To make this a little more useful we can call it with a bash script. We&#8217;ll also print a status update on each compile. Successful compiles will print the compiled file name and any compile errors will be displayed in the console.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #666666; font-style: italic;"># Requires watchr: https://github.com/mynyml/watchr</span>
watchr <span style="color: #660033;">-e</span> <span style="color: #ff0000;">'watch(&quot;.*\.less$&quot;) { |f| system(&quot;lessc #{f[0]} &gt; #{f[0]}.css &amp;&amp; echo \&quot;#{f[0]} &gt; #{f[0]}.css\&quot; &quot;) }'</span></pre></div></div>

<p>Name it something like <code>watch_less.sh</code>, put it in <code>/usr/local/bin/</code> (or wherever you keep your executables), set permissions with <code>chmod u+x watch_less.sh</code>, and then just run <code>watch_less.sh</code> from your workspace.</p>
<h5>Bonus</h5>
<p>Here&#8217;s another option that uses <a href="https://github.com/rvoicilas/inotify-tools" target="_blank">inotify-tools</a> (note: Linux-only) instead of watchr. This was suggested by <a href="https://twitter.com/#!/yoavweiss" target="_blank">@yoavweiss</a> when I asked on Twitter if anyone had a recommended solution for watch-and-compiling LESS from the command line:</p>
<blockquote class="twitter-tweet"><p>LESS watch&#038;compile: while true;do N=`find -name &#8220;*.less&#8221; `;inotifywait -qe modify $N ;for f in $N;do lessc $f ${f%.*}.css;done;done</p>
<p>&mdash; Yoav Weiss (@yoavweiss) <a href="https://twitter.com/yoavweiss/status/164446186701463552" data-datetime="2012-01-31T20:33:20+00:00">January 31, 2012</a></p></blockquote>
<p><script src="//platform.twitter.com/widgets.js" charset="utf-8"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ravelrumba.com/blog/watch-compile-less-command-line/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Responsive Ad Demos</title>
		<link>http://www.ravelrumba.com/blog/responsive-ad-demos/</link>
		<comments>http://www.ravelrumba.com/blog/responsive-ad-demos/#comments</comments>
		<pubDate>Sat, 19 Nov 2011 21:00:28 +0000</pubDate>
		<dc:creator>Rob Flaherty</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[eMedia]]></category>
		<category><![CDATA[General Web]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Publishing]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[advertising]]></category>
		<category><![CDATA[media queries]]></category>
		<category><![CDATA[responsive design]]></category>

		<guid isPermaLink="false">http://www.ravelrumba.com/?p=1407</guid>
		<description><![CDATA[My previous post was about some of the business challenges surrounding responsive design and advertising. I wrote it just after reading Mark Boulton&#8217;s excellent Responsive Advertising, which was written earlier this week and which you should definitely read if you haven&#8217;t already. While I still think the business challenges are the greater obstacle, the technical [...]]]></description>
			<content:encoded><![CDATA[<p>My <a href="http://www.ravelrumba.com/blog/responsive-design-and-advertising/">previous post</a> was about some of the business challenges surrounding responsive design and advertising. I wrote it just after reading Mark Boulton&#8217;s excellent <a href="http://www.markboulton.co.uk/journal/comments/responsive-advertising" target="_blank">Responsive Advertising</a>, which was written earlier this week and which you should definitely read if you haven&#8217;t already.</p>
<p>While I still think the business challenges are the greater obstacle, the technical challenges are interesting and beg for experimentation.  I couldn&#8217;t help from spending a few hours toying with possible solutions. Here are two demos.</p>
<h5>Responsive HTML ad</h5>
<p>My first idea was to build an HTML ad that could shift itself into 3 different standard IAB sizes: 728&#215;90, 300&#215;250, and 300&#215;50. So I designed a mock Foursquare ad with HTML and CSS, using media queries to define break points at 500px and 728px. The two images in the ad are served as data URIs which means the ad has no external resources outside the HTML document. The file size is 36K, comfortably within standard max file sizes for ads.</p>
<p>This works in latest versions of Chrome, Safari, Firefox, and Opera. Maybe/Probably works in IE9. Drag your window around to see it go. You can view the standalone ad <a href="http://www.ravelrumba.com/code/demos/responsive-ads/1/" target="_blank">here</a>.</p>
<p><iframe src="http://www.ravelrumba.com/code/demos/responsive-ads/1/" width="100%" height="250"></iframe></p>
<h5>Responsive/Adaptive HTML ad using a JavaScript interface</h5>
<p>This one is based on the same idea but does two things differently. One, instead of the ads being built with HTML, each ad is simply a static image. And two, instead of embedding the responsive logic in media queries I&#8217;ve added a JavaScript interface, the configuration portion of which looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Ad config</span>
<span style="color: #003366; font-weight: bold;">var</span> ads <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
  leaderboard<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
    width<span style="color: #339933;">:</span> <span style="color: #CC0000;">728</span><span style="color: #339933;">,</span>
    height<span style="color: #339933;">:</span> <span style="color: #CC0000;">90</span><span style="color: #339933;">,</span>
    breakpoint<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span>
    url<span style="color: #339933;">:</span> <span style="color: #3366CC;">'728x90.png'</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
  rectangle<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
    width<span style="color: #339933;">:</span> <span style="color: #CC0000;">300</span><span style="color: #339933;">,</span>
    height<span style="color: #339933;">:</span> <span style="color: #CC0000;">250</span><span style="color: #339933;">,</span>
    breakpoint<span style="color: #339933;">:</span> <span style="color: #CC0000;">728</span><span style="color: #339933;">,</span>
    url<span style="color: #339933;">:</span> <span style="color: #3366CC;">'300x250.png'</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
  mobile<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
    width<span style="color: #339933;">:</span> <span style="color: #CC0000;">300</span><span style="color: #339933;">,</span>
    height<span style="color: #339933;">:</span> <span style="color: #CC0000;">50</span><span style="color: #339933;">,</span>
    breakpoint<span style="color: #339933;">:</span> <span style="color: #CC0000;">500</span> <span style="color: #339933;">,</span>
    url<span style="color: #339933;">:</span> <span style="color: #3366CC;">'300x50.png'</span>
  <span style="color: #009900;">&#125;</span>       
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>This lets you define your responsive campaign with some settings and then the JavaScript does the rest. Note, this uses the <code><a href="https://developer.mozilla.org/en/DOM/window.matchMedia" target="_blank">window.matchMedia</a></code> method, which currently is only available in Chrome, Firefox, and Safari (but Paul Irish has a <a href="https://github.com/paulirish/matchMedia.js/" target="_blank">polyfill</a> that can extend support to other browsers).</p>
<p>This works in latest versions of Chrome, Safari, and Firefox. Drag your window around to see it go. You can view the standalone ad <a href="http://www.ravelrumba.com/code/demos/responsive-ads/2/" target="_blank">here</a>.</p>
<p><iframe src="http://www.ravelrumba.com/code/demos/responsive-ads/2/" width="100%" height="250"></iframe></p>
<h5>Coda</h5>
<p>Granted these demos are only static ads and they don&#8217;t address some of the bigger problems, like rich media and ad server implementation. But still I think the general technique around building responsive campaigns at the design/HTML/CSS/JavaScript level is not that difficult to execute. The real challenge is defining a common implementation that works for everyone involved &#8212; for advertisers, agencies, publishers, and ad servers.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ravelrumba.com/blog/responsive-ad-demos/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Responsive Design and Advertising</title>
		<link>http://www.ravelrumba.com/blog/responsive-design-and-advertising/</link>
		<comments>http://www.ravelrumba.com/blog/responsive-design-and-advertising/#comments</comments>
		<pubDate>Wed, 16 Nov 2011 18:09:09 +0000</pubDate>
		<dc:creator>Rob Flaherty</dc:creator>
				<category><![CDATA[eMedia]]></category>
		<category><![CDATA[General Web]]></category>
		<category><![CDATA[Publishing]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[advertising]]></category>
		<category><![CDATA[publishing]]></category>
		<category><![CDATA[responsive design]]></category>
		<category><![CDATA[UX]]></category>

		<guid isPermaLink="false">http://www.ravelrumba.com/?p=1386</guid>
		<description><![CDATA[A few days ago Mark Boulton posted a tweet wondering why more people haven&#8217;t written about the conflict between responsive design and advertising. Having struggled with this problem in the past and having just last week abandoned a responsive approach for an ad-heavy site, I was happy to see attention being brought to the issue. Mark [...]]]></description>
			<content:encoded><![CDATA[<p>A few days ago Mark Boulton posted a <a href="https://twitter.com/#!/markboulton/status/136210940420038656" target="_blank">tweet</a> wondering why more people haven&#8217;t written about the conflict between responsive design and advertising. Having struggled with this problem in the past and having just last week abandoned a responsive approach for an ad-heavy site, I was happy to see attention being brought to the issue.</p>
<p>Mark followed up with a <a href="http://www.markboulton.co.uk/journal/comments/responsive-advertising" target="_blank">great blog post</a> that detailed many of the obstacles and offered ideas about how to move forward. I wanted to respond with a few thoughts.</p>
<p>Quick background on why you might care at all about my opinion on this: I&#8217;ve spent the last 5 years working daily and closely on advertising-supported sites, working in a range of areas from product design, to front-end coding, to ad ops, to content strategy, to sales strategy. I&#8217;ve debugged tangled 3rd party ad server scripts and I&#8217;ve sat on calls with advertisers to try and explain why the &#8220;fold&#8221; does not exist. Many times.</p>
<h5>TV on the Web</h5>
<p>Mark talks about the problem that ads are sold as fixed &#8220;slots&#8221; on a page. For example, an advertiser buys the top leaderboard slot, which has a fixed size of 728&#215;90 and a static placement indicated clearly in the media kit (above the fold, win!). This of course poses a problem for responsive design &#8212; what happens to the leaderboard when the screen shrinks below 728px?</p>
<p>What he didn&#8217;t mention is that this sales model is mostly inherited from sales models for other media, and, more importantly, that most people buying and selling web have strong backgrounds in buying/selling those other media types.</p>
<p>Whether you&#8217;re buying a print, television, or radio ad, you&#8217;re buying something of a fixed size or duration with a specific guarantee about placement. It&#8217;s a simple, familiar model. Parties on both sides of the sale are comfortable with it. Simplicity is key.</p>
<p>What this means is that sales teams often end up selling other media types (print, especially) <em>on</em> the web instead of selling the web. The mental model is reused, some of the vocabulary overlaps (the &#8220;fold&#8221;). My point is that it&#8217;s tough to move beyond this when so much of the process is still grounded in the past.</p>
<h5>Responsive design has a business problem (maybe)</h5>
<p>The business case for responsive design is usually centered on a variation of the old &#8220;Write Once Publish Everywhere&#8221; pitch: instead of building and maintaining multiple sites for multiple devices, we build one site that can adapt to multiple devices. It&#8217;s a great solution to a <strong>technical problem</strong>.</p>
<p>The cost-saving implications are obviously attractive from a business standpoint, but the concept is actually at odds with a higher-level business goal, which is to <strong>leverage and extend brands and products into other products</strong>.</p>
<p>Desktop, tablet, and mobile experiences have the potential to be marketed as distinct products aimed at different media budgets. But only if the products are somewhat differentiated. Homogenizing into a single unified, adaptable experience &#8212; for all its technical and usability benefits &#8212; may be undesirable from an inventory perspective. If you&#8217;re a salesperson for a print product would you rather be able to offer a client two products or four?</p>
<p>That&#8217;s not to say that a responsive design couldn&#8217;t be used to produce distinct mobile and tablet offerings. Or that revenue from a combined multi-device package couldn&#8217;t offset potential revenue from separate products.</p>
<h5>Where things stand today</h5>
<p>Mark proposed some great ideas about responsive ad units and multi-unit packages. I&#8217;m sure we&#8217;ll see these ideas materialize in the marketplace soon but I think Mark (and <a href="https://twitter.com/#!/kerns/status/136402434980450304" target="_blank">@kerns</a>) are right that it won&#8217;t happen until there&#8217;s demand.</p>
<p>So until the market responds to responsive design, what are our options? If your site&#8217;s revenue is dependent on advertising you most likely have few if any. Think about it. Your constraint is the width of the widest ad unit. Even if your site only has a 300&#215;250 unit (uncommon), how do you know that you won&#8217;t need to support other units in the future?</p>
<p>Say your site has a 728&#215;90 leaderboard and a 300&#215;250 rectangle. Well, you could make a site that&#8217;s responsive from 728px (iPad portrait width) up to a 1200px+ widescreen display. Cool. But what if Sales wants to add a 970px-wide Pushdown unit to the site? Now the bottom end of your responsive spectrum is 970px. At that point, is the extra work associated with a responsive layout even worth it?</p>
<p>I&#8217;m not aware of any other realistic options. You can&#8217;t just hide ads when the screen gets smaller. And ad delivery logic is heavily tied to the server (i.e., it would be difficult, sometimes impossible, to request ads based on client-side properties like screen size).</p>
<p>&#8230;but maybe you have some other ideas?</p>
<p><strong>Update 11/17/11:</strong> Mark&#8217;s article has kicked off a lot of great discussion around this topic. If you&#8217;re interested in this topic don&#8217;t miss:</p>
<ul>
<li><a href="https://plus.google.com/u/0/115560284086196136827/posts/GwFosa2RhEU" target="_blank">Google+ discussion thread</a></li>
<li><a href="http://andr3.net/blog/post/149" target="_blank">André Luís&#8217;s blog post</a></li>
<li><a href="http://artequalswork.com/posts/responsive-ads.php" target="_blank">Nathan Ford&#8217;s blog post</a></li>
</ul>
<div><strong>Update 12/6/11: </strong>I put together a few <a href="http://www.ravelrumba.com/blog/responsive-ad-demos/">demos of responsive/adaptive ads</a>.</div>
]]></content:encoded>
			<wfw:commentRss>http://www.ravelrumba.com/blog/responsive-design-and-advertising/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

