<?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>David Calhoun&#039;s Blog &#187; css</title>
	<atom:link href="http://davidbcalhoun.com/category/css/feed" rel="self" type="application/rss+xml" />
	<link>http://davidbcalhoun.com</link>
	<description>Just another blog</description>
	<lastBuildDate>Mon, 07 May 2012 02:06:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Implementing iPhone&#8217;s slider unlock with input type=&#8221;range&#8221;</title>
		<link>http://davidbcalhoun.com/2011/implementing-iphone-slider-unlock-with-input-type-range</link>
		<comments>http://davidbcalhoun.com/2011/implementing-iphone-slider-unlock-with-input-type-range#comments</comments>
		<pubDate>Mon, 17 Jan 2011 01:11:04 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[css]]></category>

		<guid isPermaLink="false">http://davidbcalhoun.com/?p=565</guid>
		<description><![CDATA[UPDATE: Chrome has now made the shadow DOM inspectable. Introduction After reading &#8220;What the Heck is Shadow DOM?&#8221; I was inspired to see how far I could style the &#60;input type=&#34;range&#34;&#62; element. Pretty far, as it turns out! My goal was to change the input&#8217;s default appearance: To the visual appearance of the iPhone&#8217;s unlock [...]]]></description>
			<content:encoded><![CDATA[<p>UPDATE: <a href="http://peter.sh/2011/05/inspectable-shadow-dom-the-file-browser-and-new-default-avatars/">Chrome has now made the shadow DOM inspectable</a>.</p>
<h3>Introduction</h3>
<p>After reading <a href="http://glazkov.com/2011/01/14/what-the-heck-is-shadow-dom/">&#8220;What the Heck is Shadow DOM?&#8221;</a> I was inspired to see how far I could style the &lt;input type=&quot;range&quot;&gt; element.  Pretty far, as it turns out!</p>
<p>My goal was to change the input&#8217;s default appearance:</p>
<p><img src="http://davidbcalhoun.com/wp-content/uploads/2011/01/input-range.png" alt="The default appearance for input type=range" title="The default appearance for input type=range" width="144" height="25" class="aligncenter size-full wp-image-567" /></p>
<p>To the visual appearance of the iPhone&#8217;s unlock slider:</p>
<p><img src="http://davidbcalhoun.com/wp-content/uploads/2011/01/iphone-slider-native.png" alt="The iPhone's unlock slider" title="The iPhone's unlock slider" width="300" height="69" class="aligncenter size-full wp-image-566" /></p>
<p>As far as I can tell, only WebKit-based browsers and Opera have implemented input type=&#8221;range&#8221;.  Mobile Safari hasn&#8217;t yet implemented it as of iOS 4.2 and Android also hasn&#8217;t fully implemented it as of Android 2.3 (although curiously the elements are styleable but not yet interactive).  Surprisingly, the only mobile OS to implement this input type seems to be BlackBerry OS 6.</p>
<p>However, the focus here will be to get this working on just Chrome and WebKit.  This will make it a bit easier to do this proof of concept.  So we&#8217;ll be using lots of &#8220;-webkit&#8221; vendor prefixed CSS.</p>
<h3>What we have to work with</h3>
<p>Of course we have our simple range input:</p>
<pre name="code" class="html">
&lt;input type=&quot;range&quot;&gt;
</pre>
<p>Which looks like this:</p>
<p><img src="http://davidbcalhoun.com/wp-content/uploads/2011/01/input-range.png" alt="The default appearance for input type=range" title="The default appearance for input type=range" width="144" height="25" class="aligncenter size-full wp-image-567" /></p>
<p>We can target the input itself with a CSS attribute selector:</p>
<pre name="code" class="CSS">
input[type='range'] {}
</pre>
<p>And if we want, we can transform it into a vertical slider by changing the &#8220;-webkit-appearance&#8221; property:</p>
<pre name="code" class="CSS">
input[type='range'] {
    -webkit-appearance: slider-vertical;
}
</pre>
<p>Which looks like this:</p>
<p><img src="http://davidbcalhoun.com/wp-content/uploads/2011/01/input-range-vertical.png" alt="Input range in a vertical orientation" title="Input range in a vertical orientation" width="25" height="119" class="aligncenter size-full wp-image-579" /></p>
<p>If we want to style it as if it was any other element, there&#8217;s a slight catch, as we first have to set &#8220;-webkit-appearance&#8221; to &#8220;none&#8221; and then add our customizations (this appears to mean that we can&#8217;t actually style vertical sliders&#8230;).  Here we&#8217;ll set the background color as a simple demo:</p>
<pre name="code" class="CSS">
input[type='range'] {
    -webkit-appearance: none;
    background-color: gray;
}
</pre>
<p>This outputs the following:</p>
<p><img src="http://davidbcalhoun.com/wp-content/uploads/2011/01/input-range-gray-background.png" alt="Input range with a gray background" title="Input range with a gray background" width="129" height="15" class="aligncenter size-full wp-image-577" /></p>
<p>Most interestingly, we can target and style the slider button itself with CSS, although we can&#8217;t get access to it with JavaScript (for the time being anyhow).  Here we&#8217;ll style it a slightly darker shade of gray:</p>
<pre name="code" class="CSS">
input[type='range'] {
    -webkit-appearance: none;
    background-color: gray;
}

input[type='range']::-webkit-slider-thumb {
    -webkit-appearance: none;
    background-color: #444;
    width: 15px;
    height: 20px;
}
</pre>
<p>Which results in this:<br />
<img src="http://davidbcalhoun.com/wp-content/uploads/2011/01/input-range-styled.png" alt="Input range with a gray background and a slightly darker slider control" title="Input range with a gray background and a slightly darker slider control" width="129" height="20" class="aligncenter size-full wp-image-583" /></p>
<p>Now all the pieces are in place to fully style the input!</p>
<h3>Styling the background</h3>
<p>This part&#8217;s no big deal.  We just want to set up the width/height, slap on some handy rounded corners, and add a very slight background gradient:</p>
<pre name="code" class="CSS">
input[type='range'] {
    -webkit-appearance: none;
    width: 280px;
    height: 46px;
    padding: 3px;
    -webkit-border-radius: 15px;
    border-radius: 15px;
    border: 1px solid #525252;
    background-image: -webkit-gradient(
        linear,
        left top,
        left bottom,
        color-stop(0, #000000),
        color-stop(1, #222222)
    );
}
</pre>
<p>Now we have the backdrop in place:</p>
<p><img src="http://davidbcalhoun.com/wp-content/uploads/2011/01/iphone-slider-background.png" alt="iPhone slider background" title="iPhone slider background" width="288" height="54" class="aligncenter size-full wp-image-585" /></p>
<h3>Styling the button</h3>
<p>To get the button, we&#8217;ll add some width/height and rounded corners.  Here we&#8217;ll also need a more complicated background gradient as well as an arrow icon.  Your first instinct might be to add more markup to hook the arrow icon to, but remember that this is impossible.  We&#8217;re working in the &#8220;shadow DOM&#8221; of elements created and maintained by the browser itself.  We can style the existing elements but we can&#8217;t create any new ones.</p>
<p>So what do we do?  Take advantage of multiple backgrounds!  We can specify the background as both the arrow image and the gradient we need.  In this case we&#8217;ll also base64 encode the small image to avoid an extra HTTP request.</p>
<p>The CSS for the button looks like this:</p>
<pre name="code" class="CSS">
input[type='range']::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 68px;
    height: 44px;
    -webkit-border-radius: 10px;
    border-radius: 10px;
    background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAYCAYAAAB0kZQKAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAASJJREFUeNpi7OnpYaAC0AXiF0D8mhzNTAzUASBHnAdim4F0BAhIA/EBIC4aSEeAADMQ9wLxRiDmHyhHwIAfNHqMiXZEcXExGJMCiNCjCMTHgDiTkFmM////p4rXe3t78Rm0DIjTgfgLNkkWoGZQij7MQFsQBY2aICC+Rq80gQ2oA/EZIE4YSEeAACcQzwfimVD2gDgCBtKgiVZlIB0BAgbQbBwykI5A5I4BtPsaNLfcHKiQWADEJiAHDERIfAfiLKgjBiQ67kCD/zK2NAFqjMyi0AJQVnPCI78GiBNxFttQF6ZToVjG5ohfoLoOiKcMVO54BA3+swPVntgKxIbEOIAWjvgLxJVA7APE7waisHoKxBFAfGSgSszL0MLnBTmaAQIMAKg/OsrT7JG8AAAAAElFTkSuQmCC'),
    -webkit-gradient(
        linear,
        left top,
        left bottom,
        color-stop(0, #fefefe),
        color-stop(0.49, #dddddd),
        color-stop(0.51, #d1d1d1),
        color-stop(1, #a1a1a1)
    );
    background-repeat: no-repeat;
    background-position: 50%;
}
</pre>
<p>Which outputs this:<br />
<img src="http://davidbcalhoun.com/wp-content/uploads/2011/01/iphone-slider-button.png" alt="" title="iPhone slider button styled" width="288" height="54" class="aligncenter size-full wp-image-587" /></p>
<h3>&#8220;Slide to unlock&#8221; text</h3>
<p>Now we&#8217;re getting somewhere!  And now we&#8217;re approaching the limits of what we can do without getting pretty creative.  We need some &#8220;slide to unlock&#8221; text in the background.</p>
<p>The first thing to do is to move the slider all the way to the left, to the default position.  We do this through HTML by setting the value to 0:</p>
<pre name="code" class="HTML">
&lt;input type=&quot;range&quot; value=&quot;0&quot;&gt;
</pre>
<p>Ok, that wasn&#8217;t too hard.  But what about the text?  We can&#8217;t modify anything in the input itself, because it doesn&#8217;t contain any element to display text.  And we can&#8217;t dynamically add text with JavaScript, because again, it&#8217;s the shadow DOM!  What we can do is create a separate text element outside of the input and position it on top of the slider using absolute positioning.</p>
<p>But this would be no good, since the text would appear over the button itself.  What we want is for the text to show up in-between the button and the background.  Since we can style both of these with CSS, we can control the stacking order with good old z-index!</p>
<p>And while we&#8217;re at it, we might as well animate the &#8220;spotlight&#8221; effect on the text.  We can do this with a combination of a semitransparent -webkit-mask and animations (see below).</p>
<p>First we have the HTML, which has changed a bit.  For positioning and grouping, we need a wrapped element for the input and the span of text:</p>
<pre name="code" class="HTML">
&lt;div class=&quot;iphone-slider&quot;&gt;
    &lt;input type=&quot;range&quot; value=&quot;0&quot;&gt;&lt;/input&gt;
    &lt;span&gt;slide to unlock&lt;/span&gt;
&lt;/div&gt;
</pre>
<p>The final complete CSS is as follows:</p>
<pre name="code" class="CSS">
.iphone-slider {
    width: 280px;
    height: 46px;

    /* set the wrapper as the anchor element for positioning */
    position: relative;
}

.iphone-slider input {
    -webkit-appearance: none;
    width: 100%;
    background: #ddd;
    padding: 3px;
    border: 1px solid #525252;
    -webkit-border-radius: 15px;
    border-radius: 15px;
    background-image: -webkit-gradient(
        linear,
        left top,
        left bottom,
        color-stop(0, #000000),
        color-stop(1, #222222)
    );
}

.iphone-slider input::-webkit-slider-thumb {
    -webkit-appearance: none;

    /* position the button on top of everything */
    z-index: 100;
    position: relative;

    width: 68px;
    height: 44px;
    -webkit-border-radius: 10px;
    border-radius: 10px;

    /* arrow and button gradient */
    background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAYCAYAAAB0kZQKAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAASJJREFUeNpi7OnpYaAC0AXiF0D8mhzNTAzUASBHnAdim4F0BAhIA/EBIC4aSEeAADMQ9wLxRiDmHyhHwIAfNHqMiXZEcXExGJMCiNCjCMTHgDiTkFmM////p4rXe3t78Rm0DIjTgfgLNkkWoGZQij7MQFsQBY2aICC+Rq80gQ2oA/EZIE4YSEeAACcQzwfimVD2gDgCBtKgiVZlIB0BAgbQbBwykI5A5I4BtPsaNLfcHKiQWADEJiAHDERIfAfiLKgjBiQ67kCD/zK2NAFqjMyi0AJQVnPCI78GiBNxFttQF6ZToVjG5ohfoLoOiKcMVO54BA3+swPVntgKxIbEOIAWjvgLxJVA7APE7waisHoKxBFAfGSgSszL0MLnBTmaAQIMAKg/OsrT7JG8AAAAAElFTkSuQmCC'),
    -webkit-gradient(
        linear,
        left top,
        left bottom,
        color-stop(0, #fefefe),
        color-stop(0.49, #dddddd),
        color-stop(0.51, #d1d1d1),
        color-stop(1, #a1a1a1)
    );
    background-repeat: no-repeat;
    background-position: 50%;
}

.iphone-slider span {
    /* position the text just under the button in the stacking order */
    position: absolute;
    z-index: 99;
    top: 30%;
    left: 37%;

    font-family: "Helvetica Neue", Helvetica, sans;
    font-size: 24px;
    color: white;
    cursor: default;
    -webkit-user-select: none;

    /* semitransparent gradient mask to animate over the text */
    -webkit-mask-image: -webkit-gradient(
        linear,
        left top,
        right top,
        color-stop(0, rgba(0,0,0,0.3)),
        color-stop(0.45, rgba(0,0,0,0.3)),
        color-stop(0.5, rgba(0,0,0,1)),
        color-stop(0.55, rgba(0,0,0,0.3)),
        color-stop(1, rgba(0,0,0,0.3))
    );
    -webkit-mask-size: 1000px;
    -webkit-mask-repeat: no-repeat;
    -webkit-animation-timing-function: ease-in-out;
    -webkit-animation: text-spotlight 4s infinite;
}

/* animate the webkit-mark over the text */
@-webkit-keyframes text-spotlight {
  0% {
    -webkit-mask-position: -800px;
  }

  100% {
    -webkit-mask-position: 0px;
  }
}
</pre>
<p>This renders as the following:</p>
<p><img src="http://davidbcalhoun.com/wp-content/uploads/2011/01/iphone-slider-mask.png" alt="" title="The final result" width="288" height="52" class="aligncenter size-full wp-image-589" /></p>
<p>Which looks pretty dang close the the native iPhone slider if I do say so myself!  (perhaps the arrow could use some box-shadow to make it pop a bit more however).</p>
<h3>Just a bit of JavaScript</h3>
<p>Since we&#8217;ve come this far, we might as well make the experience as authentic as possible.  Here I&#8217;ve thrown in some JavaScript to check if the slider has been fully moved to the right, giving the user notification that the phone is unlocked.</p>
<p>Also, you&#8217;ll notice the opacity of the text slowly fade as the slider is moved farther to the right.  This mimics the actual experience on the iPhone.</p>
<p>Here&#8217;s the JavaScript to make this work:</p>
<pre name="code" class="JScript">
(function() {
  // variable declarations
  var slider, sliderInput, sliderButton, sliderText, sliderTimeout, sliderOnchange, unlockCheck;

  // cache our DOM elements in variables
  slider = document.querySelector('.iphone-slider');
  sliderInput = slider.querySelector('input');
  sliderButton = sliderInput.querySelector('::-webkit-slider-thumb');
  sliderText = slider.querySelector('span');

  /*
      Check if it's been unlocked, else return the
      button back to the left side (default position).
  */
  unlockCheck = function() {
    if(sliderInput.value == 100) {
      sliderText.innerHTML = 'Unlocked!';
      sliderInput.value = 0;
      sliderText.style.opacity = 1;
    } else {
      setTimeout(function(){
        sliderInput.value = 0;
        sliderText.style.opacity = 1;
      }, 1000);
    }
  };

  sliderOnchange = function() {
    /*
        Set the opacity of the text relative to the value
        on the input range.
    */
    sliderText.style.opacity = ((100 - sliderInput.value) / 200);

    /*
        Add a timeout to prevent the function from being called
        on EVERY onchange event.
    */
    clearTimeout(sliderTimeout);
    sliderTimeout = setTimeout(unlockCheck, 300);
  }

  slider.onchange = sliderOnchange;
})();
</pre>
<h3>Live example</h3>
<p>Here&#8217;s a <a href="http://www.youtube.com/watch?v=lC_pcRZgNm0">video</a> of the slider in action:<br />
<object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/lC_pcRZgNm0?fs=1&amp;hl=en_US"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/lC_pcRZgNm0?fs=1&amp;hl=en_US" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object></p>
<p>If you&#8217;re running Safari or Chrome, you should be able to see and interact with the <a href="http://davidbcalhoun.com/a/iphone-slider.html">standalone demo</a>.</p>
<p>Sweet!  Well, that was fun!  This was some good practice of using a ton of good stuff: border radius, gradients, multiple backgrounds, data URI images, webkit-mask-image, webkit-animation, and of course styleable input ranges via webkit-slider-thumb.</p>
]]></content:encoded>
			<wfw:commentRss>http://davidbcalhoun.com/2011/implementing-iphone-slider-unlock-with-input-type-range/feed</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Does it still make sense to use em rather than px?</title>
		<link>http://davidbcalhoun.com/2010/does-it-still-make-sense-to-use-em-rather-than-px</link>
		<comments>http://davidbcalhoun.com/2010/does-it-still-make-sense-to-use-em-rather-than-px#comments</comments>
		<pubDate>Tue, 05 Oct 2010 18:13:15 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[css]]></category>
		<category><![CDATA[em]]></category>
		<category><![CDATA[media queries]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[px]]></category>

		<guid isPermaLink="false">http://davidbcalhoun.com/?p=476</guid>
		<description><![CDATA[Alex Kessinger tweeted asking if there was a reason to still use EMs instead of PX measurements in mobile. This is an interesting question, but 140 characters isn&#8217;t quite enough to explain my thoughts. So here&#8217;s an old-fashioned blog post! Just a quick review: em and percentage (%) units in CSS are relative measurements, whereas [...]]]></description>
			<content:encoded><![CDATA[<p>Alex Kessinger <a href="http://twitter.com/voidfiles/status/26470129747">tweeted</a> asking if there was a reason to still use EMs instead of PX measurements in mobile.  This is an interesting question, but 140 characters isn&#8217;t quite enough to explain my thoughts.  So here&#8217;s an old-fashioned blog post!</p>
<p>Just a quick review: em and percentage (%) units in CSS are relative measurements, whereas px and other measurements are not.  What this means is that the resulting size of relative measurements depends on the size of the parent.</p>
<h3>The original reason to use EMs instead of PX measurements</h3>
<p>As far as I can tell, the original reason why it became a good practice to use EMs was because of page scaling and accessibility reasons.  When developers used PX measurements, they found that when the page was scaled (using Ctrl + Scroll Wheel), the parts of the page with fixed PX measurements didn&#8217;t scale.</p>
<p>Oh no!  So when a user with poor eyesight tried to scale a page to read the text better, it turns out that the text they were interesting in making bigger actually didn&#8217;t change size at all!</p>
<p>So is this still the case today?  By and large, no.  All modern browsers except IE6 will now scale pages correctly, regardless of the type of CSS units used.</p>
<p>From what I&#8217;ve heard, there are still many users with disabilities using IE6, but the reason is because they don&#8217;t want to upgrade their copy of the screen reader JAWS, which is quite expensive.  However, these users obviously aren&#8217;t affected by page scaling issues because they are blind.</p>
<h3>Maintainability concerns</h3>
<p>Even if the original reason to use EMs (above) is no longer valid, I still believe there are good reasons to use them.</p>
<p>One of the main reasons is maintainability.  If a page is designed to have one base font size (applied to the Body) and all other font sizes on the page use relative units (EMs or percentages), changing the font sizes later becomes almost trivial.  If someone wants to later increase the size of the fonts on their entire page, all they need to do is increase the one base font size.</p>
<p>This might be a bit of an edge case, but the elegance of the solution is too enticing!  <img src='http://davidbcalhoun.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>Media queries and mobile</h3>
<p>Very closely related to the above point is the subject of media queries.  Recently media queries have been somewhat hailed as a <a href="http://www.quirksmode.org/blog/archives/2010/09/rethinking_the.html">panacea for all mobile development</a>.  I slightly disagree, but that&#8217;s a topic for another post!</p>
<p>The main point here is that people are now using media queries to quickly make mobile-friendly versions of their desktop websites.  That&#8217;s awesome, there&#8217;s no doubt about that.</p>
<p>So what about EMs and PX measurements?  Here&#8217;s the problem: if a developer coded their webpage in such a way that they used fixed pixel measurements, the amount of CSS required in the mobile media query could be obscenely large.  This is because each individual element with pixel measurement was <i>designed with the desktop in mind</i>!  This makes the task of adapting to different content very painful.</p>
<p>On the other hand, think about a page designed with relative units such as EMs or percentages.  This page was designed so that each element was proportional to its parent element, so that ideally changing the size of the entire page occurs in only a few places, at the Body level of the document.  Suddenly the CSS required for the mobile media query is much more manageable, since it&#8217;s now (ideally) only changing a few values on the Body element, not on <i>every</i> element on the page.</p>
]]></content:encoded>
			<wfw:commentRss>http://davidbcalhoun.com/2010/does-it-still-make-sense-to-use-em-rather-than-px/feed</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>Targeting Internet Explorer (IE): the age-old struggle</title>
		<link>http://davidbcalhoun.com/2010/targeting-ie-the-age-old-struggle</link>
		<comments>http://davidbcalhoun.com/2010/targeting-ie-the-age-old-struggle#comments</comments>
		<pubDate>Wed, 07 Jul 2010 08:55:49 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[css]]></category>
		<category><![CDATA[conditional comments]]></category>
		<category><![CDATA[hacks]]></category>
		<category><![CDATA[ie hack]]></category>
		<category><![CDATA[ie6]]></category>
		<category><![CDATA[ie7]]></category>
		<category><![CDATA[ie8]]></category>
		<category><![CDATA[ie9]]></category>

		<guid isPermaLink="false">http://davidbcalhoun.com/?p=332</guid>
		<description><![CDATA[As long as I can remember, developers have always been trying to target IE one way or another. Thanks to the wonders of modern technology, there have been multiple ways to pull this off. I guess I really haven&#8217;t been keeping up with the latest frontend trends (doh!), as I&#8217;ve just recently discovered this very [...]]]></description>
			<content:encoded><![CDATA[<p>As long as I can remember, developers have always been trying to target IE one way or another.  Thanks to the wonders of modern technology, there have been multiple ways to pull this off.</p>
<p>I guess I really haven&#8217;t been keeping up with the latest frontend trends (doh!), as I&#8217;ve just recently discovered this very elegant solution circa 2008 offered by <a href="http://paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/">Paul Irish</a>, which sticks a class on the body tag using proprietary conditional IE tags (no JavaScript magic needed here!):</p>
<pre name="code" class="html">
&lt;!--[if lt IE 7 ]&gt; &lt;body class=&quot;ie6&quot;&gt; &lt;![endif]--&gt;
&lt;!--[if IE 7 ]&gt;    &lt;body class=&quot;ie7&quot;&gt; &lt;![endif]--&gt;
&lt;!--[if IE 8 ]&gt;    &lt;body class=&quot;ie8&quot;&gt; &lt;![endif]--&gt;
&lt;!--[if IE 9 ]&gt;    &lt;body class=&quot;ie9&quot;&gt; &lt;![endif]--&gt;
&lt;!--[if gt IE 9]&gt;  &lt;body&gt;             &lt;![endif]--&gt;
&lt;!--[if !IE]&gt;&lt;!--&gt; &lt;body&gt;         &lt;!--&lt;![endif]--&gt;
</pre>
<p>No need for creating multiple stylesheets for each version of IE (that makes extra network requests&#8230; boo)!  Now you can add adjustments to your main stylesheet just as you would with CSS hacks, except now you&#8217;re doing it in a not-so-hacky way.</p>
<p>For instance, if you have some peculiar CSS quirk in IE6, you simply apply a fix like this:</p>
<pre name="code" class="css">
.some-element { width: 200px; }         /* standards-based browsers */
.ie6 .some-element { width: 160px; }  /* elegant ie6 fix! */
</pre>
<h3>The old way: CSS hacks</h3>
<p>Previously I considered some CSS hacks the most elegant solution, but that was in the days when IE6/7 ruled.  You can see that the following CSS hack gets really unruly for IE8 (that hack thanks to <a href="http://my.opera.com/dbloom/blog/2009/03/11/css-hack-for-ie8-standards-mode">David Bloom</a>):</p>
<pre name="code" class="css">
.some-element {
    width: 200px;                /* standards-based browsers */
    /* some yet-to-be-determined IE9 hack goes here */
    width /*\**/: 180px\9        /* targets IE8 standards mode */
    *width: 170px;               /* targets IE7/IE6 */
    _width: 160px;               /* targets IE6 */
}
</pre>
<p>This works, but becomes quite difficult to maintain and understand.  And it just creates a need for someone to find yet another hack for each new version of IE that&#8217;s released.  By using the IE conditional comments to add a class to the body tag, we can accomplish the same result in a way that is easier to read and maintain and is dead simple to update when a new version of IE is released:</p>
<pre name="code" class="css">
.some-element { width: 200px; }
.ie9 .some-element { width: 190px; }
.ie8 .some-element { width: 180px; }
.ie7 .some-element { width: 170px; }
.ie6 .some-element { width: 160px; }
</pre>
<p>Woohoo!</p>
<h3>Related links</h3>
<p><a href="http://www.phpied.com/conditional-comments-block-downloads/">Conditional comments block downloads</a>: Stoyan Stefanov&#8217;s concerns over using this pattern</p>
]]></content:encoded>
			<wfw:commentRss>http://davidbcalhoun.com/2010/targeting-ie-the-age-old-struggle/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A primer on CSS colors</title>
		<link>http://davidbcalhoun.com/2009/a-primer-on-css-colors</link>
		<comments>http://davidbcalhoun.com/2009/a-primer-on-css-colors#comments</comments>
		<pubDate>Wed, 30 Dec 2009 05:17:41 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[css]]></category>
		<category><![CDATA[color]]></category>
		<category><![CDATA[hex]]></category>
		<category><![CDATA[rgb]]></category>
		<category><![CDATA[rgba]]></category>
		<category><![CDATA[web safe]]></category>

		<guid isPermaLink="false">http://davidbcalhoun.com/?p=85</guid>
		<description><![CDATA[Color keywords Example usage: // Example body { color: red; } // Generalization (not actual code) body { color: color_name; } Because color names are easy to remember, they&#8217;re handy for getting quick results, especially while doing rapid prototyping. W3C&#8217;s CSS1 recommendation first mentioned 16 color keywords that you can use: aqua, black, blue, fuchsia, [...]]]></description>
			<content:encoded><![CDATA[<h3>Color keywords</h3>
<p>Example usage:</p>
<pre name="code" class="css">// Example
body { color: red; }

// Generalization (not actual code)
body { color: color_name; }</pre>
<p>Because color names are easy to remember, they&#8217;re handy for getting quick results, especially while doing rapid prototyping.</p>
<p><a href="http://www.w3.org/TR/CSS1/#color-units">W3C&#8217;s CSS1 recommendation</a> first mentioned 16 color keywords that you can use: <em>aqua, black, blue, fuchsia, gray, green, lime, maroon, navy, olive, purple, red, silver, teal, white, and yellow</em>:</p>
<table>
<tr>
<th>Color</th>
<th>Hexadecimal</th>
<th>Color</th>
<th>Hexadecimal</th>
<th>Color</th>
<th>Hexadecimal</th>
<th>Color</th>
<th>Hexadecimal</th>
</tr>
<tr>
<td>aqua / cyan</td>
<td style="background:#0FF; color:#000; font-family:monospace;">#00FFFF</td>
<td>gray</td>
<td style="background:#808080; color:#FFF; font-family:monospace;">#808080</td>
<td>navy</td>
<td style="background:#000080; color:#FFF; font-family:monospace;">#000080</td>
<td>silver</td>
<td style="background:#C0C0C0; color:#000; font-family:monospace;">#C0C0C0</td>
</tr>
<tr>
<td>black</td>
<td style="background:#000; color:#FFF; font-family:monospace;">#000000</td>
<td>green</td>
<td style="background:#008000; color:#FFF; font-family:monospace;">#008000</td>
<td>olive</td>
<td style="background:#808000; color:#FFF; font-family:monospace;">#808000</td>
<td>teal</td>
<td style="background:#008080; color:#fff; font-family:monospace;">#008080</td>
</tr>
<tr>
<td>blue</td>
<td style="background:#00F; color:#FFF; font-family:monospace;">#0000FF</td>
<td>lime</td>
<td style="background:#0F0; color:#000; font-family:monospace;">#00FF00</td>
<td>purple</td>
<td style="background:#800080; color:#FFF; font-family:monospace;">#800080</td>
<td>white</td>
<td style="background:#FFF; color:#000; font-family:monospace;">#FFFFFF</td>
</tr>
<tr>
<td>fuchsia / magenta</td>
<td style="background:#F0F; color:#000; font-family:monospace;">#FF00FF</td>
<td>maroon</td>
<td style="background:#800000; color:#FFF; font-family:monospace;">#800000</td>
<td>red</td>
<td style="background:#F00; color:#FFF; font-family:monospace;">#FF0000</td>
<td>yellow</td>
<td style="background:#FF0; color:#000; font-family:monospace;">#FFFF00</td>
</tr>
</table>
<p>(color table from <a href="http://en.wikipedia.org/wiki/Web_colors">Wikipedia</a>)</p>
<p><a href="http://www.w3.org/TR/CSS2/syndata.html#keywords">CSS2</a> officially mapped the colors to recommended hex values and also added the color orange.  <a href="http://www.w3.org/TR/css3-color/#html4">CSS3</a> removed orange, presumably because having 17 colors was aesthetically unpleasing in a binary world?</p>
<p>In addition to these 16 &#8220;official&#8221; colors, there&#8217;s <a href="http://www.w3schools.com/css/css_colornames.asp">even more unofficial color names</a> you can use that appear to be supported in all the major browsers.</p>
<h3>RGB values</h3>
<p>Example usage:</p>
<pre name="code" class="css">// Example
body { color: rgb(255,0,0); }

// Generalization (not actual code)
body { color: rgb(red [integer 0-255], green [integer 0-255], blue [integer 0-255]); }</pre>
<p>For this section it&#8217;s very handy to know a bit about <a href="http://en.wikipedia.org/wiki/Color_theory">color theory</a>, particularly these facts:</p>
<ul>
<li>all colors can be made from a combination of red, green, and blue (RGB) as the primary colors</li>
<li>in light (additive color mixing), the absence of all color results in the color black</li>
<li>in light (additive color mixing), the mixing of red, green, and blue in equal amounts results in the color white</li>
</ul>
<p>With the rgb attribute, we specify the amount of each color we want with an integer from 0 to 255.  Here we can see both black and white expressed as rgb values:</p>
<p>Black:<br />
<span class="small-box" style="background-color: rgb(0,0,0);"></span>rgb(0,0,0)</p>
<p>White:<br />
<span class="small-box" style="background-color: rgb(255,255,255);"></span>rgb(255,255,255)</p>
<p>Also note that if all three values are equal, there is no color that predominates and the result is a shade of gray.</p>
<p>Dark gray:</p>
<p><span class="small-box" style="background-color: rgb(30,30,30);"></span>rgb(30,30,30)</p>
<p>A lighter shade of gray:</p>
<p><span class="small-box" style="background-color: rgb(200,200,200);"></span>rgb(200,200,200)</p>
<p>And of course we can favor only one color, which in this case gives us a full red, with no green or blue:</p>
<p><span class="small-box" style="background-color: rgb(255,0,0);"></span>rgb(255,0,0)</p>
<p>You may have guessed that we can also use percentage values to represent the same color:</p>
<p><span class="small-box" style="background-color: rgb(100%, 0%, 0%);"></span>rgb(100%, 0%, 0%)</p>
<h3>RGBA values</h3>
<pre name="code" class="css">// Example
body { color: rgba(255,0,0,0.5); }

// Generalization (not actual code)
body { color: rgb(red [integer 0-255], green [integer 0-255], blue [integer 0-255], alpha transparency [float 0-1]); }</pre>
<p><a href="http://www.w3.org/TR/css3-color/#rgba-color">CSS3</a> introduced rgba, which is in every way similar to rgb, except for the addition of a fourth value, alpha opacity, which gives us control over the transparency of the color.</p>
<p>So the equivalent full red we have above would look like this (no transparency):</p>
<p><span class="small-box" style="background-color: rgba(255, 0, 0, 1);"></span>rgba(255, 0, 0, 1)</p>
<p><span class="small-box" style="background-color: rgba(100%, 0%, 0%, 1);"></span>rgba(100%, 0%, 0%, 1)</p>
<p>And the same color, only now semitransparent:</p>
<p><span class="small-box" style="background-color: rgba(255, 0, 0, 0.5);"></span>rgba(255, 0, 0, 0.5)</p>
<p><span class="small-box" style="background-color: rgba(100%, 0%, 0%, 0.5);"></span>rgba(100%, 0%, 0%, 0.5)</p>
<h3>Hex values</h3>
<p>Example usage:</p>
<pre name="code" class="css">// Example
body { color: #ff0000; }

// Generalization (not actual code)
body { color: #rrggbb; }</pre>
<p>Hex values are probably the most common out of all of the ways to represent colors in CSS.  But I included them last &#8211; what gives?  It seems to me that the rgb value should logically be explained first.  The hex value is just a hex version (and thus slightly more confusing version) of expressing rgb values.</p>
<p>For this section you ought to know the basics of <a href="http://en.wikipedia.org/wiki/Hexadecimal">hexadecimal numbers</a>.  In particular, the fact that hexadecimals are base 16 and use letters a-f to represent numbers beyond our conventional base 10 range.</p>
<p>The hex value starts with a hash (#) and is followed by six numbers and/or letters.  This is simply our three color values again: red, green, blue, with each color allowed two digits.</p>
<p>We express our solid red color like this:</p>
<p><span class="small-box" style="background-color: #ff0000;"></span>#ff0000</p>
<p>As long as you can convert between decimal and hexadecimal (there&#8217;s <a href="http://www.google.com/search?aq=f&#038;ie=UTF-8&#038;q=decimal+to+hex">a few free tools online</a>), it&#8217;s relatively easy to convert between rgb and hex color values.  Just keep in mind that the first 16 hex values are preceded by a zero (0 becomes 00, 1 becomes 01, 10 becomes 0a, 11 becomes 0b, etc.)</p>
<h3>Shorthand hex</h3>
<p>Example usage:</p>
<pre name="code" class="css">// Example
body { color: #f00; }

// Generalization (not actual code)
body { color: #rgb; }</pre>
<p>Last but not least, if each rgb value has a repeating value, you can simply omit the repeating value.  In the case above each of our color values was repeating (red = ff, green = 00, blue = 00), so we simply drop the repeating digit from each color and cut three bytes from our code:</p>
<p><span class="small-box" style="background-color: #f00;"></span>#f00</p>
<h3>A note on web-safe colors</h3>
<p><a href="http://en.wikipedia.org/wiki/Web_colors#Web-safe_colors">Web safe colors</a> were a recommended subset of about 256 colors with which to design websites.  The rationale for solely using them for web design was for rendering consistency, so even users with very limited displays could see the page as it was intended to be displayed.</p>
<p>The concept of a &#8220;web safe&#8221; color was becoming obsolete even in 1997 or so, when I started making my personal website on AOL.  It&#8217;s safe to say that the vast majority of users today are now able to view webpages with at least 16 million colors (256*256*256).</p>
<p>But this doesn&#8217;t mean we shouldn&#8217;t be concerned about colors.  Apart from pure aesthetics, in the area of accessibility it&#8217;s often mentioned that users with colorblindness find certain combinations of colors difficult to see.  So keep this in the back of your head when you go crazy with those wild color schemes!</p>
<h3>More info</h3>
<p>Probably the best way to learn how to use these color values is to actually try them on your website, however you might also find the following links useful.</p>
<div class="website"><a href="http://colorschemedesigner.com/"><img src="http://davidbcalhoun.com/wp-content/uploads/2009/12/color-scheme-designer.png" alt="Color Scheme Designer" title="Color Scheme Designer" width="300"/></a>
<div>
<p><a href="http://colorschemedesigner.com/">Color Scheme Designer</a> is a nice tool for finding several colors that (theoretically) should go well together.  It&#8217;s a nice place to go when building a website from the ground-up.</p>
<p><a href="http://colorschemedesigner.com/">http://colorschemedesigner.com/</a></p>
</div>
</div>
<div class="website"><a href="http://schlaeps.com/mootools/gradient-creator/"><img src="http://davidbcalhoun.com/wp-content/uploads/2009/12/mootols-webkit-gradient.png" alt="Color Scheme Designer" title="Color Scheme Designer" width="300"/></a>
<div>
<p><a href="http://schlaeps.com/mootools/gradient-creator/">Jonathan Schlaepfer</a> made a nice helper tool built in Mootols for creating webkit gradients.  Gradients wasn&#8217;t the subject of this entry, but it&#8217;s helpful to see a nice visualization of rgb values corresponding to the hex values.</p>
<p><a href="http://schlaeps.com/mootools/gradient-creator/">http://schlaeps.com/mootools/gradient-creator/</a></p>
</div>
</div>
<p><a href="http://en.wikipedia.org/wiki/Web_colors">Wikipedia: Web colors</a></p>
<p><a href="http://www.w3schools.com/html/html_colors.asp">HTML Colors</a></p>
]]></content:encoded>
			<wfw:commentRss>http://davidbcalhoun.com/2009/a-primer-on-css-colors/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

