<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	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/"
		>
<channel>
	<title>Comments on: Using HTTP Headers to Serve Styles</title>
	<atom:link href="http://meyerweb.com/eric/thoughts/2009/01/22/using-http-headers-to-serve-styles/feed/" rel="self" type="application/rss+xml" />
	<link>http://meyerweb.com/eric/thoughts/2009/01/22/using-http-headers-to-serve-styles/</link>
	<description>Things that Eric A. Meyer, CSS expert, writes about on his personal Web site; it&#039;s largely Web standards and Web technology, but also various bits of culture, politics, personal observations, and other miscellaneous stuff</description>
	<lastBuildDate>Wed, 17 Mar 2010 18:47:03 -0400</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Dev Blog AF83 &#187; Blog Archive &#187; Veille technologique (x2) : Annonces, Contenus, Conférences, Méthodes, Agilité, Développment, Langages, Editeurs, Outils, Bases de données, Protocoles, Bibliothèques, SEO, Ergonomie, etc.</title>
		<link>http://meyerweb.com/eric/thoughts/2009/01/22/using-http-headers-to-serve-styles/#comment-444784</link>
		<dc:creator>Dev Blog AF83 &#187; Blog Archive &#187; Veille technologique (x2) : Annonces, Contenus, Conférences, Méthodes, Agilité, Développment, Langages, Editeurs, Outils, Bases de données, Protocoles, Bibliothèques, SEO, Ergonomie, etc.</dc:creator>
		<pubDate>Mon, 23 Feb 2009 19:47:58 +0000</pubDate>
		<guid isPermaLink="false">http://meyerweb.com/?p=1010#comment-444784</guid>
		<description>[...] http://meyerweb.com/eric/thoughts/2009/01/22/using-http-headers-to-serve-styles/ : Eric Meyer propose d&#8217;utiliser les headers HTTP pour servir une balise style, afin de distinguer les serveurs de développement de ceux de production [...]</description>
		<content:encoded><![CDATA[<p>[...] <a href="http://meyerweb.com/eric/thoughts/2009/01/22/using-http-headers-to-serve-styles/" rel="nofollow">http://meyerweb.com/eric/thoughts/2009/01/22/using-http-headers-to-serve-styles/</a> : Eric Meyer propose d&#8217;utiliser les headers HTTP pour servir une balise style, afin de distinguer les serveurs de développement de ceux de production [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: AMammenT</title>
		<link>http://meyerweb.com/eric/thoughts/2009/01/22/using-http-headers-to-serve-styles/#comment-442103</link>
		<dc:creator>AMammenT</dc:creator>
		<pubDate>Wed, 11 Feb 2009 18:35:08 +0000</pubDate>
		<guid isPermaLink="false">http://meyerweb.com/?p=1010#comment-442103</guid>
		<description>This approach is really interesting.  I propose a slight variant below which should support any browser.  It continues to depend on Apache, but moves away from using HTTP headers to just serving the modified css using rewrite rules.  

1) Staging CSS:


@import &quot;public.css&quot;

html {background: url(staging-bg.png) 100% 50% repeat-y;}


2) Production.css:
@import &quot;public.css&quot;

3) Public.css: Style rules for the production environment

3) Use an Apache rewrite rule on staging servers to rewrite requests for production.css to requests for staging.css

This does cost an extra hop even in production, so it may not be optimal for production sites.  One way to address this would be to setup a rewrite rule in production that rewrites requests for production.css to public.css.  This saves the hop, but nothing breaks if the rule is omitted.</description>
		<content:encoded><![CDATA[<p>This approach is really interesting.  I propose a slight variant below which should support any browser.  It continues to depend on Apache, but moves away from using HTTP headers to just serving the modified css using rewrite rules.  </p>
<p>1) Staging CSS:</p>
<p>@import &#8220;public.css&#8221;</p>
<p>html {background: url(staging-bg.png) 100% 50% repeat-y;}</p>
<p>2) Production.css:<br />
@import &#8220;public.css&#8221;</p>
<p>3) Public.css: Style rules for the production environment</p>
<p>3) Use an Apache rewrite rule on staging servers to rewrite requests for production.css to requests for staging.css</p>
<p>This does cost an extra hop even in production, so it may not be optimal for production sites.  One way to address this would be to setup a rewrite rule in production that rewrites requests for production.css to public.css.  This saves the hop, but nothing breaks if the rule is omitted.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Micheil</title>
		<link>http://meyerweb.com/eric/thoughts/2009/01/22/using-http-headers-to-serve-styles/#comment-440786</link>
		<dc:creator>Micheil</dc:creator>
		<pubDate>Thu, 05 Feb 2009 14:49:33 +0000</pubDate>
		<guid isPermaLink="false">http://meyerweb.com/?p=1010#comment-440786</guid>
		<description>I do something sort of similar on a few websites I work on, where by I add SB or Staging to the page title, so I know what I&#039;m looking at.</description>
		<content:encoded><![CDATA[<p>I do something sort of similar on a few websites I work on, where by I add SB or Staging to the page title, so I know what I&#8217;m looking at.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Max Design - standards based web design, development and training &#187; Some links for light reading (27/1/09)</title>
		<link>http://meyerweb.com/eric/thoughts/2009/01/22/using-http-headers-to-serve-styles/#comment-438689</link>
		<dc:creator>Max Design - standards based web design, development and training &#187; Some links for light reading (27/1/09)</dc:creator>
		<pubDate>Tue, 27 Jan 2009 10:56:42 +0000</pubDate>
		<guid isPermaLink="false">http://meyerweb.com/?p=1010#comment-438689</guid>
		<description>[...] Using HTTP Headers to Serve Styles [...]</description>
		<content:encoded><![CDATA[<p>[...] Using HTTP Headers to Serve Styles [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Cris</title>
		<link>http://meyerweb.com/eric/thoughts/2009/01/22/using-http-headers-to-serve-styles/#comment-438639</link>
		<dc:creator>Cris</dc:creator>
		<pubDate>Mon, 26 Jan 2009 21:48:24 +0000</pubDate>
		<guid isPermaLink="false">http://meyerweb.com/?p=1010#comment-438639</guid>
		<description>&lt;blockquote cite=&quot;#comment-438054&quot;&gt;Foolproof... until the .htaccess file accidentally migrates itself to the production server. :-)&lt;/blockquote&gt;
True, true. And to prevent that -- provided I have the privileges -- I would put the &#039;Header&#039; line in a &lt;Directory&gt; section of my apache configuration file (httpd.conf).
&lt;code&gt;
&lt;Directory /path/to/webroot&gt;
Header add Link &quot;&lt;/staging.css&gt;;rel=stylesheet;type=text/css;media=all&quot;
&lt;/Directory&gt;
&lt;/code&gt;

Now that the directive is safely stashed away from my development webroot, I&#039;ve further reduced the possibility of accidental migration. Or at least I&#039;ve passed the responsibility for it to my server admin ;)

By the way, how standard is it for Apache admins to enable mod_headers? I know my host has it, but I don&#039;t know if it&#039;s common practice.</description>
		<content:encoded><![CDATA[<blockquote cite="#comment-438054"><p>Foolproof&#8230; until the .htaccess file accidentally migrates itself to the production server. :-)</p></blockquote>
<p>True, true. And to prevent that &#8212; provided I have the privileges &#8212; I would put the &#8216;Header&#8217; line in a &lt;Directory&gt; section of my apache configuration file (httpd.conf).<br />
<code><br />
&lt;Directory /path/to/webroot&gt;<br />
Header add Link "&lt;/staging.css&gt;;rel=stylesheet;type=text/css;media=all"<br />
&lt;/Directory&gt;<br />
</code></p>
<p>Now that the directive is safely stashed away from my development webroot, I&#8217;ve further reduced the possibility of accidental migration. Or at least I&#8217;ve passed the responsibility for it to my server admin ;)</p>
<p>By the way, how standard is it for Apache admins to enable mod_headers? I know my host has it, but I don&#8217;t know if it&#8217;s common practice.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: angela</title>
		<link>http://meyerweb.com/eric/thoughts/2009/01/22/using-http-headers-to-serve-styles/#comment-438505</link>
		<dc:creator>angela</dc:creator>
		<pubDate>Sun, 25 Jan 2009 16:41:46 +0000</pubDate>
		<guid isPermaLink="false">http://meyerweb.com/?p=1010#comment-438505</guid>
		<description>Never thought about doing it like that - pretty interesting.  I&#039;ve never liked .htaccess though - not all servers have it enabled.  You can use a service like &lt;a href=&quot;http://www.httpviewer.net/&quot; rel=&quot;nofollow&quot;&gt;http header viewer&lt;/a&gt; to make sure that your trick is working</description>
		<content:encoded><![CDATA[<p>Never thought about doing it like that &#8211; pretty interesting.  I&#8217;ve never liked .htaccess though &#8211; not all servers have it enabled.  You can use a service like <a href="http://www.httpviewer.net/" rel="nofollow">http header viewer</a> to make sure that your trick is working</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Thomas Scholz</title>
		<link>http://meyerweb.com/eric/thoughts/2009/01/22/using-http-headers-to-serve-styles/#comment-438362</link>
		<dc:creator>Thomas Scholz</dc:creator>
		<pubDate>Sat, 24 Jan 2009 10:59:35 +0000</pubDate>
		<guid isPermaLink="false">http://meyerweb.com/?p=1010#comment-438362</guid>
		<description>I add a parameter with the result of &lt;code&gt;filemtime()&lt;/code&gt; to my stylesheets. I just have to do the client side caching on my own side.</description>
		<content:encoded><![CDATA[<p>I add a parameter with the result of <code>filemtime()</code> to my stylesheets. I just have to do the client side caching on my own side.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Timothy</title>
		<link>http://meyerweb.com/eric/thoughts/2009/01/22/using-http-headers-to-serve-styles/#comment-438300</link>
		<dc:creator>Timothy</dc:creator>
		<pubDate>Fri, 23 Jan 2009 21:40:24 +0000</pubDate>
		<guid isPermaLink="false">http://meyerweb.com/?p=1010#comment-438300</guid>
		<description>Awesome. This helps a lot. Thank you!</description>
		<content:encoded><![CDATA[<p>Awesome. This helps a lot. Thank you!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Peter Holloway</title>
		<link>http://meyerweb.com/eric/thoughts/2009/01/22/using-http-headers-to-serve-styles/#comment-438255</link>
		<dc:creator>Peter Holloway</dc:creator>
		<pubDate>Fri, 23 Jan 2009 10:56:47 +0000</pubDate>
		<guid isPermaLink="false">http://meyerweb.com/?p=1010#comment-438255</guid>
		<description>&quot;Try sprinkling in !important. Upload, reload, nothing.&quot; - I&#039;m glad it&#039;s not just me that does this ;)

We also use the coloured background idea to distinguish between test and production databases - just a bit of CSS in the database connection file does the trick.</description>
		<content:encoded><![CDATA[<p>&#8220;Try sprinkling in !important. Upload, reload, nothing.&#8221; &#8211; I&#8217;m glad it&#8217;s not just me that does this ;)</p>
<p>We also use the coloured background idea to distinguish between test and production databases &#8211; just a bit of CSS in the database connection file does the trick.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Bramus!</title>
		<link>http://meyerweb.com/eric/thoughts/2009/01/22/using-http-headers-to-serve-styles/#comment-438252</link>
		<dc:creator>Bramus!</dc:creator>
		<pubDate>Fri, 23 Jan 2009 10:16:41 +0000</pubDate>
		<guid isPermaLink="false">http://meyerweb.com/?p=1010#comment-438252</guid>
		<description>In the past I&#039;ve played with this &quot;problem&quot; too ... ended up coding a firefox extension that colors the location bar based on which URL you&#039;re at.

Only problems with my approach (and things I had coded quickly):
- it only worked on Firefox 2, Windows. Then Firefox 3 came out and I dropped the project
- no support for other browsers (IE, Safari, Opera, ...)

Great to see your approach on the subject ... and &lt;a href=&quot;http://meyerweb.com/eric/thoughts/2009/01/22/using-http-headers-to-serve-styles/#comment-438100&quot; rel=&quot;nofollow&quot;&gt;the posted PHP solution in the comments here&lt;/a&gt; is neat too!

Thanks,
B!</description>
		<content:encoded><![CDATA[<p>In the past I&#8217;ve played with this &#8220;problem&#8221; too &#8230; ended up coding a firefox extension that colors the location bar based on which URL you&#8217;re at.</p>
<p>Only problems with my approach (and things I had coded quickly):<br />
- it only worked on Firefox 2, Windows. Then Firefox 3 came out and I dropped the project<br />
- no support for other browsers (IE, Safari, Opera, &#8230;)</p>
<p>Great to see your approach on the subject &#8230; and <a href="http://meyerweb.com/eric/thoughts/2009/01/22/using-http-headers-to-serve-styles/#comment-438100" rel="nofollow">the posted PHP solution in the comments here</a> is neat too!</p>
<p>Thanks,<br />
B!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Michiel van der Blonkq</title>
		<link>http://meyerweb.com/eric/thoughts/2009/01/22/using-http-headers-to-serve-styles/#comment-438223</link>
		<dc:creator>Michiel van der Blonkq</dc:creator>
		<pubDate>Fri, 23 Jan 2009 01:12:48 +0000</pubDate>
		<guid isPermaLink="false">http://meyerweb.com/?p=1010#comment-438223</guid>
		<description>how about a solution to 

- an accidental quote char in the stylesheet, breaking it in FF, and

- background: url (image.jpg) no-repeat 0 0;

in that last one, check the space after url. In FF this works, in IE it breaks.

Well actually that background url problem I usually spot right away because I know it so well. The accidental quote was a really hard one recently, because I use an elegant font in my stylesheet editor (topstyle). The quote (`) was hardly visible.</description>
		<content:encoded><![CDATA[<p>how about a solution to </p>
<p>- an accidental quote char in the stylesheet, breaking it in FF, and</p>
<p>- background: url (image.jpg) no-repeat 0 0;</p>
<p>in that last one, check the space after url. In FF this works, in IE it breaks.</p>
<p>Well actually that background url problem I usually spot right away because I know it so well. The accidental quote was a really hard one recently, because I use an elegant font in my stylesheet editor (topstyle). The quote (`) was hardly visible.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Peter Wilson</title>
		<link>http://meyerweb.com/eric/thoughts/2009/01/22/using-http-headers-to-serve-styles/#comment-438216</link>
		<dc:creator>Peter Wilson</dc:creator>
		<pubDate>Fri, 23 Jan 2009 00:36:55 +0000</pubDate>
		<guid isPermaLink="false">http://meyerweb.com/?p=1010#comment-438216</guid>
		<description>@&lt;a href=&quot;http://meyerweb.com/eric/thoughts/2009/01/22/using-http-headers-to-serve-styles/#comment-438176&quot; rel=&quot;nofollow&quot;&gt;Sherri&lt;/a&gt;

You can add custom headers is IIS too, &lt;a href=&quot;http://technet.microsoft.com/en-us/library/cc753133.aspx&quot; title=&quot;Add custom HTTP response headers&quot; rel=&quot;nofollow&quot;&gt;details are on technet&lt;/a&gt;.</description>
		<content:encoded><![CDATA[<p>@<a href="http://meyerweb.com/eric/thoughts/2009/01/22/using-http-headers-to-serve-styles/#comment-438176" rel="nofollow">Sherri</a></p>
<p>You can add custom headers is IIS too, <a href="http://technet.microsoft.com/en-us/library/cc753133.aspx" title="Add custom HTTP response headers" rel="nofollow">details are on technet</a>.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ben Buchanan</title>
		<link>http://meyerweb.com/eric/thoughts/2009/01/22/using-http-headers-to-serve-styles/#comment-438214</link>
		<dc:creator>Ben Buchanan</dc:creator>
		<pubDate>Fri, 23 Jan 2009 00:20:36 +0000</pubDate>
		<guid isPermaLink="false">http://meyerweb.com/?p=1010#comment-438214</guid>
		<description>Great technique! Pity it&#039;s not supported by more browsers. Given that this only works in Firefox and Opera, you could also do this by running user stylesheets. It does mean everyone has to set it up, but you never have to worry about accidentally publishing it.</description>
		<content:encoded><![CDATA[<p>Great technique! Pity it&#8217;s not supported by more browsers. Given that this only works in Firefox and Opera, you could also do this by running user stylesheets. It does mean everyone has to set it up, but you never have to worry about accidentally publishing it.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Alan Hogan</title>
		<link>http://meyerweb.com/eric/thoughts/2009/01/22/using-http-headers-to-serve-styles/#comment-438202</link>
		<dc:creator>Alan Hogan</dc:creator>
		<pubDate>Thu, 22 Jan 2009 23:30:46 +0000</pubDate>
		<guid isPermaLink="false">http://meyerweb.com/?p=1010#comment-438202</guid>
		<description>Sample &lt;strong&gt;staging.css&lt;/strong&gt; (which &lt;a href=&quot;&quot; rel=&quot;nofollow&quot;&gt;looks like this&lt;/a&gt;): 
&lt;code&gt;
body::before {
	content: &#039;STAGING SITE&#039;;
	position: fixed;
	top: 3px;
	left: 3px;
	font-size: 16px;
	display: block;
	color: white;
	text-shadow: 0.1em 0.1em 0.3em black;
	-o-text-shadow: 0.1em 0.1em 0.3em black;
	-moz-text-shadow: 0.1em 0.1em 0.3em black;
	-webkit-text-shadow: 0.1em 0.1em 0.3em black;
	-ms-text-shadow: 0.1em 0.1em 0.3em black;
	opacity: 0.8;
	-moz-opacity: 0.8;
	-moz-opacity: 0.8;
	-o-opacity: 0.8;
	-ms-filter: &quot;progid:DXImageTransform.Microsoft.Alpha(Opacity=80)&quot;;
	z-index: 999;
}&lt;/code&gt;</description>
		<content:encoded><![CDATA[<p>Sample <strong>staging.css</strong> (which <a href="" rel="nofollow">looks like this</a>):<br />
<code><br />
body::before {<br />
	content: 'STAGING SITE';<br />
	position: fixed;<br />
	top: 3px;<br />
	left: 3px;<br />
	font-size: 16px;<br />
	display: block;<br />
	color: white;<br />
	text-shadow: 0.1em 0.1em 0.3em black;<br />
	-o-text-shadow: 0.1em 0.1em 0.3em black;<br />
	-moz-text-shadow: 0.1em 0.1em 0.3em black;<br />
	-webkit-text-shadow: 0.1em 0.1em 0.3em black;<br />
	-ms-text-shadow: 0.1em 0.1em 0.3em black;<br />
	opacity: 0.8;<br />
	-moz-opacity: 0.8;<br />
	-moz-opacity: 0.8;<br />
	-o-opacity: 0.8;<br />
	-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";<br />
	z-index: 999;<br />
}</code></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Sherri</title>
		<link>http://meyerweb.com/eric/thoughts/2009/01/22/using-http-headers-to-serve-styles/#comment-438176</link>
		<dc:creator>Sherri</dc:creator>
		<pubDate>Thu, 22 Jan 2009 21:03:11 +0000</pubDate>
		<guid isPermaLink="false">http://meyerweb.com/?p=1010#comment-438176</guid>
		<description>Alas not everything is hosted on Apache...
I&#039;ll go look at the greasemonkey and stylish extensions to see if those work on IIS.</description>
		<content:encoded><![CDATA[<p>Alas not everything is hosted on Apache&#8230;<br />
I&#8217;ll go look at the greasemonkey and stylish extensions to see if those work on IIS.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head profile="http://gmpg.org/xfn/1">
<title>meyerweb.com</title>
<link rel="openid.server" href="http://www.myopenid.com/server">
<link rel="openid.delegate" href="http://emeyer.myopenid.com/">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><link rel="shortcut icon" href="/favicon.ico"><link rel="home" href="http://meyerweb.com/" title="Home" ><link rel="stylesheet" href="http://meyerweb.com/ui/meyerweb.css" type="text/css" media="screen, projection"><link rel="stylesheet" href="http://meyerweb.com/ui/theme.css" type="text/css" media="screen, projection" id="themeLink"><link rel="stylesheet" href="http://meyerweb.com/ui/print.css" type="text/css" media="print"><script src="http://meyerweb.com/ui/addresses.js" type="text/javascript"></script><link rel="stylesheet" href="/ui/wordpress.css" type="text/css" media="screen">
<link rel="stylesheet" href="/ui/tfe.css" type="text/css" media="screen">
<link rel="stylesheet" href="/ui/home.css" type="text/css" media="screen">
<link rel="alternate" type="application/rss+xml" title="Thoughts From Eric" href="/eric/thoughts/rss2/full" />
<link rel="alternate" type="application/rss+xml" title="Thoughts From Eric (only technical posts)" href="/eric/thoughts/category/tech/rss2/full" />
<link rel="alternate" type="application/rss+xml" title="Thoughts From Eric (only personal posts)" href="/eric/thoughts/category/personal/rss2/full" />
<link rel="alternate" type="application/rss+xml" title="Distractions" href="/eric/thoughts/recent-links/rss2" />
<link rel="alternate" type="application/rss+xml" title="Excuse of the Day" href="/feeds/excuse/rss20.xml" />
</head>
<body id="www-meyerweb-com" class="hpg">

<div id="sitemast"><h1><a href="/"><span>meyerweb</span>.com</a></h1></div><div id="search"><h4>Exploration</h4><!-- SiteSearch Google --><form method="get" action="http://www.google.com/custom" target="_top"><div><input type="hidden" name="domains" value="meyerweb.com"></input><label for="sbb" style="display: none">Submit search form</label><input type="submit" name="sa" value="Google Search" id="sbb"></input><label for="sbi" style="display: none">Enter your search terms</label><input type="text" name="q" size="31" maxlength="255" value="" id="sbi"></input><p><input type="radio" name="sitesearch" value="meyerweb.com" checked id="ss1"></input><label for="ss1" title="Search meyerweb.com">meyerweb.com</label><input type="radio" name="sitesearch" value="" id="ss0"></input><label for="ss0" title="Search the Web">Web</label></p><input type="hidden" name="client" value="pub-3772084027748653"></input><input type="hidden" name="forid" value="1"></input><input type="hidden" name="ie" value="ISO-8859-1"></input><input type="hidden" name="oe" value="ISO-8859-1"></input><input type="hidden" name="safe" value="active"></input><input type="hidden" name="cof" value="GALT:#008000;GL:1;DIV:#336699;VLC:663399;AH:center;BGC:FFFFFF;LBGC:336699;ALC:0000FF;LC:0000FF;T:000000;GFNT:0000FF;GIMP:0000FF;FORID:1"></input><input type="hidden" name="hl" value="en"></input></div></form><!-- SiteSearch Google --><!-- <form method="get" action="http://www.google.com/custom"><div><input type="submit" name="sa" value="Search"><input type="text" name="q" size="20" maxlength="255" value=""><input type="hidden" name="sitesearch" value="meyerweb.com"></div></form><small><a href="http://www.google.com/search">Powered by Google</a></small> --></div><div id="main"><div class="skipper">Skip to: <a href="#extra">site navigation/presentation</a></div><div class="skipper">Skip to: <a href="#thoughts">Thoughts From Eric</a></div>
<div id="thoughts">


<div class="entry">
<h3><a href="http://meyerweb.com/eric/thoughts/2009/01/22/using-http-headers-to-serve-styles/" rel="bookmark" title="Permanent Link: Using HTTP Headers to Serve Styles">Using HTTP Headers to Serve Styles</a></h3>
<ul class="meta">
<li class="date">Thu 22 Jan 2009</li>
<li class="time">0846</li>
<li class="cat"><a href="http://meyerweb.com/eric/thoughts/category/tech/css/" title="View all posts in CSS" rel="category tag">CSS</a><br> <a href="http://meyerweb.com/eric/thoughts/category/tech/web/" title="View all posts in Web" rel="category tag">Web</a></li>
<li class="cmt"><a href="http://meyerweb.com/eric/thoughts/2009/01/22/using-http-headers-to-serve-styles/#comments">40 responses</a></li>
<li></li><li></li></ul>

<div class="text">
<p>
How many times have you played out the following scenario?
</p>

<ol>
<li>Makes local changes to your style sheet(s).</li>
<li>Upload the changes to the staging server.</li>
<li>Switch to your browser and hit &#8220;reload&#8221;.</li>
<li>Nothing happens.</li>
<li>Force-reload. Nothing happens.</li>
<li>Go back to make sure the upload is finished and successful.</li>
<li>Reload again.  Still nothing.</li>
<li>Try sprinkling in <code>!important</code>.  Upload, reload, nothing.</li>
<li>Start swearing at your computer.</li>
<li>Check Firebug to see what&#8217;s overriding your new styles.  Discover they aren&#8217;t being applied at all.</li>
<li>Continue in that vein for several minutes before realizing you were hitting reload while looking at the live production server, not the staging server.</li>
<li>Go to the staging server and see all your changes.</li>
<li>Start swearing at your own idiocy.</li>
</ol>

<p>
This happened to me <em>all the time</em> as we neared completion of the redesign of <a href="http://aneventapart.com/">An Event Apart</a>.  It got to the point that I would deliberately add obvious, easily-fixable-later errors to the staging server&#8217;s styles, like a light red page background.
</p>
<p>
Now that we&#8217;re launched and I have time to actually, you know, <em>think</em> about how I do this stuff, it occurred to me that what I should have done is create a distinct &#8220;staging&#8221; style sheet with the obvious error or other visual cue.  Maybe repeat the word &#8220;staging&#8221; along the right side of the page with a background image, like a watermark:
</p>

<pre>html {background: url(staging-bg.png) 100% 50% repeat-y;}</pre>

<p>
Okay, cool.  Then I just need to have that served up with every page on the staging server, without it showing up on the production server.
</p>
<p>
One way to do that is just make sure the image file never migrates to production.  That way, even if I accidentally let the above CSS get onto production, the user will never see it.  But that&#8217;s inelegant and wasteful, and fragile to boot: if the styles accidentally migrate, who&#8217;s to say the image won&#8217;t as well?  And while I&#8217;m sure there are all kinds of CMS and CVS and Git and what-have-you tricks to make sure that doesn&#8217;t happen, I am both clumsy and lazy.  Not only do I have great faith in my ability to screw up my use of such mechanisms, I don&#8217;t really want to be bothered to learn them in the first place.
</p>
<p>
So: why not send the link to the style sheet <a href="http://www.w3.org/TR/REC-html40/present/styles.html#h-14.6">using HTTP headers</a>?  Yeah, that&#8217;s the ticket!  I can just add a line to my <tt>.htaccess</tt> file on the staging server and be done.  Under Apache, which is what I use:
</p>

<pre>Header add Link "&lt;/staging.css&gt;;rel=stylesheet;type=text/css;media=all"</pre>

<p>
Those angle brackets are, so far as I can tell, absolutely mandatory, so bear that in mind.  And of course the path in those brackets can be absolute, unlike what I&#8217;ve shown here.  I&#8217;m sure there are simple PHP equivalents, which I&#8217;ll leave to others to work out.  I really didn&#8217;t need to add the <code>media=all</code> part, but what the heck.
</p>
<p>
Seems so simple, doesn&#8217;t it?  Almost&#8230; <em>too</em> simple.  Like there has to be a catch somewhere.  Well, there is.  The catch is that this is not supported by all user agents.  Internet Explorer, for one; Safari, for another.  It <em>does</em> work in Opera and Gecko browsers.  So you can&#8217;t deploy this on your production server, unless of course you want to use it as a way to hide CSS from both IE and Safari.  (For whatever reason.)  It works great in Gecko-based production environments like mine, though.
</p>
<p>
I looked around for a quick how-to on do this, and couldn&#8217;t find one.  Instead, I found <a href="http://annevankesteren.nl/test/html-element/style-header.php">Anne van Kesteren&#8217;s test page</a>, whose headers I sniffed in order to work out the proper value syntax; and <a href="http://esw.w3.org/topic/LinkHeader">a brief page on the Link header</a> that didn&#8217;t mention CSS at all.  Nothing seemed to put the two of them together.  Nothing until now, that is.
</p>
</div>

</div>

</div>
<p style="font-size: 90%; text-align: right; margin-top: 0.5em; padding-top: 0;">(If you care, there's even an <a href="/eric/thoughts/page/2/">archive of previous thoughts</a>...)</p>

</div><div id="extra"><div class="panel" id="archipelago"><h4>Identity Archipelago</h4><ul><li><a href="http://flickr.com/photos/meyerweb/" rel="me">Flickr</a></li><li><a href="http://twitter.com/meyerweb/" rel="me">Twitter</a></li><li><a href="http://dopplr.com/traveller/meyerweb">Dopplr</a></li><li><a href="http://www.linkedin.com/in/meyerweb" rel="me">LinkedIn</a></li><li><a href="http://technorati.com/profile/emeyer" rel="me">Technorati</a></li></ul></div><div class="panel" id="pointers"><h4>Projects Elsewhere</h4><ul><li><a href="http://aneventapart.com/">An Event Apart</a></li><li><a href="http://complexspiral.com/">Complex Spiral Consulting</a></li><li><a href="http://www.webassist.com/go/css/emeyer/">CSS Sculptor</a></li><li><a href="http://css-discuss.org/">css-discuss</a></li><li><a href="http://microformats.org/">Microformats</a></li><li><a href="http://s5project.org/">S5</a></li></ul></div><div class="panel" id="tour"><ul><li><a href="http://fray.com/issue3/"><img src="http://fray.com/images/i3c.gif" alt="Fray Contributor (Issue 3: Sex &amp; Death)" /></a></li><!-- <li><a href="http://www.webassist.com/go/css/emeyer/"><img src="/pix/CS_ad_180x109.jpg" alt="CSS Sculptor for Dreamweaver" style="max-width: 100%;" /></a></li> --></ul></div><div class="panel">
<h4>Recently Tweeted</h4>
<p class="more"><a href="http://twitter.com/meyerweb">see more</a></p>
<p>About once a year, I de-clutter my office.  I usually do it in the spring because the snow shovel is no longer needed elsewhere. <small>&#8211;tweeted 22 hours, 6 minutes ago</small></p>
</div><div id="sideblog" class="panel">
<h4>Distractions</h4>
<p class="more">
<a href="/eric/thoughts/recent-links/">archive</a>
</p>
<ul>
<li><a href="http://8bitnyc.com/" title="March 17 | All of a sudden I want to establish a mission in Central Park and negotiate with the natives for gold and food.">8-Bit NYC</a></li>
<li><a href="http://www.youtube.com/watch?v=nFicqklGuB0&amp;feature=player_embedded" title="March 12 | Wry comment expressing my appreciation of the creative derivativeness of this video and its uncanny accuracy in mocking common tropes.">Academy Award Winning Movie Trailer</a></li>
<li><a href="http://www.youtube.com/watch?v=414TmP12WAU" title="March 9 | &#8220;Apple juice&#8230; for half price!&#8221;  More like twice PRICELESS.  (Note: If you&#8217;re at work, don your headphones.)">Happy in Paraguay</a> <small>[via <a href="http://unstoppablerobotninja.com/">Ethan</a>]</small></li>
<li><a href="http://www.youtube.com/watch?v=9V5ubAOeOBk&amp;feature=player_embedded" title="February 10 | This is approximately the best thing ever.">U900 -Walk Don&#8217;t Run (Isogabamaware)</a></li>
<li><a href="http://www.456bereastreet.com/archive/201002/sifr_default_css_hides_content_from_at_least_one_screen_reader/?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A 456bereastreet %28456 Berea Street%29" title="February 8 | -9999px comes through again, but I really wish we were beyond that kind of thing.">sIFR default CSS hides content from at least one screen reader</a></li>
<li><a href="http://www.macosxhints.com/article.php?story=20100117064356428" title="February 8 | Storing this for future use.">Take a picture with the iSight camera when a folder is opened</a></li>
<li><a href="http://mingle2.com/blog/view/web-developer-mind" title="February 4 | Mostly valid.  (SEE WHAT I DID THERE?)">The Mind of a Web Developer: An Illustrated Diagram</a></li>
<li><a href="http://www.theonion.com/content/news/science_channel_refuses_to_dumb" title="January 28 | &#8220;Punkin Chunkin, for Christ&#8217;s sake&#8230; What more do you people want?&#8221;">Science Channel Refuses To Dumb Down Science Any Further</a></li>
<li><a href="http://www.mailchimp.com/blog/project-omnivore-declassified/" title="January 27 | Sounds like quite a feat.  But I wonder how we&#8217;d feel if Microsoft or Google announced the same kind of thing on their e-mail services.">MailChimp&#8217;s Project Omnivore: Declassified</a></li>
<li><a href="http://www.politifact.com/truth-o-meter/statements/2010/jan/25/carolyn-maloney/congresswoman-says-democratic-presidents-create-mo/" title="January 26 | &#8220;Obviously, luck matters a lot, but when there is a consistent pattern over more than 60 years, it starts to look like more than just luck.&#8221;">Congresswoman says Democratic presidents create more private-sector jobs</a></li>
<li><a href="http://www.ted.com/talks/taylor_mali_what_teachers_make.html" title="January 25 | Truth.">Taylor Mali: What teachers make</a></li>
<li><a href="http://notebook.johnmartz.com/how-websites-work?c=1" title="January 22 | At last, the truth is out and I can stop pretending:  beatific monkeys are what makes it all go.">How websites work</a></li>
<li><a href="http://morsecode.scphillips.com/jtranslator.html" title="January 22 | &#8211; &#8230;. .. &#8230; / .. &#8230; / .- .&#8211; . &#8230; &#8212; &#8212; . / -. &#8212; / &#8230; . .-. .. &#8212; ..- &#8230; .-.. -.&#8211;">Morse Code Translator</a></li>
</ul>
</div>
<div class="panel" id="advisory">
<div class="guarded">
<a href="http://blogadvisorysystem.com/"><img src="/pix/bas/guarded.png" alt="Blog Advisory System Alert Level: Guarded"></a>
</div>
</div>

<div class="panel" id="excuse">
<h4>The <a href="/feeds/excuse/">excuse of the day</a> is</h4>
<p>packet storms caused by a flock of rogue penguins</p>
</div>

<div class="panel" id="extras">
<h4>Extras</h4>
<ul>
<li><a href="/feeds/">Feeds</a> &#8226;</li>
<li><a href="/eric/faq.html">FAQ</a> &#8226;</li>
<li><a href="/family.html">Family</a></li>
</ul>
</div>

</div>

<div id="navigate">
<h4>Navigation</h4>
<ul id="navlinks">
<li id="archLink"><a href="/eric/thoughts/">Archives</a></li>
<li id="cssLink"><a href="/eric/css/">CSS</a></li>
<li id="toolsLink"><a href="/eric/tools/">Toolbox</a></li>
<li id="writeLink"><a href="/eric/writing.html">Writing</a></li>
<li id="speakLink"><a href="/eric/talks/">Speaking</a></li>
<li id="otherLink"><a href="/other/">Leftovers</a></li>
<li id="aboutsite"><a href="/ui/about.html">About this site</a></li>
</ul>
</div>

<div id="footer">
<p class="sosumi">All contents of this site, unless otherwise noted, are &copy;1995-2008 <strong>Eric A. and Kathryn S. Meyer</strong>.  All Rights Reserved.</p>
<p>"<a href="/eric/thoughts/">Thoughts From Eric</a>" is powered by the &uuml;bercool <a href="http://wordpress.org/">WordPress</a></p>
</div>
</body>
</html>
