<?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>User Agent Man &#187; CSS</title>
	<atom:link href="http://www.useragentman.com/blog/category/technologies/css/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.useragentman.com/blog</link>
	<description>A Blog about Client Side Web Technology</description>
	<lastBuildDate>Thu, 26 Jan 2012 03:14:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Cross Browser HTML5 Progress Bars In Depth</title>
		<link>http://www.useragentman.com/blog/2012/01/03/cross-browser-html5-progress-bars-in-depth/</link>
		<comments>http://www.useragentman.com/blog/2012/01/03/cross-browser-html5-progress-bars-in-depth/#comments</comments>
		<pubDate>Tue, 03 Jan 2012 07:08:54 +0000</pubDate>
		<dc:creator>zoltan</dc:creator>
				<category><![CDATA[CSS3]]></category>
		<category><![CDATA[Forms]]></category>
		<category><![CDATA[gradients]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Polyfills]]></category>
		<category><![CDATA[progress]]></category>

		<guid isPermaLink="false">http://www.useragentman.com/blog/?p=4016</guid>
		<description><![CDATA[<img src="http://www.useragentman.com/blog/wp-content/uploads/2012/01/intro.png" />  As a web application developer,<strong> progress bars are great when you want to show the user that some action is happening,</strong> especially when it can take a long time.  Creating them is easy with the HTML5 <code>&#60;progress&#62;</code> tag.  This article will discuss <strong>how this tag is rendered by default</strong> in all operating systems and browsers and how to <strong>style the <code>progress</code> tag with CSS</strong>, even in browsers that don't officially support the it.  It will also show some <strong>interesting examples using advanced CSS3 techniques.</strong>]]></description>
			<content:encoded><![CDATA[<div class="importantNotes">
<h3>Note:</h3>
<p>The stylesheet for the polyfill was not included correctly when this post was first published, and as a result, the examples below were not showing up correctly on IE7-8 and Safari 5.1+.  The problem has been corrected.</p>
</div>
<p><div id="attachment_4224" class="wp-caption alignleft" style="width: 260px"><img src="http://www.useragentman.com/blog/wp-content/uploads/2012/01/intro.png" alt="" title="intro" width="250" height="180" class="size-full wp-image-4224" /><p class="wp-caption-text">Screenshots of HTML5 progress bars with different styles applied.  Details given below.</p></div> As a web application developer,<strong> progress bars are great when you want to show the user that some action is happening,</strong> especially when it can take a long time.  They can be <strong>animated</strong> (like the one in Gmail does when it shows the user how long it is going to take for it to load and initialize), <strong>or static</strong> (like some shopping cart applications have to show the user how many pages it will take to check out an order).  I used to <a href="http://css-tricks.com/css3-progress-bars/">create progress bars using <code>&lt;div&gt;</code> tags, CSS and a litle bit of math</a>, but now I like to do it the HTML5 way using the <code>&lt;progress&gt;</code> tag.  This article will discuss <strong>how this tag is rendered by default</strong> in all operating systems and browsers and how to <strong>style the <code>progress</code> tag with CSS</strong>, even in browsers that don&#8217;t officially support the it.  It will also discuss some interesting <strong>limitations of all the browser implementations</strong> amd show some <strong>interesting examples using advanced CSS3 techniques.</strong></p>
<h2>The HTML: Simple</h2>
<p>The HTML for a Progress bar is dead simple:</p>
<blockquote class="code">
<pre>
&lt;progress max="100" value="60"&gt;
  &lt;strong&gt;Progress: 60% done.&lt;/strong&gt;
&lt;/progress&gt;
</pre>
</blockquote>
<div class="example">
<progress max="100" value="60"><strong>Progress: 60% done.</strong></progress>
</div>
<p><strong>Note that the HTML inside the <code>&lt;progress&gt;</code> tag is the fallback for browsers that do not support it.</strong>  That, unfortunately, includes all versions of IE and Safari so far, as well older versions of Firefox (5.x and lower) and Opera (10.x and lower).  Although the fallback is acceptable, we can go a step further and use <strong><a href="http://lea.verou.me/">Lea Verou&#8217;s</a> excellent <a href="http://lea.verou.me/2011/07/a-polyfill-for-html5-progress-element-the-obsessive-perfectionist-way/"><code>&lt;progress&gt;</code> tag polyfill</a></strong>, which adds pretty much full-support for all of these browsers <strong>except for Safari 5 and lower</strong> (so you should <em><strong>always put in the fallback HTML just to be on the safe side</strong></em>).  Let&#8217;s take a look at these screenshots to see what how <code>&lt;progress&gt;</code> looks across the browserverse:</p>
<table class="dataTable">
<thead>
<tr>
<th></th>
<th>Windows 7</th>
<th>Windows XP</th>
<th>Mac OS X</th>
<th>Ubuntu Linux</th>
</thead>
<tbody>
<tr>
<th>Firefox</th>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/defaultFirefoxWin.png" alt=""  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/defaultFirefoxWinXP.png" alt=""  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/defaultFirefoxMac.png" alt=""  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/defaultFirefoxLinux.png" alt=""  /></td>
</tr>
<tr>
<th>Chrome</th>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/defaultChromeWin.png" alt=""  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/defaultChromeWinXP.png" alt=""  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/defaultChromeMac.png" alt=""  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/defaultChromeLinux.png" alt=""  /></td>
</tr>
<tr>
<th>IE7+ (polyfill)</th>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/defaultSafariWin_poly.png" alt=""  /></td>
<td colspan="3" class="na">N/A</td>
</tr>
<tr>
<th>Safari 5.1+ (polyfill)</th>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/defaultSafariWin_poly.png" alt=""  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/defaultSafariWin_poly.png" alt=""  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/defaultSafariWin_poly.png" alt=""  /></td>
<td class="na">N/A</td>
</tr>
<tr>
<th>Opera</th>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/defaultOperaWin.png" alt=""  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/defaultOperaWin.png" alt=""  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/defaultOperaMac.png" alt=""  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/defaultOperaLinux.png" alt=""  /></td>
</tr>
</tbody>
</table>
<p>Note that:</p>
<ul>
<li>Firefox and Chrome will render the progress bar the same way that the host operating system would &#8230; except for Chrome for Linux, which uses it&#8217;s own custom style (thanks to <a href="http://blog.oldworld.fr/">Mounir Lamouri</a> for correcting me on this exception).</li>
<li>The color of the Opera progress value is always green (more on this later).</li>
<li>The browsers that use the polyfill all render the progress bar with a nice bluish gradient effect</li>
</ul>
<p>A progress bar <strong>can also have an <em>&#8220;indeterminate&#8221;</em> state</strong>, which happens when there is <strong>no value attribute</strong>. </p>
<blockquote class="code">
<pre>
&lt;progress max="100"&gt;
  &lt;strong&gt;Progress: 60% done.&lt;/strong&gt;
&lt;/progress&gt;
</pre>
</blockquote>
<div class="example">
<progress max="100" ><strong>Progress: 60% done.</strong></progress>
</div>
<p>This effect is used to show that the state of progress is currently unknown (e.g. how long it will take for a web server to initiate the download of a file if is generating it on the fly).  How this looks varies from browser to browser as well.</p>
<table class="dataTable">
<thead>
<tr>
<th></th>
<th>Windows 7</th>
<th>Windows XP</th>
<th>Mac OS X</th>
<th>Ubuntu Linux</th>
</thead>
<tbody>
<tr>
<th>Firefox</th>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/indeterFirefoxWin.png" alt=""  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/indeterFirefoxWinXP.png" alt=""  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/indeterFirefoxMac.png" alt=""  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/indeterFirefoxLinux.png" alt=""  /></td>
</tr>
<tr>
<th>Chrome</th>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/indeterChromeWin.png" alt=""  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/indeterChromeWinXP.png" alt=""  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/indeterChromeMac.png" alt=""  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/indeterChromeLinux.png" alt=""  /></td>
</tr>
<tr>
<th>IE7+ (polyfill)</th>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/indeterSafariWin_poly.png" alt=""  /></td>
<td colspan="3" class="na">N/A</td>
</tr>
<tr>
<th>Safari 5.1+ (polyfill)</th>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/indeterSafariWin_poly.png" alt=""  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/indeterSafariWin_poly.png" alt=""  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/indeterSafariWin_poly.png" alt=""  /></td>
<td class="na">N/A</td>
</tr>
<tr>
<th>Opera</th>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/indeterOperaWin.png" alt=""  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/indeterOperaWin.png" alt=""  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/indeterOperaMac.png" alt=""  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/indeterOperaLinux.png" alt=""  /></td>
</tr>
</tbody>
</table>
<p>Note that:</p>
<ul>
<li>Opera is the only browser that doesn&#8217;t distinguish between a progress bar with an indeterminate state and one with a value of zero.</li>
<li>All of the other browsers (including the ones that use the polyfill) animate the indeterminate states.  (I have opted to not show all the animations here to avoid readers getting seizures &#8230; I hear that would be a bad thing).</li>
</ul>
<h2>But I Want To Style Them My Way!</h2>
<p>If you are particular in how you want your <code>&lt;progress&gt;</code> tags to look, the good news is that <strong>you can pretty much style them any way you want</strong>.  You must, however, <strong>be aware about the browser quirks</strong> that can trip you up &#8230; and it isn&#8217;t all IE&#8217;s fault this time!  Follow this three-to-four-step process, and you&#8217;ll be styling progress bars in your sleep in no time:</p>
<h3>Step 1: Turn off default styling</h3>
<p>The first step is to turn off the default styling in all browsers:</p>
<blockquote class="code">
<pre>
progress,          /* All HTML5 progress enabled browsers */
progress[role]     /* polyfill */
{

	/* Turns off styling - not usually needed, but good to know. */
	appearance: none;
	-moz-appearance: none;
	-webkit-appearance: none;

	/* gets rid of default border in Firefox and Opera. */
	border: none;

	/* Needs to be in here for Safari polyfill so background images work as expected. */
	background-size: auto;

	/* Dimensions */
	width: 400px;
	height: 60px;

}

/* Polyfill */
progress[role]:after {
	background-image: none; /* removes default background from polyfill */
}

/* Ensure fallback text doesn't appear in polyfill */
progress[role] strong {
	display: none;
}
</pre>
</blockquote>
<div class="example">
<progress class="example1 a" min="0" max="100" value="50">
<strong>Progress: 60% done.</strong>
</progress>
</div>
<p>Simple stuff: remove the border and add a specific width and height.  I added the second rule to remove the background image inserted by the polyfill&#8217;s stylesheet, but if you wanted, you can  modify the polyfill&#8217;s stylesheet directly (or leave it out completely if you elect not to use the polyfill).   The final rule is to ensure the polyfill doesn&#8217;t display the fallback content &mdash; it assumes that is always wrapped in a <code>&lt;strong&gt;</code> tag, so this may be something you should keep in mind when setting the default content (if you don&#8217;t like using a <code>&lt;strong&gt;</code> tag as a wrapper for your fallback content, use whatever tag you like).</p>
<p>Note that the <code>appearance</code> property (and its vendor-specific brethren) are there to turn off the default operating-system styling on the progress bar &mdash; it doesn&#8217;t seem like it is really necessary, but I put it here for reference in case it becomes mandatory in the future.</p>
<h3>Step 2: The Progress Bar Background.</h3>
<p>Now let&#8217;s change the background color of the progress bar to a light red.  </p>
<blockquote class="code">
<pre>
progress,                          /* Firefox  */
progress[role][aria-valuenow] {    /* Polyfill */
   background: #ffeeee !important; /* !important is needed by the polyfill */
}

/* Chrome */
progress::-webkit-progress-bar {
    background: #ffeeee;
}
</pre>
</blockquote>
<div class="example">
<progress class="example1 a b" min="0" max="100" value="50"></progress>
</div>
<p>Notice that with Firefox and the polyfilled browsers, all you need to do is change the background of just the <code>progress</code> tag itself, while in Chrome (and I assume future versions of Safari) it is necessary to use the <code>-webkit-progress-bar</code> pseudo-element. Note that even though the code inside these rules are the same,<strong> you cannot put all of these selectors in one rule</strong>: doing so breaks Firefox and Opera (so much for degrading gracefully).</p>
<h3>Step 3: The Progress Bar Value</h3>
<p>Now let&#8217;s change the color of progress bar value to black.  The CSS is a <em>wee bit longer than it really should be</em>:</p>
<blockquote class="code">
<pre>
/* Firefox */
progress::-moz-progress-bar {
    background: black;
}

/* Chrome */
progress::-webkit-progress-value {
    background: black;
}

/* Polyfill */
progress[aria-valuenow]:before  {
    background: black;
}
</pre>
</blockquote>
<div class="example">
<progress class="example1 a b c" min="0" max="100" value="50"></progress>
</div>
<p>Yes, three rules to rule them all!  Again, putting them all together in one selector breaks every browser on the planet (including the polyfilled ones), so we have to write three separate rules with the same CSS properties in them! &lt;sarcasm&gt;Yaaayyy!!!!&lt;/sarcasm&gt;</p>
<p><strong>Note that there is no way that I know of to style the progress bar value in Opera 11.52 and lower.</strong>  It just stays the same green no matter what you do. :-( If anyone is reading this and knows otherwise, I would be indebted to you to let me know how.</p>
<h3>Step 4: The Indeterminate Value</h3>
<p>This part is optional, and I would only put these rules in if I know I&#8217;ll need a style for the indeterminate value (not all applications need it):</p>
<blockquote class="code">
<pre>
/* Firefox */
progress:not([value])::-moz-progress-bar {
  background-image:  url(../images/indeter.gif);
}

/* Chrome */
progress:not([value])::-webkit-progress-bar {
  background-image:  url(../images/indeter.gif);
}

/* Polyfill - IE */
progress[role]{
	background-image: url(../images/indeter.gif) !important;
}

/* Polyfill - Safari */
progress:not([value])  {
	background-image: url(../images/indeter.gif) !important;
	background-size: auto;  /* Needs to be in here for Safari */
}
</pre>
</blockquote>
<div class="example">
<progress class="example1 a b c d" min="0" max="100"></progress>
</div>
<p>It even works in Opera! Note that the <code>background-size</code> must be set to <code>auto</code> in order to override the default style in the polyfill.  :-)</p>
<p><a href="http://www.useragentman.com/examples/progress/" class="exampleLink">See the above CSS in action in a &#8220;clean room&#8221; page</a></p>
<h2>That&#8217;s Too Basic! I Want Fancy-Pants&trade; Progress Bars</h2>
<p>So, now that you know the basics, let&#8217;s take a look at some more complicated and interesting progress bars:</p>
<h3>Two Image Effect</h3>
<p>This progress bar uses two versions of the same image (one grey-scale, one color) to differentiate between the progress bar background and value: </p>
<div class="example">
<progress class="example2" min="0" max="100" value="60"></progress>
</div>
<p><a href="http://www.useragentman.com/examples/progress/uam.html" class="exampleLink">See the above example in action in a &#8220;clean room&#8221; page</a></p>
<h3>Gradients</h3>
<p>Note that  not only can you use <code>background-color</code>s and <code>-image</code>s, but also use the variety of gradients that are available for developers today in supported browsers (this does <strong>not</strong> include IE9 and lower).  To prove this, I took Chris Croyer beautiful <code>&lt;div&gt;</code> style progress bars from his <a href="http://css-tricks.com/css3-progress-bars/">blog post on CSS3 based progress bars</a> and HTML5-ified&trade; them here:</p>
<div class="example">
<progress class="example3" min="0" max="100" value="60"></progress>
</div>
<div class="example">
<progress class="example4" min="0" max="100" value="60"></progress>
</div>
<p>Unfortunately, due to CSS gradients being implemented by the browser vendors using vendor-specific prefixes, the CSS tends to be a wee long.  Here is the CSS of the first example (scroll the code to see the whole lot of it):</p>
<blockquote class="code shortened">
<pre>
/*
 * Gradient Shadow
 */

/* All HTML5 progress enabled browsers */
progress.example3 {

	/* Turns off styling - not usually needed, but good to know. */
	appearance: none;
	-moz-appearance: none;
	-webkit-appearance: none;
	/* gets rid of default border in Firefox and Opera. */
	border: solid #cccccc 5px;
	border-radius: 10px;
	/* Dimensions */
	width: 238px;
	height: 45px;
}

/* Polyfill */
progress.example3[role]:after {
	background-image: none; /* removes default background from polyfill */
}

/*
 * Background of the progress bar background
 */

/* Firefox and Polyfill */
progress.example3 {
	background: #cccccc !important; /* !important only needed in polyfill */
}

/* Chrome */
progress.example3::-webkit-progress-bar {
	background: #cccccc;
}

/*
 * Background of the progress bar value
 */

/* Firefox */
progress.example3::-moz-progress-bar {
	border-radius: 5px;
	background-image: -moz-linear-gradient(
		center bottom,
		rgb(43,194,83) 37%,
		rgb(84,240,84) 69%
	);
}

/* Chrome */
progress.example3::-webkit-progress-value {
	border-radius: 5px;
	background-image: -webkit-gradient(
		linear,
		left bottom,
		left top,
		color-stop(0, rgb(43,194,83)),
		color-stop(1, rgb(84,240,84))
	);
	background-image: -webkit-linear-gradient(
		center bottom,
		rgb(43,194,83) 37%,
		rgb(84,240,84) 69%
	);
}

/* Polyfill */
progress.example3[aria-valuenow]:before {
	border-radius: 5px;
	background-image: -moz-linear-gradient(
		center bottom,
		rgb(43,194,83) 37%,
		rgb(84,240,84) 69%
	);
	background-image: -ms-linear-gradient(
		center bottom,
		rgb(43,194,83) 37%,
		rgb(84,240,84) 69%
	);
	background-image: -o-linear-gradient(
		center bottom,
		rgb(43,194,83) 37%,
		rgb(84,240,84) 69%
	);

}
</pre>
</blockquote>
<p>Note that I did not use the <a href="http://msdn.microsoft.com/en-us/library/ms532997%28v=vs.85%29.aspx"><code>Gradient</code> filter</a> to polyfill CSS3 gradients in IE6-9.  This is because Visual Filters don&#8217;t work in CSS3 pseudo-elements like <code>:before</code> or <code>:after</code>.  Oh well.</p>
<p><a href="http://www.useragentman.com/examples/progress/striping.html" class="exampleLink">See the above CSS in action in a “clean room” page</a></p>
<h3>Monkeys!</h3>
<p>What blog post about HTML5 progress tags would be complete without monkeys?  These simians appear in all browser except for IE8 and lower (as explained below).  </p>

<div class="example">
<progress class="monkey" min="0" max="100" value="60"></progress><div class="after"></div>
</div>
<p>Apologies to the great <a href="http://banksy.co.uk/">Banksy</a> &mdash; it&#8217;s not <a href="http://www.guyhepner.com/index.php?url=images/get/509x397/3087/banksy-paintings-laugh-now-but-one-day-we-ll-be-in-charge.jpg">his monkey</a> but one grabbed from <a href="http://www.animatedgif.net/clockscounters/clockscounters3.shtml">this Animated GIF site</a> and converted into a <a href="http://www.alistapart.com/articles/sprites">CSS sprite</a> using <a href="http://blog.somepixels.net/">André Gil&#8217;s</a> super-cool <a href="http://labs.andregil.net/Gif2TileSet/Gif2TileSet.html">Gif2TileSet tool</a>.  I took this sprite and animated the monkey using blitting whenever the progress bar changes values (thanks to my friend and colleague <a href="http://noel.tibbles.ca/">Noel Tibbles</a> for turning me on to this technique).</p>
<p>Note the HTML has an extra <code>&lt;div&gt;</code> tag so the monkey has a place to live:</p>
<blockquote class="code">
<pre>
&lt;progress class="monkey" min="0" max="100" value="60"&gt;&lt;/progress&gt;
&lt;div class="after"&gt;&lt;/div&gt;
</pre>
</blockquote>
<p><strong>I wish that I could have used <code>:after</code> (or <code>::after</code>) rules</strong> instead, but these pseudo-elements <strong>don&#8217;t work with the <code>progress</code> tags in <em>any</em> browser that doesn&#8217;t use the polyfill</strong>.  And no, <code>:before</code> doesn&#8217;t work either.  I have no idea why it doesn&#8217;t work, but it&#8217;s a shame &mdash; using them would be perfect to get rid of the extra markup.</p>
<p>The CSS that makes the monkey animate when the progress bar changes values is here:</p>
<blockquote class="code">
<pre>
progress.monkey[value="0"] +  .after{
	background: url('/blog/wp-content/uploads/2011/12/monkeyBlit.gif');
} 

progress.monkey[value^="1"] +  .after {
	background: url('/blog/wp-content/uploads/2011/12/monkeyBlit.gif') 0  -77px ;
}

progress.monkey[value^="2"] +  .after {
	background: url('/blog/wp-content/uploads/2011/12/monkeyBlit.gif') 0  -154px ;
}

progress.monkey[value^="3"] +  .after,
progress.monkey[value="100"] +  .after  {
	background: url('/blog/wp-content/uploads/2011/12/monkeyBlit.gif') 0  -231px !important ;
}

progress.monkey[value^="4"] +  .after {
	background: url('/blog/wp-content/uploads/2011/12/monkeyBlit.gif') 0  -308px ;
}

progress.monkey[value^="5"] +  .after {
	background: url('/blog/wp-content/uploads/2011/12/monkeyBlit.gif') 0  -385px ;
}

progress.monkey[value^="6"] +  .after {
	background: url('/blog/wp-content/uploads/2011/12/monkeyBlit.gif') 0  -462px ;
}

progress.monkey[value^="7"] +  .after {
	background: url('/blog/wp-content/uploads/2011/12/monkeyBlit.gif') 0  -539px ;
}

progress.monkey[value^="8"] +  .after {
	background: url('/blog/wp-content/uploads/2011/12/monkeyBlit.gif') 0  -616px ;
}

progress.monkey[value^="9"] +  .after {
	background: url('/blog/wp-content/uploads/2011/12/monkeyBlit.gif') 0  -693px ;
}
</pre>
</blockquote>
<p>Each of these rules are applied when the first digit changes in the progress bar, which is done using the ^= attribute rules. This works because the progress bar goes from 0 &#8211; 100 and the progress bar increments by 10.  They monkeys don&#8217;t appear in IE8 and under because of it&#8217;s lack of support of the ^= attribute selector (but it works well in IE9).</p>
<p>Note that <strong>this would be much easier if CSS allowed us to combine the CSS3 <code>calc()</code> and <code>attr()</code> attributes together</strong> like <a href="http://lea.verou.me/2010/09/on-attr-and-calc/">Lea Verou dreams about in one of her blog posts</a>:</p>
<blockquote class="code">
<pre>
/*
 * Don't try this - it doesn't work in any browser, but it would be nice if it did.
 */

progress.monkey::after {
   background-image: url('/blog/wp-content/uploads/2011/12/monkeyBlit.gif');
   background-position-x: 0;
   background-position-y: calc(-77 * attr(value), 'px');
}
</pre>
</blockquote>
<p>Hopefully this will come to pass in the future.</p>
<p><a href="http://www.useragentman.com/examples/progress/blit.html" class="exampleLink">See the above CSS in action in a “clean room” page</a></p>
<h3>Speedometer</h3>
<p>My last example is radically different than the others.  How about we apply the speedometer metephor to the progress bar with some fancy-pants CSS3?   This example in all browsers except IE8 and lower (due to lack of support for native CSS3 <code>transform</code>) </p>

<div class="example speedometer">
<div id="progressContainer">
  <progress id="rot" class="example_r" min="0" max="100" value="60"></progress>
  <div data-arrow-for="rot" class="arrow"><img src="/blog/wp-content/uploads/2012/01/hand.png" /></div>
</div>
</div>
<p>The CSS is similar to the monkey example in that I add an extra <code>&lt;div&gt;</code> after the progress tag, except that it has an image of a pointer inside of it.</p>
<blockquote class="code">
<pre>
&lt;div id="progressContainer"&gt;
  &lt;progress id="rot" class="example_r" min="0" max="100" value="60"&gt;&lt;/progress&gt;
  &lt;div data-arrow-for="rot" class="arrow"&gt;&lt;img src="/blog/wp-content/uploads/2012/01/hand.png" /&gt;&lt;/div&gt;
&lt;/div&gt;
</pre>
</blockquote>
<p>I wrapped both these tags inside a relatively positioned container <code>&lt;div&gt;</code>.  This is so I could absolutely position both the progress bar and the arrow in order for them to line up properly.  I make the progress bar into a semi-circle by using <code>border-radius</code> and part of a <a href="http://www.flickr.com/photos/listener42/4991330345/">photo from Flickr user &#8216;listener42&#8242;</a> &#8230;</p>
<blockquote class="code">
<pre>
progress.example_r {

	/* gets rid of default border in Firefox and Opera. */
	border: solid 1px black;
	display: inline-block;

	/* Produces the semi-circle */
	<span class="hilite">border-radius: 238px 238px 0 0;</span>

	/* Dimensions */
	width: 238px;
	height: 126px;
	padding: 0;
}
</pre>
</blockquote>
<p>&#8230; and make the arrow rotate as the progress bar increments by using CSS transforms: </p>
<blockquote class="code shortened">
<pre>
progress.example_r[value="0"] + .arrow {
	-moz-transform: rotate(270deg);
	-webkit-transform: rotate(270deg);
	-o-transform: rotate(270deg);
	-ms-transform: rotate(270deg);
}

progress.example_r[value^="1"]:not([value="1"]):not([value="100"]) + .arrow {
	-moz-transform: rotate(288deg);
	-webkit-transform: rotate(288deg);
	-o-transform: rotate(288deg);
	-ms-transform: rotate(288deg);
}

progress.example_r[value^="2"]:not([value="2"]) + .arrow {
	-moz-transform: rotate(306deg);
	-webkit-transform: rotate(306deg);
	-o-transform: rotate(306deg);
	-ms-transform: rotate(306deg);
}

progress.example_r[value^="3"]:not([value="3"]) + .arrow {
	-moz-transform: rotate(324deg);
	-webkit-transform: rotate(324deg);
	-o-transform: rotate(324deg);
	-ms-transform: rotate(324deg);
}

progress.example_r[value^="4"]:not([value="4"]) + .arrow {
	-moz-transform: rotate(342deg);
	-webkit-transform: rotate(342deg);
	-o-transform: rotate(342deg);
	-ms-transform: rotate(342deg);
}

progress.example_r[value^="5"]:not([value="5"]) + .arrow {
	-moz-transform: rotate(360deg);
	-webkit-transform: rotate(360deg);
	-o-transform: rotate(360deg);
	-ms-transform: rotate(360deg);
}

progress.example_r[value^="6"]:not([value="6"]) + .arrow {
	-moz-transform: rotate(378deg);
	-webkit-transform: rotate(378deg);
	-o-transform: rotate(378deg);
	-ms-transform: rotate(378deg);
}

progress.example_r[value^="7"]:not([value="7"]) + .arrow {
	-moz-transform: rotate(396deg);
	-webkit-transform: rotate(396deg);
	-o-transform: rotate(396deg);
	-ms-transform: rotate(396deg);
}

progress.example_r[value^="8"]:not([value="8"]) + .arrow {
	-moz-transform: rotate(414deg);
	-webkit-transform: rotate(414deg);
	-o-transform: rotate(414deg);
	-ms-transform: rotate(414deg);
}

progress.example_r[value^="9"]:not([value="9"]) + .arrow {
	-moz-transform: rotate(432deg);
	-webkit-transform: rotate(432deg);
	-o-transform: rotate(432deg);
	-ms-transform: rotate(432deg);
}

progress.example_r[value="100"] + .arrow {
	-moz-transform: rotate(450deg);
	-webkit-transform: rotate(450deg);
	-o-transform: rotate(450deg);
	-ms-transform: rotate(450deg);
}
</pre>
</blockquote>
<p>Again, the CSS would be much smaller in size if I could use <code>calc()</code> and <code>attr()</code> together, but again, oh well.   Also note that this example doesn&#8217;t work in Opera very well because we cannot turn of the green in the progress bar value.  :-(</p>
<p><a href="http://www.useragentman.com/examples/progress/rotate.html" class="exampleLink">See the above CSS in action in a “clean room” page</a></p>
<h2>Summary of Gotchas</h2>
<p>As mentioned before, there are a few annoyances I have found with they way the browsers have implemented HTML5 progress bars:</p>
<ol>
<li>You cannot use <code>:before</code>/<code>::before</code> or <code>:after</code>/<code>::after</code> pseudo-elements on the <code>progress</code> element.  Why this is not allowed is unclear to me, and I hope this is allowed in the future.</li>
<li>Safari 5.0 and lower cannot use the polyfill, so you should always use the fallback HTML inside the <code>&lt;progress&gt;</code> tag.</li>
<li>It seems like it is impossible to change Opera&#8217;s progress bar style to anything besides green.</li>
<li>There is a <strong>small bug in the polyfill</strong> when applying borders to the progress bar.  I have <a href="https://github.com/zoltan-dulac/HTML5-Progress-polyfill">a fix</a> that has been <a href="https://github.com/LeaVerou/HTML5-Progress-polyfill/pull/6">submitted as a pull request</a> and I assume being reviewed, but in the meantime, you can <a href="https://github.com/zoltan-dulac/HTML5-Progress-polyfill">get my forked version of the polyfill (with the bug fix) on GitHub</a>.</li>
</ol>
<h2>Help Me Keep This Page Up-To-Date!</h2>
<p>If you find out more information about the HTML5 <code>progress</code> tag, I&#8217;d love to hear from you!  Please let me know in the comments below.  I will add relevant information to the above article and credit you fully. :-)</p>
<p><script src="/shared/js/lea.verou.me/progressPolyfill/progress-polyfill.js"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://www.useragentman.com/blog/2012/01/03/cross-browser-html5-progress-bars-in-depth/feed/</wfw:commentRss>
		<slash:comments>31</slash:comments>
		</item>
		<item>
		<title>Cross Browser CSS cursor Images In Depth</title>
		<link>http://www.useragentman.com/blog/2011/12/21/cross-browser-css-cursor-images-in-depth/</link>
		<comments>http://www.useragentman.com/blog/2011/12/21/cross-browser-css-cursor-images-in-depth/#comments</comments>
		<pubDate>Wed, 21 Dec 2011 05:34:31 +0000</pubDate>
		<dc:creator>zoltan</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[cursor]]></category>
		<category><![CDATA[Images]]></category>
		<category><![CDATA[bugs]]></category>
		<category><![CDATA[custom cursors]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[Internet Explorer]]></category>

		<guid isPermaLink="false">http://www.useragentman.com/blog/?p=3893</guid>
		<description><![CDATA[<img src="/blog/wp-content/uploads/2011/12/intro.png" /> When used properly, custom CSS cursors can add a little bit of polish to your web sites and applications.  However, doing this in a cross browser way can be a little confusing unless you know all the gotchas, and this article will go into depth about them.   We will also explore issues such as when to use custom cursors, performance, what makes good cursor design, cursor file formats, and cursor size.]]></description>
			<content:encoded><![CDATA[
<!--
        This notice is required for the CanvasPainer widget below.

	Copyright (c) 2005, 2006 Rafael Robayna

	Permission is hereby granted, free of charge, to any person obtaining 
	a copy of this software and associated documentation files (the "Software"), 
	to deal in the Software without restriction, including without limitation 
	the rights to use, copy, modify, merge, publish, distribute, sublicense, 
	and/or sell copies of the Software, and to permit persons to whom the Software 
	is furnished to do so, subject to the following conditions:
	
	The above copyright notice and this permission notice shall be included
	in all copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
	OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
	DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
	OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
	OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

	Additional Contributions by: Morris Johns
-->


<div id="canvasPainter">
<div id="controls">
  <div class="ctr_btn" id="btn_1" >brush 2</div> 
  <div class="ctr_btn" id="btn_2" >line</div> 
  <div class="ctr_btn" id="btn_3" >rectangle</div> 
  <div class="ctr_btn" id="btn_4" >circle</div> 
  <div class="ctr_btn" id="btn_5" >clear</div> 
  <div class="ctr_btn" id="btn_9">new</div>
  <input class="color" id="color" value="#ff3333"></div>
<canvas id="canvas" width="200" height="200"></canvas>
<canvas id="canvasInterface" width="200" height="200"></canvas>
<p class="description"><small>Paint widget a remix of <a href="http://caimansys.com/painter/">CanvasPainter</a> © <a href="http://caimansys.com/">Rafael Robayna</a></small></p>
</div>
<p><strong>If you are using a desktop browser (except for Opera), play with the paint widget on the left.</strong>  When you select a tool and mouse over the white canvas, your mouse arrow will change to a custom cursor representing that tool (&agrave; la Photoshop or The GIMP).  This is not done by creating a DOM object and moving it to the mouse&#8217;s coordinates &mdash; we are using CSS to do it using the <code>cursor</code> property&#8217;s <code>url()</code> function. <strong> When used properly, custom CSS cursors can add a little bit of polish</strong> to your web sites and applications.  However, <strong>doing this in a cross browser way can be a little confusing</strong> unless you know all the gotchas, and this article will go into depth about them.   We will also explore issues such as <strong>when to use custom cursors, performance, what makes good cursor design, cursor file formats, and cursor size.</strong></p>
<h2>When Should I Use Custom Cursors Instead of the Built-in Ones?</h2>
<p>In general, CSS cursors (built-in or custom) should be used as a hint to the user as to what action the mouse can perform.  Let&#8217;s take a look at an example that doesn&#8217;t use custom cursors to illustrate a common use-case: drag and drop.  To give users a visual cue that an item is draggable, it is common practice to set an object&#8217;s CSS <code>cursor</code> property to <code>move</code>.  Mouse over the object draggable object below to see how this works. </p>
<div id="container">
<a href="#" id="toDrag" draggable="true">Drag me!</a>
</div>
<p>This is done with the following CSS:</p>
<blockquote class="code">
<pre>
a[draggable="true"] {
    cursor: move;
}
</pre>
</blockquote>
<p>The code above ensure that when a user &#8220;mouses over&#8221; a link with the HTML5 Drag and Drop &#8220;draggable&#8221; attribute, the <code>move</code> cursor appears.  It is a great way to help the user &#8220;figure out&#8221; how to use the user interface with minimal instruction.  A list of the built-in cross-browser cursor property values can be seen at <a href="http://www.quirksmode.org/css/cursor.html">CSS2 Cursor Style Page</a>.</p>
<p>The built-in cursors are great, but there are a few things to keep in mind.</p>
<ul>
<li><strong>Built-in cursors may look different depending on what browser/operating system is being used</strong>.  For example, some browsers (e.g. Firefox on Windows 7) will show the <code>move</code> cursor as a four-pointed arrow (<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/move_cursor.png" alt="[Four-Pointed Arrow Cursor]" class="inline" />) while others (e.g. Firefox on Mac OS X) will show a hand (<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/12/cursor-hand.png" alt="[Hand Cursor]" class="inline" />).  Using custom cursors, you can ensure all applications are using the same cursor for a more consistent expeience.  The example below is the same as the one above, except in all browsers, you will see the a hand icon.
<div id="container2">
<a href="#" id="toDrag2" draggable="true">Drag me!</a>
</div>
</li>
<li><strong>Not all browsers support all the same &#8220;built-in&#8221; cursors, and custom cursors allows you to add support for them.</strong> For example, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=258960">while Firefox on Windows doesn&#8217;t support <code>context-menu</code></a>, it seems to be the only browser that <a href="https://developer.mozilla.org/en/CSS/-moz-zoom-in">supports the zoom-in and -out cursors</a>.  Using custom cursors, you can implement all of these in all browsers.</li>
<li><strong>There may not be a built-in cursor for the use-case you need to solve.</strong>  A good example is in the paint widget at the beginning of this article &mdash; none of those cursors exist natively in any browser.</li>
<li><strong>It&#8217;s nice to design your own cursors</strong>, since sometimes the built-in ones may be a little basic looking (If you do this, please keep in mind that users are used to the built in ones, so your custom cursor shouldn&#8217;t look too much different than them if you want your application to be easy-to-use).
</ul>
<h2>The CSS of Custom Cursors</h2>
<p>Here is some sameple CSS code that will show custom cursor when the user mouses over a <code>div</code> with an id of <code>dragMe</code>.  If the browser doesn&#8217;t do custom cursors (like Opera), the cursor fallback to the built-in <code>move</code> cursor.</p>
<blockquote class="code">
<pre>
#dragMe {
    cursor: url('customMoveCursor.cur'), move;
}
</pre>
</blockquote>
<p><strong>As long as your cursor is in the same directory as your stylesheet, and as long as it is an uncompressed .CUR file, it&#8217;s as simple as that.</strong> Note that <a href="http://en.wikipedia.org/wiki/ICO_%28file_format%29">a .CUR file is just an .ICO file with extra information</a> that allows the developer to define the &#8220;host spot&#8221; position of the cursor (i.e. the part of the image which points to the position of the mouse).  Note that <strong>.CUR files support 32-bit color</strong> (16.7 million colors plus alpha channel transparency), so designers can create cursors that have semitransparent areas like shadows and anti-aliasing.   </p>
<p><strong>How does one create a .CUR file?</strong> Not too many graphic tools create .CUR files natively, but there are some easy solutions. If you are a Photoshop user, the <a href="http://www.telegraphics.com.au/svn/icoformat/trunk/dist/README.html">ICO (Windows Icon) file format plugin for Photoshop</a> is what you are looking for (I have not used it myself, but it apparently can save .CUR files directly.  Any comment on how well this works would be most welcome). If, like me, you use the GIMP, simply save the file as a .ICO file and convert it with <a href="http://www.janthor.com/sketches/index.php?/archives/10-A-Python-script-to-convert-ICO-to-CUR-files.html">this command line tool written in Python</a> by <a href="http://www.janthor.com">Jan Thor</a>. </p>
<h2>The Gotchas of Custom CSS Cursors</h2>
<p>There are a few things you need to remember when using CSS cursors</p>
<ol>
<li><strong>You must add a default &#8220;built-in&#8221; cursor after your custom cursor,</strong> or the custom cursor will not load in Firefox.  Think of it as Mozilla&#8217;s way of enforcing good web practices. :-)</li>
<li><strong>Internet Explorer interprets relative URLs as <em>relative to the HTML document</em></strong>, and not the CSS file like God (and the W3C) intended (Sometimes it seems that IE goes out of its way to make lives difficult for us developers).  This is true for all versions of IE, even IE9. To ensure cross-browser compatibility, you must either use an absolute URL:<br />
<blockquote class="code">
<pre>
#dragMe {
    cursor: url('/cursors/customMoveCursor.cur'), move;
}
</pre>
</blockquote>
<p>or a fallback url for IE:</p>
<blockquote class="code">
<pre>
/*
 * Assume this the HTML is in a directory above this CSS file
 */

#dragMe {
    cursor: url('../cursors/customMoveCursor.cur'),     /* Modern browsers    */
            url('cursors/customMoveCursor.cur'),        /* Internet Explorer  */
            move;                                       /* Older browsers     */
}
</pre>
</blockquote>
</li>
<li><strong>It is best that your .CUR files are 32&#215;32 pixels in size.</strong>  IE9 seems to resize cursors that are smaller than this to 32&#215;32, and IE8 and under cannot show cursors larger than this size.  While it is true that you can fit multiple file sizes inside a .CUR file, sticking with one 32&#215;32 image will ensure cross-browser consistency.</li>
<li>Although .CUR files can be saved in either a compressed or uncompressed format, <strong>not all browsers can read the compressed ones</strong>.  It is best to save your cursors in uncompressed format.  If you are using the GIMP to save to .ICO format first before you convert to .CUR, make sure that the .ICO is saved without compression.</li>
</ol>
<h2>Performance Issues</h2>
<p>As mentioned earlier, a lot of browsers (like Firefox or IE6) cannot show <em><strong>compressed</strong></em> .CUR files, but they can show .PNG files.  Since we would like to use a compressed version if possible, one could do this:</p>
<blockquote class="code">
<pre>
#dragMe {
    cursor: url('/cursors/customMoveCursor.png'),      /* Modern browsers    */
            url('/cursors/customMoveCursor.cur'),      /* Internet Explorer  */
            move;                                      /* Older browsers     */
}
</pre>
</blockquote>
<p><strong>This works well as long as the cursor hotspot is 0,0.</strong>  You can define a PNG hotspot using the CSS3 cursor syntax, but it breaks IE:</strong></p>
<blockquote class="code">
<pre>
#dragMe {
    cursor: url('customMoveCursor.png') 5 15, /* Modern browsers, hotspot is (5, 15)            */
            url('customMoveCursor.cur'),      /* IE chokes on the above line .. never gets here */
            move;                             /* Older browsers (IE never gets here either)     */
}
</pre>
</blockquote>
<p>In order to fix this issue, one must you conditional comments to make a separate IE from everyone else.  Let&#8217;s use a variation of <a href="http://paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/">Paul Irish&#8217;s Conditional Comment pattern</a> to do this.  Change the <code>html</code> tag to this:</p>
<blockquote class="code">
<pre>
&lt;!--[if (lte IE 9) ]&gt;&lt;html class="ie9 oldIE"&gt;    &lt;![endif]--&gt;
&lt;!--[if (gt IE 9)  ]&gt;&lt;html class="modern"&gt;       &lt;![endif]--&gt;
&lt;!--[!(IE)]&gt;&lt;!--&gt;    &lt;html class="notIE modern"&gt; &lt;!--&lt;![endif]--&gt;
</pre>
</blockquote>
<p>Now we can use this CSS to ensure .PNG loads in non-IE browsers:</p>
<blockquote class="code">
<pre>
html.modern #dragMe {
  cursor: url('customMoveCursor.png') 5 15, /* Modern browsers, hotspot is (5, 15).   */
          move;                             /* Older browsers                         */
}

html.oldIE #dragMe {
  cursor: url('customMoveCursor.cur'),      /* IE .CUR file loads                     */
          move;                             /* In case IE can't load the above.       */
}
</pre>
</blockquote>
<p>The extra bytes used to create the conditional comments may or may not be worth the trouble.  If you are using conditional comments (like I do all the time), it may be worth it.</p>
<h2>A Final Word On Testing in IE </h2>
<p>If you edit a .cur file on the web server and reload your page with that cursor in Internet Explorer, you may not see the edited change, since <strong>IE has kept the older cursor in cache and has a hard time letting go</strong>, kind of like <a href="http://www.youtube.com/watch?v=MBHOL1PcPR8">that person you dated in high-school</a>.  You will need to clear IE&#8217;s cache in order to see the new cursor.  This is quite annoying, and it is something you should keep in mind when troubleshooting in IE.</li>
</ul>
<h2>Further Reading</h2>
<ul>
<li><a href="http://beradrian.wordpress.com/2008/01/08/cross-browser-custom-css-cursors/">Cross-browser custom CSS cursors</a> by <a href="http://beradrian.wordpress.com/">Adrian Ber</a></li>
</ul>
<p><script type="text/javascript">
doOnLoad()
</script></p>
]]></content:encoded>
			<wfw:commentRss>http://www.useragentman.com/blog/2011/12/21/cross-browser-css-cursor-images-in-depth/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>How to Simulate CSS3 box-shadow in IE6-8 Without JavaScript.</title>
		<link>http://www.useragentman.com/blog/2011/08/24/how-to-simulate-css3-box-shadow-in-ie7-8-without-javascript/</link>
		<comments>http://www.useragentman.com/blog/2011/08/24/how-to-simulate-css3-box-shadow-in-ie7-8-without-javascript/#comments</comments>
		<pubDate>Wed, 24 Aug 2011 04:07:03 +0000</pubDate>
		<dc:creator>zoltan</dc:creator>
				<category><![CDATA[box-shadow]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[IE Visual Filters]]></category>
		<category><![CDATA[Chroma]]></category>
		<category><![CDATA[DropShadow]]></category>
		<category><![CDATA[Glow]]></category>
		<category><![CDATA[IE6]]></category>
		<category><![CDATA[IE7]]></category>
		<category><![CDATA[IE8]]></category>

		<guid isPermaLink="false">http://www.useragentman.com/blog/?p=3563</guid>
		<description><![CDATA[<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/intro.png" /> Using CSS3, developers can create <strong>simple</strong>, <strong>glowing</strong> and <strong>blurred</strong> box-shadows in all modern web browsers. <strong>But what about IE6-8?</strong>  This article will discuss how you can simulate them using a variety of Visual Filters to simulate them.  This article will cover a few CSS3 box-shadow effects, the equivalent Visual Filter recipes for IE 6-8, and the differences between them.]]></description>
			<content:encoded><![CDATA[<div id="intro">
<div class="box">
<span class="text">Simulating CSS3 <code>box-shadow</code> in IE6-8 <em>is</em> possible!</span>
</div>
<div class="description">The above is not an image.  It uses Allen R. Walden&#8217;s <a href="http://www.fontspace.com/allen-r-walden/neon-lights">Neon Lights</a> font and <a href="http://www.useragentman.com/blog/2010/03/09/cross-browser-css-transforms-even-in-ie/">cssSandpaper</a> to simulate CSS3 text-shadowing in IE. The box shadows are made with pure CSS in all browsers.</div>
</div>
<p><strong>CSS3 Box-Shadows are a great to quickly decorate the outside of block-level elements.</strong>  There are many CSS box-shadow recipes you can use to produce a variety of effects, including <strong>simple</strong>, <strong>glowing</strong> and <strong>blurred</strong> shadows. And, <a href="http://www.useragentman.com/blog/2011/06/29/full-css3-text-shadows-even-in-ie/">unlike CSS3 text-shadows</a>, <strong>box-shadows are natively supported by the latest version of IE.</strong>  However, if you want them to appear in <strong>older versions of IE</strong> (i.e. 6 through 8), you will want to <strong>learn how to use a variety of Visual Filters to simulate them.</strong>  This article will cover a few CSS3 box-shadow effects, the equivalent Visual Filter recipes for IE 6-8, and the differences between them. <strong>It will also cover the differences in the CSS3 implementations in all the modern browsers.</strong>  Box-shadows like the example on the left is possible in all commonly used browsers.</p>
<h2>First off, what is a <code>box-shadow</code>?</h2>
<p>A box-shadow is equivalent to a <a href="http://www.useragentman.com/blog/2011/06/29/full-css3-text-shadows-even-in-ie/">CSS3 <code>text-shadow</code></a> except it is applied to the box of the block-level element instead of the actual text.  Just like text-shadows, you can have one shadow:</p>
<blockquote class="code">
<pre>
#box {
  box-shadow: <em>&lt;x-offset&gt;</em> <em>&lt;y-offset&gt;</em> <em>&lt;blur-radius&gt;</em> <em>&lt;color&gt;</em>;
}
</pre>
</blockquote>
<p>&#8230; three shadows:</p>
<blockquote class="code">
<pre>
#box {
  box-shadow: <em>&lt;x-offset<sub>1</sub>&gt;</em> <em>&lt;y-offset<sub>1</sub>&gt;</em> <em>&lt;blur-radius<sub>1</sub>&gt;</em>, <em>&lt;color<sub>1</sub>&gt;</em>,
              <em>&lt;x-offset<sub>2</sub>&gt;</em> <em>&lt;y-offset<sub>2</sub>&gt;</em> <em>&lt;blur-radius<sub>2</sub>&gt;</em>, <em>&lt;color<sub>2</sub>&gt;</em>,
              <em>&lt;x-offset<sub>3</sub>&gt;</em> <em>&lt;y-offset<sub>3</sub>&gt;</em> <em>&lt;blur-radius<sub>3</sub>&gt;</em>, <em>&lt;color<sub>3</sub>&gt;</em>;
}
</pre>
</blockquote>
<p>&#8230; or as many as you want.  The <code>x-</code> and <code>y-offset</code>s measure the position of the horizontal and vertical shadow respectively, and the <code>blur-radius</code> measures the amount of blur in the shadow.  Let&#8217;s take a look at a simple example:</p>
<blockquote class="code">
<pre>
#box {
  <span class="hilite">box-shadow: 5px 5px 0px #ff0000;</span>
}
</pre>
</blockquote>
<table class="dataTable firstExample">
<thead>
<tr>
<th>Live HTML result</th>
<th>Firefox 4.0 Screenshot (for browsers like IE6-8<br />
that can&#8217;t see the Live result)</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div id="box0">
This is an example of a simple box-shadow without blurring
</div>
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/box11.png"   />
</td>
</tr>
</tbody>
</table>
<p>Note that although <code>box-shadow</code> is the official property name, one must use the vendor-specific prefixes in order to use it in Webkit browsers (i.e. Chrome and Safari) as well as older versions of Firefox:</p>
<blockquote class="code">
<pre>
#box {
  box-shadow: 5px 5px 0px #ff0000,          /* Firefox 4.0+, Opera, IE 9 */
  -webkit-box-shadow: 5px 5px 0px #ff0000,  /* Chrome and Safari         */
  -moz-box-shadow: 5px 5px 0px #ff0000;     /* Firefox 3.6               */
}
</pre>
</blockquote>
<p>Furthermore, there are two optional parameters, the <em>spread</em> (which allows you to determine the size of the shadow) as well as the <code>inset</code> parameter that can allow you to put the shadow inside the box instead of outside of the box.  I direct readers to <a href="https://developer.mozilla.org/En/CSS/Box-shadow">Mozilla.org&#8217;s great reference for <code>box-shadow</code></a> to read more on these properties, since they are not, as far as I can tell, reproducible in IE 8 or lower. </p>
<h2>What about IE?</h2>
<p><strong>IE9 has no problem showing <code>box-shadow</code></strong> <a href="http://stackoverflow.com/questions/5617455/issue-with-box-shadow-on-ie9">except when shadowing a box within a table-cell</a> (If the CSS of the table has its <code>border-collapse</code> property set to <code>collapse</code> then the <code>box-shadow</code> is not applied.  Hopefully this is fixed in a future release). </p>
<p>As mentioned earlier, <strong>IE6-8 requires Visual Filters to simulate CSS3 box-shadows without JavaScript.</strong>  In order to illustrate this, I will show several different types of box-shadows below and show both the CSS3 syntax and the equivalent Visual Filter CSS recipe.  Some of these recipes produce almost identical results, while others are rough equivalents.  Note that all these examples use a variation of <a href="http://paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/">Paul Irish’s Conditional CSS Pattern</a> in order to create the IE-only rules.  This involves replacing the <code>&lt;body&gt;</code> tag of the document with this HTML:</p>
<blockquote class="code">
<pre>
   &lt;!-- Extra white-space below is just to make it easier to read. :-) --&gt;

   &lt;!--[if lt IE 7 ]&gt;   &lt;body class="ie6"&gt;          &lt;![endif]--&gt;
   &lt;!--[if IE 7 ]&gt;      &lt;body class="ie7"&gt;          &lt;![endif]--&gt;
   &lt;!--[if IE 8 ]&gt;      &lt;body class="ie8"&gt;          &lt;![endif]--&gt;
   &lt;!--[if IE 9 ]&gt;      &lt;body class="ie9"&gt;          &lt;![endif]--&gt;
   &lt;!--[if (gt IE 9) ]&gt; &lt;body class="modern"&gt;       &lt;![endif]--&gt;
   &lt;!--[!(IE)]&gt;&lt;!--&gt;    &lt;body class="notIE modern"&gt; &lt;!--&lt;![endif]--&gt;
</pre>
</blockquote>
<p>We can then apply CSS specific to a version of IE.  For example:</p>
<blockquote class="code">
<pre>
body.ie7 #box {
   /* insert IE7 specific CSS here */
}
</pre>
</blockquote>
<p>(<strong>Note:</strong> Paul Irish&#8217;s technique officially has the conditional comments around the <code>html</code> tag, not the <code>body</code> tag.  You can use either for these techniques to work.  I just prefer using the latter.)</p>
<p><strong>All these Visual Filter recipes depend on the box <a href="http://www.satzansatz.de/cssd/onhavinglayout.html">&#8220;having layout&#8221;</a>.</strong>  If you have any difficulty with the Visual Filters activating, set <code>zoom: 1</code> or a static width inside the IE6-8 specific CSS to force the block to have layout.</p>
<h3>Type #1: Simple, Unblurred Shadows</h3>
<p>In order to <strong>simulate simple, unblurred <code>box-shadow</code>s in IE</strong>, we use <a href="http://msdn.microsoft.com/en-us/library/ms532985%28v=vs.85%29.aspx">IE&#8217;s <code>DropShadow</code> Visual filter</a>: </p>
<blockquote class="code">
<pre>
#box {
  /* CSS for all browsers. */
  border: solid 1px #808080;
  background: #ffffcc;
  margin: 10px;
  padding: 10px;

  /* CSS3 Box-shadow code: */
  box-shadow: <span class="hilite">5px</span> <span class="hilite2">5px</span> 0px <span class="hilite3">#ff0000</span>;
  -webkit-box-shadow: 5px 5px 0px #ff0000;
  -moz-box-shadow: 5px 5px 0px #ff0000;
}

/* IE6-8 Specific Code */
body.ie6 #box,
body.ie7 #box,
body.ie8 #box {
   zoom: 1;
   filter: progid:DXImageTransform.Microsoft.DropShadow(<span class="hilite">OffX=5</span>, <span class="hilite2">OffY=5</span>, <span class="hilite3">Color=#ff0000</span>);
}
</pre>
</blockquote>
<table class="dataTable">
<thead>
<tr>
<th>Live HTML result</th>
<th>Firefox Screenshot</th>
<th>IE7 Screenshot</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div id="box1">
This is an example of a simple box-shadow without blurring <strong>that also works in IE6-8.</strong>
</div>
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/box2Firefox.png"   />
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/box2IE.png"   />
</td>
</tr>
</tbody>
</table>
<p><strong>There are two exceptions to this solution.</strong> The first deals with when the block has a <strong>transparent background</strong>, and the other has to do with <strong>negative box-shadow offsets</strong>.</p>
<h3>Type #1a: Blocks With Transparent Backgrounds</h3>
<p>Let&#8217;s say you use the above CSS, but omit the <code>background</code> property:</p>
<blockquote class="code">
<pre>
#box {
  /* CSS for all browsers.  Note there is no background-color, so box will be transparent */
  border: solid 1px #808080;
  margin: 10px;
  padding: 10px;

  /* CSS3 Box-shadow code: */
  box-shadow: 5px 5px 0px #ff0000;
  -webkit-box-shadow: 5px 5px 0px #ff0000;
  -moz-box-shadow: 5px 5px 0px #ff0000;
}

/* IE6-8 Specific Code */
body.ie6 #box,
body.ie7 #box,
body.ie8 #box {
   zoom: 1;
   filter: progid:DXImageTransform.Microsoft.DropShadow(OffX=5, OffY=5, Color=#ff0000);
}
</pre>
</blockquote>
<p>Doing this will results in some unexpected results in IE6-8:</p>
<table class="dataTable">
<thead>
<tr>
<th>Live HTML result</th>
<th>Firefox Screenshot</th>
<th>IE7 Screenshot</th>
</tr>
</thead>
<tbody>
<tr>
<td class="withGrid">
<div id="box1a">
This is an example of a box with a transparent background and simple box-shadow without blurring. IE6-8 is having a hard time dealing with the transparent background.
</div>
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/box3Firefox.png"   />
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/box3IE.png"   />
</td>
</tr>
</tbody>
</table>
<p>The results in IE7 are as hideous and unreadable as the average <a href="http://yourethemannowdog.ytmnd.com/">YTMND</a> page! In order to fix this issue in elderly IE, one must <strong>add a background color in IE6-8 only and remove it with the <code>Chroma</code> filter</strong> (more information on this technique can be found on my previous blog post, <a href="http://www.useragentman.com/blog/2010/09/02/how-to-make-cleartype-font-face-fonts-and-css-visual-filters-play-nicely-together/">How to Make ClearType, @font-face Fonts and CSS Visual Filters Play Nicely Together</a>).</p>
<blockquote class="code">
<pre>
#box {
  border: solid 1px #808080;
  margin: 10px;
  padding: 10px;

  /* Box-shadow code: */
  box-shadow: 5px 5px 0px #ff0000;
  -webkit-box-shadow: 5px 5px 0px #ff0000;
  -moz-box-shadow: 5px 5px 0px #ff0000;
}

body.ie6 #box,
body.ie7 #box,
body.ie8 #box {
   background-color: #ffffff;
   zoom: 1;
   filter: progid:DXImageTransform.Microsoft.DropShadow(OffX=5, OffY=5, Color=#ff0000),
           <span class="hilite">progid:DXImageTransform.Microsoft.Chroma(Color='#ffffff');</span>
}
</pre>
</blockquote>
<p>As you can see below, adding this CSS logic produces much better results:</p>
<table class="dataTable">
<thead>
<tr>
<th>Live HTML result</th>
<th>Firefox Screenshot</th>
<th>IE7 Screenshot</th>
</tr>
</thead>
<tbody>
<tr>
<td class="withGrid">
<div id="box1a-after">
This is an example of a box<br />with a transparent background and simple box-shadow<br />without blurring, with a fix for IE6-8 to deal with the transparent color.
</div>
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/box4Firefox.png"   />
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/box4IE.png"   />
</td>
</tr>
</tbody>
</table>
<p><strong>Note:</strong> All the other types of box-shadow recipes that follow should also use this Chroma filter method when it is desirable to have a transparent background in the box itself.</p>
<h3 id="type1b" name="type1b">Type 1b: Negative Shadow Offsets</h3>
<p>If there are negative shadow offsets, you will see a small difference with the position of the box being shadowed:</p>
<blockquote class="code">
<pre>
#box {
  /* CSS for all browsers. */
  border: solid 1px #808080;
  background: #ffffcc;
  margin: 10px;
  padding: 10px;

  /* CSS3 Box-shadow code: */
  box-shadow: <span class="hilite">-10px</span> <span class="hilite2">-5px</span> 0px <span class="hilite3">#ff0000</span>;
  -webkit-box-shadow: -10px -5px 0px #ff0000;
  -moz-box-shadow: -10px -5px 0px #ff0000;
}

/* IE6-8 Specific Code */
body.ie6 #box,
body.ie7 #box,
body.ie8 #box {
   zoom: 1;
   filter: progid:DXImageTransform.Microsoft.DropShadow(<span class="hilite">OffX=-10</span>, <span class="hilite2">OffY=-5</span>, <span class="hilite3">Color=#ff0000</span>);
}
</pre>
</blockquote>
<table class="dataTable">
<thead>
<tr>
<th>Live HTML result</th>
<th>Firefox Screenshot</th>
<th>IE7 Screenshot</th>
</tr>
</thead>
<tbody>
<tr>
<td class="withGrid">
<div id="box1b">
This is an example of a simple box-shadow without blurring <strong>that also works in IE6-8.</strong>
</div>
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/box1bFirefox.png"   />
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/box1bIE.png"   />
</td>
</tr>
</tbody>
</table>
<p>You will note that the offsets in IE push the box down and to the right.  This is because <strong>IE&#8217;s Visual Filters believes that the box-shadow as part of the box itself,</strong> while <strong>CSS3 believes that it should be outside of the box.</strong>  As a result, negative box-shadows shift the box in IE6-8.  In order to compensate for this, one can use <code>margin-top</code> and <code>margin-bottom</code> to move the shadow to where CSS3 thinks it should be:</p>
<blockquote class="code">
<pre>
#box {
  /* CSS3 Box-shadow code: */
  box-shadow: <span class="hilite">-10px</span> <span class="hilite2">-5px</span> 0px <span class="hilite3">#ff0000</span>;
  -webkit-box-shadow: -10px -5px 0px #ff0000;
  -moz-box-shadow: -10px -5px 0px #ff0000;
}

/* IE6-8 Specific Code */
body.ie6 #box,
body.ie7 #box,
body.ie8 #box {
   zoom: 1;
   filter: progid:DXImageTransform.Microsoft.DropShadow(<span class="hilite">OffX=-10</span>, <span class="hilite2">OffY=-5</span>, <span class="hilite3">Color=#ff0000</span>);
   margin-top: <span class="hilite">10px</span>;
   margin-left: <span class="hilite2">5px</span>;
}
</pre>
</blockquote>
<table class="dataTable">
<thead>
<tr>
<th>Live HTML result</th>
<th>Firefox Screenshot</th>
<th>IE7 Screenshot</th>
</tr>
</thead>
<tbody>
<tr>
<td class="withGrid">
<div id="box1b-after">
This is an example of a simple box-shadow without blurring <strong>that also works in IE6-8.</strong>
</div>
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/box1bFirefox.png"   />
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/box1bIE-after.png"   />
</td>
</tr>
</tbody>
</table>
<p>Note that one could also make use relative positioning and use the CSS <code>top</code> and <code>left</code> properties to do the same thing in IE.  I leave it up to readers to decide which method would be more appropriate for the situation they find themselves in.</p>
<h3>Type #2: Glowing <code>box-shadow</code></h3>
<p>The second <code>box-shadow</code> I use a lot is what I call the &#8220;glowing box&#8221; effect.  This happens when a shadow with a large blur radius is put directly behind a box (i.e. the x- and y-offsets are set to 0, and the blur-radius is a non-zero number). It is possible to simulate this effect in IE using the <code>Shadow</code> filter. This filter must be applied four times (north, south, east and west of the box) in order to simulate the CSS3 effect.  Here is the CSS recipe:</p>
<blockquote class="code">
<pre>
#box {
   box-shadow: 0 0 5px #666666;
   -webkit-box-shadow: 0 0 5px #666666;
   -moz-box-shadow: 0 0 5px #666666;
}   

body.ie6 #box,
body.ie7 #box,
body.ie8 #box {
   zoom: 1;
   filter: progid:DXImageTransform.Microsoft.Shadow(Color=#cccccc, Strength=5, Direction=0),
         progid:DXImageTransform.Microsoft.Shadow(Color=#cccccc, Strength=5, Direction=90),
         progid:DXImageTransform.Microsoft.Shadow(Color=#cccccc, Strength=5, Direction=180),
         progid:DXImageTransform.Microsoft.Shadow(Color=#cccccc, Strength=5, Direction=270);
}
</pre>
</blockquote>
<p>&#8230; and here are the results as rendered in Firefox 4 and IE7:</p>
<table class="dataTable">
<thead>
<tr>
<th>Live HTML result</th>
<th>Firefox Screenshot</th>
<th>IE7 Screenshot</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div id="glowShadow1">
This is an example of a box that has short blurred shadows horizontally and vertically on all sides.
</div>
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/blurred2Firefox.png"   />
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/blurred2IE.png"   />
</td>
</tr>
</tbody>
</table>
<p>Note that the color in the Visual Filter syntax is lighter than the CSS3 one.  In order to get the equivalent IE color, I take a screenshot of the CSS3 box-shadow, open the image in The GIMP or Photoshop, and find the color that is just outside of the box.  This is the color I use in the IE syntax.  If you don&#8217;t want to go through all this trouble, you can also guess, which is what I do if I&#8217;m lazy.  Which is a lot of the time.</p>
<p>You can increase the blur radius/strength to produce larger glows as well:</p>
<blockquote class="code">
<pre>
#box {
    box-shadow: 0 0 15px #cccccc;
   -webkit-box-shadow: 0 0 15px #cccccc;
   -moz-box-shadow: 0 0 15px #cccccc;
}	

body.ie6 #box,
body.ie7 #box,
body.ie8 #box {
   zoom: 1;
   filter: progid:DXImageTransform.Microsoft.Shadow(Color=#eeeeee, Strength=15, Direction=0),
           progid:DXImageTransform.Microsoft.Shadow(Color=#eeeeee, Strength=15, Direction=90),
           progid:DXImageTransform.Microsoft.Shadow(Color=#eeeeee, Strength=15, Direction=180),
           progid:DXImageTransform.Microsoft.Shadow(Color=#eeeeee, Strength=15, Direction=270);
}
</pre>
</blockquote>
<table class="dataTable">
<thead>
<tr>
<th>Live HTML result</th>
<th>Firefox Screenshot</th>
<th>IE7 Screenshot</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div id="glowShadow2">
This is an example of a box that has longer blurred shadows horizontally and vertically on all sides.
</div>
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/blurred2aFirefox.png"   />
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/blurred2aIE.png"   />
</td>
</tr>
</tbody>
</table>
<p>You can also use this alternate recipe I have used one or twice if you want a darker color closer to the box, with it becoming dramatically lighter father away:</p>
<table class="dataTable">
<thead>
<tr>
<th>Live HTML result</th>
<th>Firefox Screenshot</th>
<th>IE7 Screenshot</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div id="glowShadow2a">
This is another example of a box that has longer blurred shadows horizontally and vertically on all sides.
</div>
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/blurred3Firefox.png"   />
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/blurred3IE.png"   />
</td>
</tr>
</tbody>
</table>
<p>Sure, the IE7 screenshot looks slightly different from the Firefox one, but <strong>let&#8217;s take a look at what all the modern browsers look with exactly the same CSS code:</strong></p>
<table class="dataTable blurredComparison">
<thead>
<tr>
<th>Opera</th>
<th>IE 9</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/blurred2aOpera.png"   />
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/blurred2aIE9.png"   />
</td>
</tr>
</tbody>
<thead>
<tr>
<th>Safari 5</th>
<th>Chrome 13</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/blurred2aSafari.png"   />
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/blurred2aChrome.png"   />
</td>
</tr>
</tbody>
</table>
<p>They are all slightly different.  It is almost impossible to be pixel perfect with blurred box-shadows unless you give different rules to the different browsers using vendor-specific prefixes.</p>
<p>Two important caveats about the Visual Filter rules:</p>
<ol>
<li>As mentioned before, the CSS for IE6-8 uses a lighter color for the shadow.  This is due to the way the <code>Shadow</code> filter behaves: it requires a lighter shade to simulate the same effect.</li>
<li><strong>Note that the Visual Filters examples are pushed down and to the right compared to the CSS3 example.</strong>  This is for the same reasons as stated in <a href="#type1b">Type 1b</a>, and a developer would again have to use margins or positioning to get the box in exactly the same place as it is in IE6-8:<br />
<blockquote class="code">
<pre>
#box {
   box-shadow: 0 0 5px #666666;
   -webkit-box-shadow: 0 0 5px #666666;
   -moz-box-shadow: 0 0 5px #666666;
}   

body.ie6 #box,
body.ie7 #box,
body.ie8 #box {
<span class="hilite">   margin-left: -5px;
   margin-top: -5px;</span>
   zoom: 1;
   filter: progid:DXImageTransform.Microsoft.Shadow(Color=#cccccc, Strength=5, Direction=0),
         progid:DXImageTransform.Microsoft.Shadow(Color=#cccccc, Strength=5, Direction=90),
         progid:DXImageTransform.Microsoft.Shadow(Color=#cccccc, Strength=5, Direction=180),
         progid:DXImageTransform.Microsoft.Shadow(Color=#cccccc, Strength=5, Direction=270);
}
</pre>
</blockquote>
</li>
</ol>
<h3>Type #3: Blurred <code>box-shadow</code></h3>
<p>Up until a few days ago, I thought this last type of text-shadow could not be simulated in IE using just CSS.  I then came across <a href="http://css-tricks.com/snippets/css/css-box-shadow/">an interesting recipe from CSS-Tricks</a> and <a href="http://www.der-schepp.de/blur-breaker-dropshadow/">this demo by Christian ”Schepp” Schaefer</a>. These CSS recipes came close, but was not able to control the color of the shadow itself (it assumed grey shadows only) or the exact location of the shadow.  I decided to take this work to the next level and add full control of the text-shadow, with some nice results:</p>
<table class="dataTable">
<thead>
<tr>
<th>Live HTML result</th>
<th>Firefox Screenshot</th>
<th>IE7 Screenshot</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div id="blurredShadow">
<div class="content">
                This is an example of a box with a blurred box-shadow.  It uses a special CSS recipe in order for it to work in Internet Explorer 6-8 involving a container HTML element and the Blur Visual Filter.
        </div>
</div>
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/blurred4Firefox.png"   />
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/blurred4IE.png"   />
</td>
</tr>
</tbody>
</table>
<p>Here is the HTML:</p>
<blockquote class="code">
<pre>
&lt;div id="box"&gt;
        &lt;div class="content"&gt;
                This is an example of a box with a blurred box-shadow.
                It uses a special CSS recipe in order for it to work in
                Internet Explorer 6-8 involving a container HTML element
                and the Blur Visual Filter.
        &lt;/div&gt;
&lt;/div&gt;
</pre>
</blockquote>
<p>and here is the CSS:</p>
<blockquote class="code">
<pre>
#box {
        /* CSS3 syntax */
	box-shadow: 5px 5px <span class="hilite2">5px</span> <span class="hilite">#cccccc</span>;
	-webkit-box-shadow: 5px 5px 5px #cccccc;
	-moz-box-shadow: 5px 5px 5px #cccccc;

        /* Place any other shared CSS properties here, except for those in the next rule */
        margin: 20px auto;
	text-align: center;
}

#box,
body.ie6 #box .content,
body.ie7 #box .content,
body.ie8 #box .content {
        /*
         * Any width, height, padding, border and background information goes here, so it is
         * shared between the CSS3 and legacy-IE solutions
         */
	width: 200px;
	padding: 10px;
	background: white;
	border: solid 1px black;
}

body.ie6 #box,
body.ie7 #box,
body.ie8 #box {
        /* This contains the color of the shadow in the CSS3 syntax */
	background: <span class="hilite">#cccccc</span>;

        /* This contains the blur-radius in the CSS3 syntax */
	zoom: 1;
	filter: progid:DXImageTransform.Microsoft.Blur(PixelRadius=<span class="hilite2">5</span>);

        /* You must remove the border in IE, since it will be replaced in the next rule */
	border: none;
}

body.ie6 #box .content,
body.ie7 #box .content,
body.ie8 #box .content {
	position: relative;

        /*
         * Margins must be added here to place the box above the shadow correctly.
         * The margin-left and margin-right properties should be -2 times the CSS3 x-offset.
         * The margin-top and margin-bottom properties should be -2 times the CSS3 y-offset.
        /
	margin-top: -10px;
	margin-left: -10px;
	margin-bottom: -10px;
        margin-right: -10px;
}
</pre>
</blockquote>
<p>Yes, <strong>the Legacy-IE Specific CSS as long and as painful like a meeting with your accountant,</strong> but it gets the job done.  </p>
<h2>Conclusion</h2>
<p>These Visual Filters CSS recipes can come handy when you want IE6-8 to have similar box-shadow effects that modern web browsers have.  There are probably other types of box-shadows that can be handled using them, and if you are interested I encourage those with time and patience to check out Microsoft&#8217;s reference to Visual Filters and start playing with them.  Although Visual Filter support will probably be taken out of IE10, developers won&#8217;t need worry since IE9 already has box-shadow support &mdash; these experiments should only be used to add box-shadow support in older versions of IE.</p>
<h2>Further Reading</h2>
<ul>
<li><a href="https://developer.mozilla.org/En/CSS/Box-shadow">Mozilla.org&#8217;s <code>box-shadow</code> reference page</a>
<li><a href="http://css-tricks.com/snippets/css/css-box-shadow/">CSS Box Shadow</a> from <a href="http://css-tricks.com">CSS Tricks</a></li>
<li><a href="http://www.der-schepp.de/blur-breaker-dropshadow/">CSS3 Box-Shadow for Legacy IEs</a> from <a href="http://twitter.com/#!/derSchepp">Christian ”Schepp” Schaefer</a></li>
<li><a href="http://robertnyman.com/2010/03/16/drop-shadow-with-css-for-all-web-browsers/">Drop shadow with CSS for all web browsers</a> by <a href="http://robertnyman.com">Robert Nyman</a>.  Note his article includes an alternate simpler solution for a blurred <code>box-shadow</code> that involves the <code>Shadow</code> filter:<br />
<table class="dataTable">
<thead>
<tr>
<th>Live HTML result</th>
<th>Firefox Screenshot</th>
<th>IE7 Screenshot</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div id="shadow4">
                This is an example of a box with a blurred box-shadow.  It uses the <code>Shadow</code> filter for Internet Explorer 6 through 8.
</div>
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/nyman1-Firefox.png"   />
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/nyman1-IE.png"   />
</td>
</tr>
</tbody>
</table>
<p> but does not as similar when dealing with large shadows:</p>
<table class="dataTable">
<thead>
<tr>
<th>Live HTML result</th>
<th>Firefox Screenshot</th>
<th>IE7 Screenshot</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div id="shadow4a">
                This is an example of a box with a blurred box-shadow.  It uses the <code>Shadow</code> filter for Internet Explorer 6 through 8.
</div>
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/nyman2-Firefox.png"   />
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/08/nyman2-IE.png"   />
</td>
</tr>
</tbody>
</table>
<p>This difference may or may not be important to you, and again, I leave it up to the reader to decide what the right solution would be according to the situation.
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.useragentman.com/blog/2011/08/24/how-to-simulate-css3-box-shadow-in-ie7-8-without-javascript/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Full CSS3 Text-Shadows &#8212; Even In IE</title>
		<link>http://www.useragentman.com/blog/2011/06/29/full-css3-text-shadows-even-in-ie/</link>
		<comments>http://www.useragentman.com/blog/2011/06/29/full-css3-text-shadows-even-in-ie/#comments</comments>
		<pubDate>Wed, 29 Jun 2011 04:04:29 +0000</pubDate>
		<dc:creator>zoltan</dc:creator>
				<category><![CDATA[ClearType]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[IE Visual Filters]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Polyfills]]></category>
		<category><![CDATA[text-shadow]]></category>

		<guid isPermaLink="false">http://www.useragentman.com/blog/?p=3296</guid>
		<description><![CDATA[<img src="/blog/wp-content/uploads/2011/06/splash.png" />While researching the possibilities of using text-shadows in IE, I noticed that there wasn't any silver bullet that produced multiple CSS3-like text-shadows in IE.  However, combining my cssSandpaper script with a refactored version of a text-shadowing script by Kazumasa Hasegawa, we can now have IE text-shadow goodness.]]></description>
			<content:encoded><![CDATA[<div id="intro" class="alignLeft">
<span id="css3And">CSS3 &amp;</span><br /><span id="html5">HTML5</span>
</div>
<p>In the last few months, <strong>I have written two articles where I discussed a few strategies to do CSS3-style transforms in IE</strong> (<a href="http://www.useragentman.com/blog/2011/04/14/css3-text-shadow-can-it-be-done-in-ie-without-javascript/">CSS3 Text-Shadow – Can It Be Done in IE Without JavaScript?</a> and <a href="http://www.useragentman.com/blog/2011/04/23/css-blurred-text-shadow-in-ie-part-i/">CSS Blurred Text-Shadow in IE — Part I</a>).  While demonstrating the possibilities to creating a varied range of text-shadows in IE, there wasn&#8217;t any silver bullet that produced what I considered one of the Holy Grails of CSS polyfills: <strong>a method that could take an existing page and render multiple CSS3 text-shadows in IE</strong> with few, if any, changes to the CSS code. To that end, at the end of my last article, I dropped the gauntlet at the end of my last article  and challenged the web development community to help come up with a better solution.  I got a few takers, but one stood out from the rest. <strong><a href="http://asamuzak.jp/">Kazumasa Hasegawa</a> submitted his script and blog post <a href="http://asamuzak.jp/html/321">(in Japanese</a> and then <a href="http://asamuzak.jp/html/322">in English</a>) about his script that could do exactly what I asked: full CSS3-style text-shadowing in IE.</strong>   It can do multiple blurred and unblurred shadows per block of text.  The only caveat is that one would have to set the CSS selectors inside a JavaScript file.  However, the code was extremely well written, and it was very easy for me to refactor it to become a plug-in for my CSS3 polyfill library, <a href="http://www.useragentman.com/blog/current-projects/cross-browser-css-transforms-even-in-ie/">cssSandpaper</a>.  Now, all a developer has to do now is include a few <code>&lt;script&gt;</code> tags into the <code>&lt;head&gt;</code>, and<strong> BAM!!! &mdash; instant text-shadow goodness in IE7+.</strong></p>
<h2>Yeah Whatever!  Show Me Proof!</h2>
<p>If you are viewing this page in IE7+, here are the droids you are looking for:</p>
<table class="dataTable">
<thead>
<tr>
<th>
Live CSS/HTML
</th>
<th class="screenshot">
IE9
</th>
<th class="screenshot">
Firefox
</th>
<th>
Text-Shadow Syntax<br />
</tr>
</thead>
<tbody>
<tr  id="example1">
<td  class="example">
<span><strong>Simple</strong></span>
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/06/ie01.png" alt=""  />
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/06/ff01.png" alt=""  />
</td>
<td class="code">
<pre>
2px 2px 0 #E51919
</pre>
</td>
</tr>
<tr id="example2">
<td  class="example">
<span>Blurred</span>
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/06/ie02.png" alt=""  />
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/06/ff02.png" alt=""  />
</td>
<td class="code">
<pre>
3px 3px 3px #B24C4C
</pre>
</td>
</tr>
<tr id="example3">
<td  class="example cssSandpaper-IEuseGradientFilter">
<span>Etched</span>
</td>
<td class="cssSandpaper-IEuseGradientFilter">
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/06/ie03.png" alt=""  />
</td>
<td class="cssSandpaper-IEuseGradientFilter">
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/06/ff03.png" alt=""  />
</td>
<td class="code">
<pre>
0px 1px 0px white
</pre>
</td>
</tr>
<tr  id="example4">
<td  class="example">
<span>Flaming</span>
</td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/06/ie04.png" alt=""  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/06/ff04.png" alt=""  /></td>
<td class="code">
<pre>
0px   0px  4px white,    0px  -5px  4px #FFFF33,
2px -10px  6px #FFDD33, -2px -15px 11px #FF8800,
2px -25px 18px #FF2200 </pre>
</td>
</tr>
<tr  id="example5">
<td  class="example">
<span>Neon</span>
</td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/06/ie05.png" alt=""  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/06/ff05.png" alt=""  /></td>
<td class="code">
<pre>
0 0 1px  #ffffff, 0 0 2px  #ffffff,
0 0 3px  #ffffff, 0 0 4px  #ff00de,
0 0 7px  #ff00de, 0 0 8px  #ff00de,
0 0 10px #ff00de, 0 0 15px #ff00de;
</pre>
</td>
</tr>
<tr  id="example6">
<td  class="example">
<span>Unfocused</span>
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/06/ie06.png" alt=""  />
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/06/ff06.png" alt=""  />
</td>
<td class="code">
<pre>
0 0 3px #fff
</pre>
</td>
</tr>
<tr  id="example7" >
<td class="example">
<span>Glowing</span>
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/06/ie07.png" alt=""  />
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/06/ff07.png" alt=""  />
</td>
<td class="code">
<pre>
0 0 20px yellow, 0 0 60px yellow
</pre>
</td>
</tr>
<tr  id="example8">
<td  class="example">
<span>Embossed</span>
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/06/ie08.png" alt=""  />
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/06/ff08.png" alt=""  />
</td>
<td class="code">
<pre>
-1px -1px white, 1px 1px #333333
</pre>
</td>
</tr>
<tr  id="example9">
<td  class="example">
<span>Pillow</span>
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/06/ie09.png" alt=""  />
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/06/ff09.png" alt=""  />
</td>
<td class="code">
<pre>
1px 1px white, -1px -1px #444
</pre>
</td>
</tr>
<tr  id="example10">
<td  class="example">
<span>Fake 3D</span>
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/06/ie10.png" alt=""  />
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/06/ff10.png" alt=""  />
</td>
<td class="code">
<pre>
1px 1px rgba(255,128,0,.7),
2px 2px rgba(255,128,0,.7),
3px 3px rgba(255,128,0,.7),
4px 4px rgba(255,128,0,.7),
5px 5px rgba(255,128,0,.7)
</pre>
</td>
</tr>
</tbody>
</table>
<p>(Note that the Blur example does not appear correctly in IE7 and 8, due to lack of support of the <code>transparent</code> color)</p>
<p>These examples were inspired by these excellent examples on the web:</p>
<ul>
<li><a href="http://www.css3.info/preview/text-shadow/">Text-shadow, Photoshop like effects using CSS</a> by <a href="http://www.css3.info">CSS3.info</a> (<a href="http://www.useragentman.com/packages/cssSandpaper-1.5/tests/csssandpaper/textshadowcss3info.html">cssSandpaper version</a>)</li>
<li><a href="http://line25.com/articles/using-css-text-shadow-to-create-cool-text-effects">Using CSS Text-Shadow to Create Cool Text Effects</a> from <a href="http://line25.com/">Chris Spooner</a> (<a href="http://www.useragentman.com/packages/cssSandpaper-1.5/tests/csssandpaper/textshadowline25.html">cssSandpaper version</a>)</li>
<li><a href="http://themegamag.com/coding/css-coding/8-css3-text-shadow-effects/">8 css3 text-shadow effects</a> by <a href="http://falemadi.com/">Fatma Alemadi</a> (<a href="http://www.useragentman.com/packages/cssSandpaper-1.5/tests/csssandpaper/textshadowthemegamag.html">cssSandpaper version</a>)</li>
</ul>
<h2>How Can cssSandpaper Give Me <code>text-shadow</code> Goodness?</h2>
<ol>
<li><a href="https://github.com/zoltan-dulac/cssSandpaperhttps://github.com/zoltan-dulac/cssSandpaper">Download the code from github</a>.</li>
<li>Include the following in the <code>head</code> of the document you have <code>text-shadow</code>ing on:<br />
<blockquote class="code">
<pre>
&lt;script type="text/javascript" src="/path/to/EventHelpers.js"&gt;
&lt;/script&gt;
&lt;script type="text/javascript" src="/path/to/textshadow.js"&gt;
&lt;/script&gt;
&lt;script type="text/javascript" src="/path/to/cssQuery-p.js"&gt;
&lt;/script&gt;
&lt;script type="text/javascript" src="/path/to/cssSandpaper.js"&gt;
&lt;/script&gt;
</pre>
</blockquote>
</li>
<li>It should now work in IE.  With the HTML5 Doctype, <a href="http://mathiasbynens.be/notes/html5-levels#level-1">you can remove the <code>type="text/javascript"</code> attributes</a>.</li>
</ol>
<p><a href="https://github.com/zoltan-dulac/cssSandpaper" class="exampleLink">Download the latest version of cssSandpaper with IE <code>text-shadow</code> support.</a></p>
<h2>Okay, What Are The Caveats</h2>
<p>Like any polyfill solution, there are a few things one has to keep in mind when using a solution like this. </p>
<ol>
<li>As you can see from the above examples, blurred text-shadows in IE look slightly different because of the different algorithm IE&#8217;s Blur Visual Filter uses compared to what CSS3 text-shadow uses.  This is not so obvious on the second example above, but becomes more obvious the more blurred text-shadows are applied on the same text.  For most applications, this is acceptable, but for those of us who like to pixel-bitch (i.e. complain when something is not pixel-perfect), you should be aware of this difference (No, I don&#8217;t know where I got that term from.  I may have made it up.  Anyone else heard of it before?)</li>
<li>Creating a large text-shadow blur (i.e. greater than 70px) on a large piece of text can cause Internet Explorer&#8217;s rendering engine to slow down when the text is scrolled into view.</li>
<li>Sometimes IE cuts off the shadows when the <code>line-height</code> is too small:<br />
<div id="attachment_3452" class="wp-caption aligncenter" style="width: 312px"><a href="http://www.useragentman.com/blog/wp-content/uploads/2011/06/ie01-cutoff.png"><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/06/ie01-cutoff.png" alt="" title="ie01-cutoff" width="302" height="98" class="size-full wp-image-3452" /></a><p class="wp-caption-text">The letter 'P' and other letters with descenders may get cut off if the line-height is not set to be larger than the actual font-size.</p></div></p>
<li>In IE7-8, elements above text-shadowed text that have a <code>line-height</code> property measured in <code>em</code> units may effect the text-shadow in IE.  If there is a problem, the shadow is one pixel off from where it is supposed to be, as shown in this screenshot:<br />
<div id="attachment_3460" class="wp-caption aligncenter" style="width: 626px"><a href="http://www.useragentman.com/blog/wp-content/uploads/2011/06/1pxOff.png"><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/06/1pxOff.png" alt="" title="1pxOff" width="616" height="201" class="size-full wp-image-3460" /></a><p class="wp-caption-text">Examples of a correct looking text-shadow (left) and a text shadow that is a pixel off (right).</p></div></p>
<p>As you can see from the screenshots above, this problem is much more obvious when there is no blur-radius in the text-shadow.  I am trying to see if I can work around this problem, but it looks like it has to do rounding errors when IE converts <code>em</code> units to pixels.  If you have a lot <code>em</code> units in your document, you may want to consider using <a href="/blog/2011/04/14/css3-text-shadow-can-it-be-done-in-ie-without-javascript/">my non-JavaScript solution</a> when using a single, non-blurred text-shadows.
</li>
<li>Sometimes, in order for the text-shadows to render correctly when using ClearType, you may have to use the <code>-sand-chroma-override</code> CSS property on the HTML you applied the <code>text-shadow</code> on.  This property is used by cssSandpaper to fix a problem with ClearType and IE&#8217;s Visual Filters, as described in my previous blog post, <a href="http://www.useragentman.com/blog/2010/09/02/how-to-make-cleartype-font-face-fonts-and-css-visual-filters-play-nicely-together/" >How to Make ClearType, @font-face Fonts and CSS Visual Filters Play Nicely Together</a>.  Most of the time, this property should be set to be the color that that is behind the text value of the background of the text, but sometimes you will have to look at the outline of the texts and the solid shadows to get an idea as to how it should be set.  Let&#8217;s take, for example, the &#8220;Law and Order&#8221; style text at the top of this page.  We used the following CSS to produce the text-shadow on the &#8220;CSS3&#8243; text:<br />
<blockquote class="code">
<pre>
-sand-chroma-override: #666666;
text-shadow:
	-4px 0px 0px #0f1128,
	-8px 0px 4px rgb(50, 152, 234),
	-10px 0px 4px rgba(50, 152, 234, 0.3),
	-8px -4px 4px rgba(50, 152, 234, 0.6),
	-8px 4px 4px rgba(50, 152, 234, 0.6);
</pre>
</blockquote>
<p>Why did I end up using <code>#666666</code>?  It is a greyscale color that is roughly between the brightness of the off-white text and the blue shadow.   If I set it to black instead, the outline of the text&#8217;s first dark text-shadow would be blocky, as seen here:</p>
<table class="dataTable detailedScreenshots">
<thead>
<th></th>
<th><code>-sand-chroma-override: #000000</code></th>
<th><code>-sand-chroma-override: #666666</code></th>
</thead>
<tbody>
<tr>
<th>Scale 100%</th>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/06/lawAndOrderIEChromaBlack.png" alt="" title="lawAndOrderIEChromaBlack"/></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/06/lawAndOrderIEChromaGray.png" alt="" title="lawAndOrderIEChromaBlack"/</td>
</tr>
<tr>
<th>Scale 300%</th>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/05/lawAndOrderIEChromaBlack_Detail1.png" alt="" title="lawAndOrderIEChromaBlack"/</td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/05/lawAndOrderIEChromaGray_Detail1.png" alt="" title="lawAndOrderIEChromaBlack"/</td>
</tbody>
</table>
<p>What you set this value to will depend on the text-shadow recipe you are using and, to paraphrase my Mathematics text-books in college, I leave it up to the reader to play around with the <code>-sand-chroma-override</code> value to see what looks best in which situation.
</li>
</ol>
<h2>In Conclusion</h2>
<p>This script opens up a lot of great possibilities for styling text in IE.  There is still some work to be done to make the script even better with some inevitable bugs that will need to be fixed, and I will continue to work on it to make improvements.  If you see areas for improvement, or any bugs that you see with the code, please make a comment on the <a href="https://github.com/zoltan-dulac/cssSandpaper/issues">cssSandpaper issues page on github</a>.  If you have something to contribute, I would be most grateful. :-)</p>
<p>Other changes that I am planning for cssSandpaper will include:</p>
<ol>
<li><strong>Choice of Selector Library:</strong> I will be refactoring cssSandpaper to use other selector libraries besides cssQuery, which is currently bundled with it.  <strong>This will include, but not restricted to, jQuery. </strong> This will allow developers to reduce the number of libraries included in their documents and reduce load time.</li>
<li><strong>Modularity:</strong> I will make it easy for developers to make their own plugins to support CSS properties not currently supported by cssSandpaper.  This module framework will also allow developers to only add support for the CSS properties they want to use (e.g. if a developer doesn&#8217;t use any CSS3 transforms, then they don&#8217;t have include that code or supporting libraries, like Sylvester.js).</li>
<li><strong>Only Download Code If Needed:</strong> I want to make cssSandpaper only download plugins if actually needed.  This will probably be done with Alex Sexton&#8217;s and Ralph Holzmann&#8217;s excellent <a href="http://yepnopejs.com/">yepnope.js</a> library.  While this library can be used today to speed things up, I want to look into making a little more integrated, if possible.</li>
<li><strong>Further CSS3 Support:</strong> I am looking into polyfills at the moment, like <code>border-image</code>.  Any other ideas for plugins will be most welcome.</li>
</ol>
<h2>Download cssSandpaper</h2>
<p><a href="https://github.com/zoltan-dulac/cssSandpaper" class="exampleLink">Download the latest version of cssSandpaper with IE <code>text-shadow</code> support.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.useragentman.com/blog/2011/06/29/full-css3-text-shadows-even-in-ie/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>CSS Blurred Text-Shadow in IE &#8212; Part I</title>
		<link>http://www.useragentman.com/blog/2011/04/23/css-blurred-text-shadow-in-ie-part-i/</link>
		<comments>http://www.useragentman.com/blog/2011/04/23/css-blurred-text-shadow-in-ie-part-i/#comments</comments>
		<pubDate>Sun, 24 Apr 2011 03:26:16 +0000</pubDate>
		<dc:creator>zoltan</dc:creator>
				<category><![CDATA[CSS3]]></category>
		<category><![CDATA[IE Visual Filters]]></category>
		<category><![CDATA[text-shadow]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[blurred text-shadow]]></category>
		<category><![CDATA[Cross-Browser CSS3 text-shadow]]></category>
		<category><![CDATA[Cross-Browser text-shadow]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[CSS3 blurred text-shadow]]></category>
		<category><![CDATA[CSS3 text-shadow]]></category>
		<category><![CDATA[DropShadow]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[ie filters]]></category>
		<category><![CDATA[IE9]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[Visual Filters]]></category>

		<guid isPermaLink="false">http://www.useragentman.com/blog/?p=2946</guid>
		<description><![CDATA[<img src="/blog/wp-content/uploads/2011/04/introIE9.png" /> Last week, I discussed several strategies web developers can use to simulate CSS text-shadow in IE.  <a href="http://www.useragentman.com/blog/2011/04/14/css3-text-shadow-can-it-be-done-in-ie-without-javascript/">In that article</a>, I mentioned that there was no way that I knew of to simulate text-shadow with a blur-radius in IE without JavaScript.  Since then, <strong>I have discovered a way to simulate the CSS <code>text-shadow</code> effect in IE9 that does not use JavaScript and does not add extra elements to the DOM.</strong>]]></description>
			<content:encoded><![CDATA[<div class="importantNotes">
<h3>Notes:</h3>
<ul>
<li>Before reading this article, you may want to read <a href="http://www.useragentman.com/blog/2011/04/14/css3-text-shadow-can-it-be-done-in-ie-without-javascript/">my previous article</a>, which covers producing other text-shadow effects in IE.</li>
<li>After reading this article, you may want to read <a href="http://www.useragentman.com/blog/2011/06/29/full-css3-text-shadows-even-in-ie/">my subsequent article</a>, which covers using <a href="http://www.useragentman.com/blog/csssandpaper-a-css3-javascript-library/">my cssSandpaper JavaScript library</a> <strong>to produce multiple blurred and un-blurred text-shadows in IE7+</strong></li>
<li>When I first posted this article, I wrote that this solution works with IE8 as well as IE9.  However, further testing has shown that IE8 produces unpredictable results.  Please see the <a href="#caveats">Caveats section</a> for more information</li>
</ul>
</div>
<div id="intro" class="alignLeft">
<p data-innertext="Blurred Text-Shadow in IE9 Without JavaScript">
     Blurred Text-Shadow in IE9 Without JavaScript</p>
</div>
<p>Last week, I discussed several strategies web developers can use to simulate CSS text-shadow in IE.  <a href="http://www.useragentman.com/blog/2011/04/14/css3-text-shadow-can-it-be-done-in-ie-without-javascript/">In that article</a>, I mentioned that there was no way that I knew of to simulate text-shadow with a blur-radius in IE without JavaScript.  Since then, <strong>I have discovered a way to simulate the CSS <code>text-shadow</code> effect in IE9 that does not use JavaScript and does not add extra elements to the DOM.</strong> There are some other caveats to this solution, and because of this, I have titled this article &#8220;Part 1&#8243;, since I believe more work can be done in this area to improve support for blurred text-shadows in IE.</p>
<h2>Step by Step Text-Shadowing in IE9</h2>
<p>This solution makes use of <a href="http://paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/">Paul Irish’s Conditional CSS Pattern</a>, and I would suggest reading that article first before proceeding any further.  I would also recommend reading my previous article, <em><a href="http://www.useragentman.com/blog/2011/04/14/css3-text-shadow-can-it-be-done-in-ie-without-javascript/">CSS3 Text-Shadow – Can It Be Done in IE Without JavaScript?</a></em>, since this solution relies on some ideas presented in that article.</p>
<p>After you become familiar with the above two articles, implementing text-shadow in IE9 becomes a two-step process.</p>
<p>For this tutorial, let&#8217;s assume the following HTML:</p>
<blockquote class="code">
<pre>
&lt;div id="intro" class="alignLeft"&gt;
  &lt;p data-innertext="Blurred Text-Shadow in IE9 Without JavaScript"&gt;
    Blurred Text-Shadow in IE9 Without JavaScript
  &lt;/p&gt;
&lt;/div&gt;
</pre>
</blockquote>
<p>(Note the <code>data-innertext</code> attribute in the element we want to add the text-shadow to.  This must contain exactly the same text that the element itself contains. We&#8217;ll explain why we need this later on).</p>
<p>Let&#8217;s also assume we want a gray text-shadow with both an x- and y-offset of 3 pixels as well as a blur radius of 3 pixels:</p>
<blockquote class="code">
<pre>
#intro p {
     text-shadow: <span class="hilite">3px 3px</span> <span class="hilite2">3px</span> <span class="hilite3">#cccccc</span>;
     width: 230px;
}
</pre>
</blockquote>
<p>Let&#8217;s look at the result so far:</p>
<table class="dataTable">
<thead>
<tr>
<th>Firefox screenshot</th>
<th>IE screenshot</th>
</tr>
</thead>
<tbody>
<tr>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/04/firefox-all.png" alt="Firefox screenshot" title="Firefox screenshot"  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/04/ie-1.png" alt="IE screenshot without blurred text-shadow" title="IE screenshot without blurred text-shadow"  /></td>
</tr>
</tbody>
</table>
<p>As one would expect, works in Firefox but not in IE9.</p>
<p><a class="exampleLink" href="/tests/textShadow/blur1.html">See the above <code>text-shadow</code> code in action (without any IE9 goodness)</a></p>
<h3>Step 1 &#8211; IE Blur Filter</h3>
<p>Using <a href="http://paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/">Paul Irish’s Conditional CSS Pattern</a>, we make an IE9 only rule that will blur the text</p>
<blockquote class="code">
<pre>
#intro p {
     text-shadow: 3px 3px <span class="hilite2">3px</span> <span class="hilite3">#cccccc</span>;
     width: 230px;
}

/* Step 1: apply the Chroma and Blur filter to the text you want the Drop Shadow on */
body.ie9 #intro p {
	zoom: 1;
	color: <span class="hilite3">#cccccc</span>;
	background-color: <span class="hilite">#ccccce</span>;
	filter: progid:DXImageTransform.Microsoft.Chroma(color=<span class="hilite">#ccccce</span>),
	        progid:DXImageTransform.Microsoft.Blur(<span class="hilite2">pixelradius=3</span>);
}
</pre>
</blockquote>
<p>Note four things:</p>
<ol>
<li>I set the <code>color</code> to be the color of the text-shadow.</li>
<li>We set a background-color to be halfway between the color of the text (black) and the visual background of the text (white).  In this case, I chose <code>#ccccce</code> since <code>#cccccc</code> is already being used by as the color of the text-shadow.</li>
<li>We remove the background color with the <a href="http://msdn.microsoft.com/en-us/library/ms532982%28v=vs.85%29.aspx"><code>Chroma</code> Visual Filter</a> (this is necessary to avoid the Blur filter from being pixelated, in the same manner as <a href="/blog/2011/04/14/css3-text-shadow-can-it-be-done-in-ie-without-javascript/">the text-shadows in my previous article</a>).</li>
<li>We apply the <a href="http://msdn.microsoft.com/en-us/library/ms532979%28v=vs.85%29.aspx"><code>Blur</code> Visual Filter</a> to have a <code>pixelradius</code> of 3 (which is the same as the blur radius from the <code>text-shadow</code>.</li>
</ol>
<table class="dataTable">
<thead>
<tr>
<th>Firefox screenshot</th>
<th>IE screenshot</th>
</tr>
</thead>
<tbody>
<tr>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/04/firefox-all.png" alt="Firefox screenshot" title="Firefox screenshot"  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/04/ie-2.png" alt="IE screenshot of text with Chroma and Blur filters applied" title="IE screenshot of text with Chroma and Blur filters applied"  /></td>
</tr>
</tbody>
</table>
<p><a class="exampleLink" href="/tests/textShadow/blur2.html">See the above code in action (IE9 will only show the blurred text)</a></p>
<p>So now we have the shadow in IE!  But what about the solid text on top?</p>
<h3>Step 2 &#8211; Use <code>:before</code> To Replace the Solid Text</h3>
<p>We now must add one more selector in order to get our black, un-blurred text back:</p>
<blockquote class="code">
<pre>
/* Step 2: create a :before rule on the blurred text */
body.ie9 #intro p:before {
  /* color and width of the original text */
  color: black;
  width: 230px;

  /* This is needed to place the text directly over the shadow. */
  position: absolute;

  /* This assumes that the data-innertext is the same as the text inside the element. */
  content: attr(data-innertext);

  /* Positions the text */
  margin-top: 0px;
  margin-left: 0px;
}
</pre>
</blockquote>
<p>The <code>:before</code> rule duplicates the blurred text, colors it black and places it before the blurred text.  The text is then duplicated because of the <code>content</code> property, which uses the value of the <code>data-innertext</code> attribute as the generated content &mdash; now you know why we set <code>data-innertext</code> at the beginning of this example.  It is absolutely positioned, and since the <code>top</code> and <code>left</code> properties are not set, it places the text on top of the original text.  Also note that the <code>width</code> is the same as the original element (in this case <code>230px</code>).  This is very important, otherwise the shadow will not appear below the text correctly. </p>
<p>The only thing left to explain is the margins and how they position the text.  We must use these formulas to produce the x- and y- offsets of the original <code>text-shadow</code></p>
<div class="equation">
<p><code>margin-left</code> = blur-radius &#8211; offset-x </p>
<p><code>margin-top</code> = blur-radius &#8211; offset-y </p>
</div>
<p>Why do we need to do this?  Because adding the <code>Blur</code> filter pushes the text a few pixels from down and to the right &mdash; namely, the same amount of pixels from the blur-radius.  These simple formulas compensate for that, and place the shadows according to what you set for the x- and y-offsets.</p>
<table class="dataTable">
<thead>
<tr>
<th>Firefox screenshot</th>
<th>IE screenshot</th>
</tr>
</thead>
<tbody>
<tr>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/04/firefox-all.png" alt="Firefox screenshot" title="Firefox screenshot"  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/04/ie-3.png" alt="IE screenshot of simultaed text-shadow" title="IE screenshot of simultaed text-shadow"  /></td>
</tr>
</tbody>
</table>
<p>And now, let&#8217;s take a look at the difference close up:</p>
<table class="dataTable">
<thead>
<tr>
<th>Firefox screenshot</th>
<th>IE screenshot</th>
</tr>
</thead>
<tbody>
<tr>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/04/firefox-zoom.png" alt="Firefox screenshot" title="Firefox screenshot"  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/04/ie-zoom.png" alt="IE screenshot of simultaed text-shadow" title="IE screenshot of simultaed text-shadow"  /></td>
</tr>
</tbody>
</table>
<p>Note: the other browsers look about the same in Firefox, so I didn&#8217;t bother posting screen captures of them.</p>
<p><a class="exampleLink" href="/tests/textShadow/blur3.html">See the above code in action, with IE9&#8242;s blurred <code>text-shadow</code> workaround.</a></p>
<h2 id="caveats" name="caveats">Caveats</h2>
<p>This solution only works under certain conditions:</p>
<ol>
<li><strong>You cannot have more than one type of font, font-size, font-weight or font-style with the shadowed element.</strong>  This is due to the way we produce the shadow (i.e. the <code>data-innertext</code> cannot contain any HTML elements to control the style).</li>
<li><strong>The shadowed element cannot be an <code>inline</code> element.</strong>  It can be a block or an inline-block though.</li>
<li><strong>Any background colors or background-images that you want to appear in with the text-shadow must appear in an outside element.</strong>  For example, in the following HTML, you would put the <code>background-image</code> or <code>background-color</code> on the <code>&lt;div&gt;</code> tag, not the <code>&lt;p&gt;</code> tag which would have the <code>text-shadow</code>.<br />
<blockquote class="code">
<pre>
&lt;div id="intro" class="alignLeft"&gt;
  &lt;p data-innertext="Blurred Text-Shadow in IE9 Without JavaScript"&gt;
    Blurred Text-Shadow in IE9 Without JavaScript
  &lt;/p&gt;
&lt;/div&gt;
</pre>
</blockquote>
</li>
<li><strong>The shadowed element must be of fixed width</strong> (i.e. widths can be measured in <code>px</code>, <code>em</code>, etc.  <strong>Percentages will not work</strong>).</li>
<li><strong>As far as I know, it is impossible to have multiple text-shadows on the same block of text.</strong>  If you wish to do this do glow text, you may want to look at my previous article, <em><a href="/blog/2011/04/14/css3-text-shadow-can-it-be-done-in-ie-without-javascript" />CSS3 Text-Shadow – Can It Be Done in IE Without JavaScript?</a></em>.
<li><strong>It only works in IE9.</strong>  When I originally posted this article, I claimed it worked with IE8, but after further testing, when setting a font on a <code>:before</code> rule, IE8 sometimes produces unpredictable results (sometimes, the font is set to something different than the original text, and other times, the letter spacing is not correct).  IE8 and lower are out of luck. :-(</li>
</ol>
<h2>An Open Challenge To Improve This Technique</h2>
<p>Think you can do better?  I challenge you!  I am almost certain there has to be a better way with fewer restrictions that the solution I give here. I also know there are quite a few smart people out there who read this blog, so <strong>I am dropping the gauntlet and challenging everyone reading this article to help come up with a better solution.</strong>  Post a URL with an example below, and if I like what I see, I will post a follow up article to this one with what I believe are the best solutions. Here&#8217;s your chance to solve what I think is a huge web development problem and be recognized as Someone Really Clever&trade;.</p>
<p>Unless, of course, I come up with a better solution first. :-)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.useragentman.com/blog/2011/04/23/css-blurred-text-shadow-in-ie-part-i/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>CSS3 Text-Shadow &#8211; Can It Be Done in IE Without JavaScript?</title>
		<link>http://www.useragentman.com/blog/2011/04/14/css3-text-shadow-can-it-be-done-in-ie-without-javascript/</link>
		<comments>http://www.useragentman.com/blog/2011/04/14/css3-text-shadow-can-it-be-done-in-ie-without-javascript/#comments</comments>
		<pubDate>Thu, 14 Apr 2011 14:13:05 +0000</pubDate>
		<dc:creator>zoltan</dc:creator>
				<category><![CDATA[ClearType]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[IE Visual Filters]]></category>
		<category><![CDATA[text-shadow]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Cross-Browser CSS3 text-shadow]]></category>
		<category><![CDATA[Cross-Browser text-shadow]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[CSS3 text-shadow]]></category>
		<category><![CDATA[DropShadow]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[ie filters]]></category>
		<category><![CDATA[IE9]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[Visual Filters]]></category>

		<guid isPermaLink="false">http://www.useragentman.com/blog/?p=2720</guid>
		<description><![CDATA[<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/04/splash.png" /> CSS3 <code>text-shadow</code> rocks, but it doesn't work in any version of Internet Explorer, including IE9.  While it is impossible to replicate all <code>text-shadow</code> effects in The Browser That Likes To Be Difficult, there are some ways to emulate this effect without JavaScript using Visual Filters, even when ClearType is enabled.  This article can show you how and contains lots of examples.]]></description>
			<content:encoded><![CDATA[<div class="importantNotes">
<h3>Update: April 24, 2011</h3>
<p>Since writing this article, I have also discovered <a href="http://www.useragentman.com/blog/2011/04/23/css-blurred-text-shadow-in-ie-part-i/">a way to implement blurred text-shadows in IE8+</a>.
</div>
<div class="importantNotes">
<h3>Update: July 13, 2011</h3>
<p>You may want to read <a href="http://www.useragentman.com/blog/2011/06/29/full-css3-text-shadows-even-in-ie/">my subsequent article</a>, which covers <strong>using my cssSandpaper JavaScript library to produce multiple blurred and un-blurred text-shadows in IE7+.</strong></p>
</div>
<div id="introExample" class="alignLeft">
<p>CSS3 + IE</p>
</div>
<p>When IE9 was released, I was really happy to see all the great CSS3 features it supported.  2D Transforms, advanced selectors, border-radius, rgba/hsla colors, WOFF fonts &#8230; the list goes on.  And no polyfills required!  <strong>I was, however, disappointed that IE9 doesn&#8217;t support two of my favorite CSS3 effects: <code>border-image</code> and <code>text-shadow</code>.</strong>  I&#8217;m sure that I will notice other CSS3 effects missing over time, but these are two features that I currently find incredibly useful. This article will deal with <code>text-shadow</code>: how it works in browsers that support it, and strategies we can use today to emulate some of its functionality in IE.  <strong>Although the solutions I present here are based on IE&#8217;s Visual Filters,</strong> and that some articles like <a href="http://www.workingwith.me.uk/articles/css/cross-browser-drop-shadows">this one by Neil Crosby</a> have looked into it as a solution, <strong>I present here some new information</strong> &#8211; how to make them work correctly with Windows Standard and ClearType font-smoothing and how to write the final CSS that won&#8217;t break any browser.</p>
<h2>How does CSS3 <code>text-shadow</code> Work?</h2>
<p>Before we go on about IE, let&#8217;s have a quick overview of how the CSS3 specification works.  In all the other browsers (i.e. Firefox 3.0+, Safari 4.0+, Opera 10.0+ and Chrome 4.0+) text-shadow has pretty solid support.  Its basic syntax is:</p>
<blockquote class="code">
<pre>
#obj {
   text-shadow: <em>&lt;x-offset&gt;</em> <em>&lt;y-offset&gt;</em> <em>&lt;blur-radius&gt;</em> <em>&lt;color&gt;</em>;
}
</pre>
</blockquote>
<p>The <em>x-offset</em> and <em>y-offset</em> state how many pixels horizontally and vertically the shadow is positioned with respect to the original text, while the <em>blur-radius</em> is used to express how much the shadow is blurred (the higher the value, the more blurry it is).  All of these values can be expressed using any CSS unit of measure (e.g. <code>px</code>, <code>em</code>, etc).  The <em>color</em> can be any CSS color value, representing the color of the text.</p>
<p>Here are some examples:</p>
<table class="dataTable screenshots">
<thead>
<tr>
<th>Pure CSS Example (will be visible if your browser supports <code>text-shadow</code></th>
<th>Firefox Screenshot (similar in other browsers except IE)</th>
</tr>
</thead>
<tbody>
<tr>
<td id="cssExample1" class="test">text:shadow: 5px 5px 0px black;</td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/04/example1.png" alt="Screenshot of the text on the left in Firefox." /></td>
</tr>
<tr>
<td id="cssExample2" class="test">text:shadow: 5px 5px 5px black;</td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/04/example2.png" alt="Screenshot of the text on the left in Firefox." /></td>
</tr>
<tr>
<td id="cssExample3" class="test">text:shadow: 1px 0px 0px white;</td>
<td class="example3"><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/04/example3.png" alt="Screenshot of the text on the left in Firefox." /></td>
</tr>
</tbody>
</table>
<p>You are not restricted to just one shadow.  You can have multiple shadows, separated by commas.  For example:</p>
<blockquote class="code">
<pre>
#obj {
	text-shadow:
		 1px -1px 5px rgba(0, 0, 0, 0.2),
		-1px  1px 5px rgba(0, 0, 0, 0.2),
		 1px  1px 5px rgba(0, 0, 0, 0.2),
		-1px -1px 5px rgba(0, 0, 0, 0.2),
		 0px  1px 5px rgba(0, 0, 0, 0.2),
		 0px -1px 5px rgba(0, 0, 0, 0.2),
		 1px  0px 5px rgba(0, 0, 0, 0.2),
		-1px  0px 5px rgba(0, 0, 0, 0.2);
}
</pre>
</blockquote>
<p>renders white text legibly on a white background:</p>
<table class="dataTable screenshots">
<thead>
<tr>
<th>Pure CSS Example (will be visible if your browser supports <code>text-shadow</code></th>
<th>Firefox Screenshot (similar in other browsers except IE)</th>
</tr>
</thead>
<tbody>
<tr>
<td id="white" class="test">
This is white text on a white background
</td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/04/example4.png" alt="Screenshot of the text on the left in Firefox." /></td>
</tr>
<tr>
</tbody>
</table>
<h2>Well &#8230; What About IE?</h2>
<p><strong>Currently, no version of Internet Explorer natively understands the CSS3 Syntax for <code>text-shadow</code>. </strong> However, IE 4.0+ can do text-shadow-like effects using Microsoft&#8217;s proprietary <a href="http://msdn.microsoft.com/en-us/library/ms532853%28v=vs.85%29.aspx">Visual Filters</a> &#8212; unfortunately, if the user&#8217;s computer has any type of font-smoothing technology enabled, the <strong><a href="http://msdn.microsoft.com/en-us/library/ms532985%28v=vs.85%29.aspx"><code>DropShadow</code></a> Visual Filter effect is quite messy and ugly</strong>.  Since <a href="http://blogs.msdn.com/b/e7/archive/2009/06/23/engineering-changes-to-cleartype-in-windows-7.aspx">ClearType is enabled by default</a> in modern versions of the Windows operating system (i.e. Vista, Windows 7) and is <a href="http://social.technet.microsoft.com/Forums/en/ieitprocurrentver/thread/01c447b1-5c78-4d2f-9968-6eeabc04a68b">very difficult to disable it in Internet Explorer 9</a>, this is a show-stopper. <strong>Don&#8217;t dispair, there is a workaround.</strong> Let&#8217;s see how <code>DropShadow</code> is supposed to work, and see how <strong>we can &#8220;clean-up&#8221; the result to look much nicer in modern versions of Windows.</strong></p>
<h3>Basic Text-Shadow</h3>
<p>Let&#8217;s first take a look at a basic text-shadow without any blurring of the shadow:</p>
<blockquote class="code">
<pre>
#basicTextShadow {
	background-color: white;
}

#basicTextShadow p {
	text-shadow: <span class="hilite2">3px 3px</span> 0px <span class="hilite3">#99cc99</span>;
}
</pre>
</blockquote>
<p>The equivalent Visual Filter syntax is:</p>
<blockquote class="code">
<pre>

#basicTextShadow {
	background-color: white;
}

#basicTextShadow p {
	zoom: 1;
	filter: progid:DXImageTransform.Microsoft.DropShadow(<span class="hilite2">OffX=3, OffY=3</span>, <span class="hilite3">Color=#99cc99</span>);
}
</pre>
</blockquote>
<p>Note that the <code>zoom</code> line &mdash; it is here since it <a href="http://www.satzansatz.de/cssd/onhavinglayout.html">forces IE to recognize that the object &#8220;has layout&#8221;</a>.  Visual Filters do not work unless a node &#8220;has layout&#8221;.</p>
<p>The problem is that when ClearType is turned on, many Visual Filters, including <code>DropShadow</code> don&#8217;t render text very well:</p>
<table class="dataTable  screenshots">
<thead>
<tr>
<th>IE <code>DropShadow</code> without ClearType</code></th>
<th>IE <code>DropShadow</code> with ClearType</th>
</tr>
</thead>
<tbody>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/04/justDropShadowWithoutFontSmoothing.png" alt="IE DropShadow without ClearType" />
</td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/04/justDropShadowWithFontSmoothing.png" alt="IE DropShadow with ClearType" />
</td>
</tbody>
</table>
<p>The text renders much better when you have a <code>background-color</code>.  </p>
<blockquote class="code">
<pre>
#basicTextShadow p {
	zoom: 1;
	<span class="hilite">background-color: white;</span>
	filter: progid:DXImageTransform.Microsoft.DropShadow(OffX=3, OffY=3, Color=#99cc99);
}
</pre>
</blockquote>
<p><div id="attachment_2882" class="wp-caption aligncenter" style="width: 335px"><a href="http://www.useragentman.com/blog/wp-content/uploads/2011/04/dropShadowWithBackground.png"><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/04/dropShadowWithBackground.png" alt=" IE using the DropShadow Visual Filter with a &lt;code&gt;background-color&lt;/code&gt;." title="dropShadowWithBackground" width="325" height="130" class="size-full wp-image-2882" /></a><p class="wp-caption-text"> IE using the <code>DropShadow</code> Visual Filter with a <code>background-color</code>.</p></div></p>
<p>However, this will cause <code>DropShadow</code> to behave more like the CSS3 <code>box-shadow</code> property.</p>
<p>How can we have the font render well <em>without</em> the <code>background-color</code>.  All we have to do is cut-out the background-color using the <a href="http://msdn.microsoft.com/en-us/library/ms532982%28v=vs.85%29.aspx"><code>Chroma</code> filter</a>:</p>
<blockquote class="code">
<pre>
#basicTextShadow p {
	zoom: 1;
	background-color: <span class="hilite">white</span>;
	filter: progid:DXImageTransform.Microsoft.Chroma(Color=<span class="hilite">white</span>)
		progid:DXImageTransform.Microsoft.DropShadow(OffX=3, OffY=3, Color=#99cc99);
}
</pre>
</blockquote>
<table class="dataTable">
<thead>
<tr>
<th>Firefox using CSS3 <code>text-shadow</code></th>
<th>IE with <code>Chroma</code> and <code>DropShadow</code> Filters Applied</th>
</tr>
</thead>
<tbody>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/04/firefoxBasic.png" alt="Firefox Using CSS3 Syntax." />
</td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/04/dropShadowWithBackgroundAndChroma.png" alt="IE with Chroma and DropShadow Filters Applied" />
</td>
</tbody>
</table>
<p><strong>The Chroma filter allows us to remove a specific color from the rendered element.</strong>  In this case, we are removing white, which is also the background-color.  As a result the font renders smoothly, and the <code>DropShadow</code> filter behaves almost like a true <code>text-shadow</code>.  This is similar to the method I describe in a previous article I wrote, <a href="http://www.useragentman.com/blog/2010/09/02/how-to-make-cleartype-font-face-fonts-and-css-visual-filters-play-nicely-together/" rel="bookmark" title="Permanent Link to How to Make ClearType, @font-face Fonts and CSS Visual Filters Play Nicely Together">How to Make ClearType, @font-face Fonts and CSS Visual Filters Play Nicely Together</a>.  To sum-up: regardless of whether you use @font-face or not, you can make Visual Filters render text correctly by creating a background for the element, and then removing that background with the <code>Chroma</code> filter.</p>
<p><a class="exampleLink" href="http://www.useragentman.com/tests/textShadow/example1.html">See the above three examples in action (IE is recommended in order to see the Visual Filter differences)</a></p>
<p>Here is some actual HTML that is styled so that all browsers, including IE, will render a text-shadow correctly:</p>
<div id="basicTextShadow" class="test">
<p>This is an example of a basic text-shadow.  Note that is looks almost the same in browsers that understand CSS3 text-shadow as well as Internet Explorer, which doesn't.</p>
</div>
<p>Here is the CSS for "compliant" web-browsers:</p>
<blockquote class="code">
<pre>
#basicTextShadow p {
	text-shadow: <span class="hilite2">3px 3px</span> 0px <span class="hilite3">#99cc99</span>;
}
</pre>
</blockquote>
<p>And here is the CSS for IE (using <a href="http://paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/">Paul Irish’s Conditional CSS Pattern</a>):</p>
<blockquote class="code">
<pre>
body.ie6 #basicTextShadow p,
body.ie7 #basicTextShadow p,
body.ie8 #basicTextShadow p,
body.ie9 #basicTextShadow p {
	zoom: 1;
	background-color: <span class="hilite">#cccccc;</span>
	filter: progid:DXImageTransform.Microsoft.Chroma(Color=<span class="hilite">#cccccc</span>)
	        progid:DXImageTransform.Microsoft.DropShadow(<span class="hilite2">OffX=3, OffY=3</span>, <span class="hilite3">Color=#99cc99</span>);
}
</pre>
</blockquote>
<p><strong>There are some things that you should keep in mind with this solution:</strong></p>
<ul>
<li>Since we are using the <code>Chroma</code> filter to remove the <code>background-color</code> of the object, <strong>any background image or color that you want to appear in the document must be placed in the containing tag</strong>.  In this example, the background-image is styled on a <code>&lt;div&gt;</code> tag, while the text-shadow appears in a <code>&lt;p&gt;</code> tag inside it.</li>
<li><strong>Unlike CSS3, it is impossible to use multiple shadows using Visual Filters</strong> (to be more accurate: it is syntactically possible, but it doesn't look good or behave as one would expect).</li>
<li>According to Microsoft's documentation, <strong>IE8+ is required to have an extra line containing an <code>-ms-filter</code> property</strong> which is identical to the <code>filter</code> one except the property's value is contained on one line within a set of quotation marks.<br />
<blockquote class="code">
<pre>
body.ie6 #basicTextShadow p,
body.ie7 #basicTextShadow p,
body.ie8 #basicTextShadow p,
body.ie9 #basicTextShadow p {
	zoom: 1;
	background-color: #cccccc;
	<span class="hilite">-ms-filter: "progid:DXImageTransform.Microsoft.Chroma(Color=#cccccc) progid:DXImageTransform.Microsoft.DropShadow(Color=#99cc99, OffX=3, OffY=3)";</span>
	filter: progid:DXImageTransform.Microsoft.Chroma(Color=#cccccc)
	        progid:DXImageTransform.Microsoft.DropShadow(OffX=3, OffY=3, Color=#99cc99);
}
</pre>
</blockquote>
<p>I have, however, noticed that the CSS works in IE9 standards mode without this additional line.</li>
</ul>
<h3>Text Glowing</h3>
<p>Text glowing is a term to describe a shadow that "envelopes" some text in a glow of color to make it more legible.  Let's take the following example of black text on a dark background:</p>
<div id="sky" class="test">
<p>This is dark text on a dark background.</p>
</div>
<p>Hard to read, isn't it?  We could change the color of the text to white, but you could also put a white glow around the text to keep it black and maintain the dark atmosphere of the image:</p>
<div id="sky" class="test textShadowTest">
<p>This is dark text on a dark background.</p>
</div>
<p>Using the CSS3 <code>text-shadow</code> property, this is just a case of creating a set of eight shadows around the text in question:</p>
<blockquote class="code">
<pre>
#sky.textShadowTest p {
	text-shadow:
		 0px -1px <span class="hilite2">5px</span> <span class="hilite3">#eeeeee</span>,     /* north      */
		 0px  1px <span class="hilite2">5px</span> <span class="hilite3">#eeeeee</span>,     /* south      */
		-1px  0px <span class="hilite2">5px</span> <span class="hilite3">#eeeeee</span>,     /* west       */
		 1px  0px <span class="hilite2">5px</span> <span class="hilite3">#eeeeee</span>,     /* east       */
		-1px -1px <span class="hilite2">5px</span> <span class="hilite3">#eeeeee</span>,     /* north-west */
		-1px  1px <span class="hilite2">5px</span> <span class="hilite3">#eeeeee</span>,     /* north-east */
		 1px -1px <span class="hilite2">5px</span> <span class="hilite3">#eeeeee</span>,     /* south-west */
		 1px  1px <span class="hilite2">5px</span> <span class="hilite3">#eeeeee</span>;     /* south-east */
}
</pre>
</blockquote>
<p>It basically creates a text-shadow in all eight directions and blurs them together, giving us a glow effect.  Pretty neat, but it doesn't work in Internet Explorer.  However adding this CSS code will give IE something <em>roughly</em> equivalent:</p>
<blockquote class="code">
<pre>

/* Use <a href="http://paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/"
>Paul Irish’s Conditional CSS Pattern</a> to isolate the rule for Internet Explorer */
body.ie6 #sky.textShadowTest p,
body.ie7 #sky.textShadowTest p,
body.ie8 #sky.textShadowTest p,
body.ie9 #sky.textShadowTest p {
	background-color: #cccccc;
	filter: progid:DXImageTransform.Microsoft.Chroma(Color=#cccccc)
		progid:DXImageTransform.Microsoft.Glow(<span class="hilite2">Strength=5</span>, Color=<span class="hilite3">#eeeeee</span>);
}
</pre>
</blockquote>
<table class="dataTable smallDataTable">
<thead>
<tr>
<th>Firefox using CSS3<br /><code>text-shadow</code></p>
<th>IE using the <code>Chroma</code><br />and <code>Glow</code> Visual Filter.</th>
</tr>
</thead>
<tbody>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/04/FirefoxGlow.png" alt="" title="FirefoxGlow" width="170" height="92" class="alignnone size-full wp-image-2780" />
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/04/IEGlow.png" alt="" title="FirefoxGlow" width="170" height="92" class="alignnone size-full wp-image-2780" />
</td>
</tbody>
</table>
<p>Note a few things about this solution:</p>
<ol>
<li>The results aren't exactly the same.  Doing a side by side comparison reveals that the CSS3 version looks a little smoother. Here are the above examples blown up 300% to show detail:<br />
<table class="dataTable smallDataTable">
<thead>
<tr>
<th>Firefox using CSS3<br /><code>text-shadow</code></p>
<th>IE using the <code>Chroma</code><br />and <code>Glow</code> Visual Filter.</th>
</tr>
</thead>
<tbody>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/04/FirefoxGlowScaled.png" alt="" title="FirefoxGlow" width="170" height="92" class="alignnone size-full wp-image-2780" />
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/04/IEGlowScaled.png" alt="" title="FirefoxGlow" width="170" height="92" class="alignnone size-full wp-image-2780" />
</td>
</tbody>
</table>
</li>
<li>The <code>Strength</code> in the <code>Glow</code> filter is the same amount of pixels in the blur-factor in the CSS3 <code>text-shadow</code> code.</li>
<li>You'll notice that <code>background-color</code> I removed with the <code>Chroma</code> filter in this case is not blue, but gray, a color halfway between the color of the text (black) and the color or the glowing text (white).  This is so that the smoothness obtained by ClearType is somewhat preserved. Choosing black would make the text look to "thick", while choosing white would make the text look too "thin".</li>
<li>You'll notice the IE glowing text is "pushed" a little down and to the right.  That's because IE treats the <code>Glow</code> as part of the width and height of the element.  This can be fixed by relatively positioning the object and setting the <code>top</code> and <code>left</code> properties to the negative value of <code>Glow</code>'s <code>Strength</code> value to compensate:<br />
<blockquote class="code">
<pre>
body.ie6 #sky.textShadowTest p,
body.ie7 #sky.textShadowTest p,
body.ie8 #sky.textShadowTest p,
body.ie9 #sky.textShadowTest p {
	zoom: 1;
	background-color: #cccccc;
	filter: progid:DXImageTransform.Microsoft.Chroma(Color=#cccccc)
		progid:DXImageTransform.Microsoft.Glow(Color=#eeeeee, Strength=3);
	<span class="hilite">position: relative;</span>
	<span class="hilite">top: -3px;</span>
	<span class="hilite">left: -3px;</span>
}
</pre>
</blockquote>
<p>The results are subtle, but will help to make the result a little more pixel perfect. </p>
<table class="dataTable smallDataTable">
<thead>
<tr>
<th>Firefox using CSS3<br /><code>text-shadow</code></p>
<th>IE using the modified<br />version of the <code>Chroma</code><br />fix.</th>
<th>IE using the both <br />positioning and modified<br /><code>Chroma</code><br />fix.</th>
</tr>
</thead>
<tbody>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/04/FirefoxGlow.png" alt="" title="FirefoxGlow" width="170" height="92" class="alignnone size-full wp-image-2780" />
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/04/IEGlow.png" alt="" title="FirefoxGlow" width="170" height="92" class="alignnone size-full wp-image-2780" />
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/04/IEGlow2.png" alt="" title="FirefoxGlow" width="170" height="92" class="alignnone size-full wp-image-2780" />
</td>
</tbody>
</table>
<p> If you don't like using relatively positioning the text, you can also use negative left and top margins to achieve the same effect, or you can leave it the way it is &mdash; after all, what are a few pixels between friends? ;-)</p>
</li>
</ol>
<p>I have used this method in <a href="/blog/2011/03/29/pixel-perfect-css3-border-image-in-depth/">my previous blog post</a> about CSS3 <code>border-image</code>:</p>
<table class="dataTable">
<thead>
<tr>
<th>Firefox</th>
<th>IE9</th>
</thead>
<tbody>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/03/firefoxFallback.png" alt="Screenshot of how the border-image example at the top of the page looks in Firefox." title="Screenshot of how the border-image example at the top of the page looks in Firefox." width="355" height="284" class="size-full wp-image-2634" /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/03/IEfallback.png" alt="Screenshot of how the border-image example &#039;falls back&#039; in IE9." title="Screenshot of how the border-image example &#039;falls back&#039; in IE9." width="362" height="291" class="size-full wp-image-2633" /></td>
</tbody>
</table>
<p>Here is the CSS that I used to produce it:</p>
<blockquote class="code">
<pre>
#introExample p, #introExample code {
   color: white;
   text-shadow:   2px  2px 3px #333333,
                 -2px -2px 3px #333333,
                 -2px  2px 3px #333333,
                  2px -2px 3px #333333;
}

/*
 * The "poor man's" version of text-shadow for IE's Visual filters.
 */
body.ie6 #introExample p,
body.ie7 #introExample p,
body.ie8 #introExample p,
body.ie9 #introExample p {
	zoom: 1;
	background: #000003;
	filter: progid:DXImageTransform.Microsoft.Chroma(Color=#000003)
		progid:DXImageTransform.Microsoft.Glow(Color=#3e3e3e, Strength=4); 

}
</pre>
</blockquote>
<p>The values of the Visual Filter code doesn't match exactly with the <code>text-shadow</code>.  This is in part that I only used four directions in the <code>text-shadow</code> code (i.e. south-east, north-west, north-east and south-west).  I don't believe this conversion is an exact science ... it is worth your time to experiment with these values, using the examples in this article as a guide.</p>
<h2>But How About Other Types Of Shadows?</h2>
<p><strike>The short answer for now is that you are out of luck.  There are no Visual Filters, as far as I know, that will allow you to do other types of shadowing, like a Basic Text-Shadow with blurring:</strike> <strong>Update April 24, 2011:</strong> Since writing this article, I have a discovered <a href="http://www.useragentman.com/blog/2011/04/23/css-blurred-text-shadow-in-ie-part-i/">a way to implement blurred text-shadows in IE8+</a>.  I have left the rest of the information here since it is still relevant, interesting and influenced my own work.</p>
<p><div id="attachment_2848" class="wp-caption aligncenter" style="width: 390px"><a href="http://www.useragentman.com/blog/wp-content/uploads/2011/04/example2.png"><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/04/example2.png" alt="An example of a basic text shadow with blurring." title="example2" width="380" height="90" class="size-full wp-image-2848" /></a><p class="wp-caption-text">There is no way that I know to do this in IE without JavaScript or without affecting the DOM</p></div></p>
<p><a href="http://kilianvalkhof.com/">Kilian Valkhob</a> also has <a href="http://kilianvalkhof.com/2008/design/almost-cross-browser-text-shadow/">a solution for this</a> which involves making a copy of the desired text and blurring it with the <a href="http://msdn.microsoft.com/en-us/library/ms532979%28v=vs.85%29.aspx"><code>Blur</code> filter</a>. While I think the results look pretty good, I hesitate using this method since search engines may see the text repeated in the document and index that text higher than it should be rated (or they might penalize the document because the search engine thinks the author is trying to do some unethical hack of the page ranking algorithm it uses).  Vilkhob has, however, also created a <a href="http://kilianvalkhof.com/2008/javascript/text-shadow-in-ie-with-jquery/">text-shadowing JavaScript library</a> that automates this process, and since the repeated text isn't actually in the document, it may be a solution to the search engine concern.  This solution is something i am currently looking into adding to cssSandpaper, but I want to do more research into this before I implement it in a public version of my library. For example, how would screen readers handle this JavaScript generated "double text"?  </p>
<h2>Conclusion</h2>
<p>CSS3 <code>text-shadow</code> is a great effect in a web developer's toolkit.  Hopefully IE will natively support it soon, but in the meantime, at least there are some use cases you can use Visual Filters to do some of eye-candy it supports.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.useragentman.com/blog/2011/04/14/css3-text-shadow-can-it-be-done-in-ie-without-javascript/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Pixel Perfect CSS3 border-image In Depth.</title>
		<link>http://www.useragentman.com/blog/2011/03/29/pixel-perfect-css3-border-image-in-depth/</link>
		<comments>http://www.useragentman.com/blog/2011/03/29/pixel-perfect-css3-border-image-in-depth/#comments</comments>
		<pubDate>Tue, 29 Mar 2011 04:18:55 +0000</pubDate>
		<dc:creator>zoltan</dc:creator>
				<category><![CDATA[border-image]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.useragentman.com/blog/?p=2536</guid>
		<description><![CDATA[<img src="/blog/wp-content/uploads/2011/03/front.png" /> Using the CSS3 <code>border-image</code> property, you can make coo graphical borders without cutting up images to bits. There are a few gotchas that developers should be aware of before implementing it and this article will cover these caveats, a tool that you can use to help generate border-images effectively, and a few strategies to ensure it gracefully degrades in older browsers]]></description>
			<content:encoded><![CDATA[<div id="introExample" class="alignLeft">
<p>This is an example of CSS3 <code>border-image</code> in action. Browsers that don&#8217;t support it will see a normal solid coloured <code>border</code>, while modern browsers will see a nice framed <code>border-image</code>. Note that the clouds are produced with an additional <code>background-image</code>, showing the possibility of having separate images for borders and backgrounds.</p>
</div>
<p>The <code>border-image</code> property is something I&#8217;ve been wanting for a long time. For years, I have been cutting up images into several pieces in order to emulate this effect (the most recent example of this was used in <a href="/tests/fontConverter/ArgBiwSc.html">this demo</a> of the <a href="/blog/2011/02/20/converting-font-face-fonts-quickly-in-any-os/">CSS3 Font Converter</a>).  The difference is that <strong>CSS3&#8242;s border-image property uses only one image and two lines of CSS</strong> (well &#8230; 6 if you include the vendor-specific properties and the fallback for browsers that don&#8217;t support it).</p>
<p>Since it is newly implemented in most web browsers, there are a few gotchas that developers should be aware of before implementing <code>border-image</code>.  This article will cover these caveats, a tool that you can use to help generate border-images effectively, and a few things you should keep in mind so that pages don&#8217;t look funny in browsers that don&#8217;t support <code>border-radius</code>.  </p>
<h2>Let&#8217;s Look At An Example</h2>
<div id="example1">
<p>This is an example of a block level element that uses the  <code>border-image</code> property.  The <code>border-image</code> is viewable in all major browsers except for IE (more on that later).  It <strong>uses only one image</strong> to produce the border &mdash; no images were cut-up into pieces or harmed in any other way.  The code to generate this border is fairly straight-forward once you know how it works:</p>
<blockquote class="code">
<pre>
#object {

   /*
    * These border widths must match the border-image numbers.
    */
    border-width: 23px 22px 22px 26px;

   /*
    * Note that all browsers use their respective vendor prefix.  Also note
    * that, unlike the border-width values, the widths in the border-image
    * property don't have the 'px' unit at the end.
    */
   -moz-border-image:    url('image.png') 23 22 22 26 round round;
   -webkit-border-image: url('image.png') 23 22 22 26 round round;
   -o-border-image:      url('image.png') 23 22 22 26 round round;
   border-image:         url('image.png') 23 22 22 26 round round;

   /*
    * You should include a border-color and border-style as a fallback for
    * browsers that don't support border-image
    */
    border-color: #cccccc;
    border-style: solid;
 }
</pre>
</blockquote>
<div class="centered">
The original image looks like this:<br />
<img src="/border-image/images/borders/chain.png" alt="image of a chain" /><br />
It is an edited version of an image produced by <a href="http://www.free-printable-borders.com/">Free Printable Borders</a>.
</div>
</div>
<p>Note that the image repeats to the size of the block it borders.  When you design a <code>border-image</code>, the border should tile in a similar way that a <code>background-image</code> does.  There are some major differences though, so let&#8217;s show in depth how <code>border-image</code> is used, and introduce you to the tool that will help even the laziest developer in the world (i.e. me) create them quickly.</p>
<h2>Basic Syntax</h2>
<p>Note that the basic CSS is quite easy if you know how <code>border-width</code> works:</p>
<blockquote class="code">
<pre>
#selector {

  border-width: <em>&lt;top-width&gt;</em>px <em>&lt;right-width&gt;</em>px <em>&lt;bottom-width&gt;</em>px <em>&lt;left-width&gt;</em>px;

  border-image: url(<em>&lt;image-url&gt;</em>) <em>&lt;top-width&gt;</em> <em>&lt;right-width&gt;</em> <em>&lt;bottom-width&gt;</em> <em>&lt;left-width&gt;</em> 
                <em>&lt;horizontal-effect&gt;</em> <em>&lt;vertical-effect&gt;</em>;

}
</pre>
</blockquote>
<p>Note that if you are measuring your widths in pixels, then you must put the <code>px</code> unit inside the <code>border-width</code> declaration, but you must leave it out in the <code>border-image</code> one.  I know it doesn&#8217;t seem logical, but it&#8217;s just the way it is.</p>
<p>To illustrate the all of the <code>border-image</code> parameters, let&#8217;s take this image:</p>
<div class="centered">
<img src="/border-image/images/borders/border.png" alt="image of a border" />
</div>
<p>First we must grab the border widths in the right order:</p>
<p><div id="attachment_2568" class="wp-caption aligncenter" style="width: 396px"><a href="http://www.useragentman.com/blog/wp-content/uploads/2011/03/diagram.png"><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/03/diagram.png" alt="A diagram showing how the borders widths are ordered." title="diagram" width="386" height="198" class="size-full wp-image-2568" /></a><p class="wp-caption-text">A diagram showing how the borders widths are ordered.</p></div></p>
<p>(Note that the order of the <code>border-image</code> widths is consistent with the order that <code>margin</code> and <code>padding</code> uses).  </p>
<p>Now, let us apply effects on our image.</p>
<table class="dataTable">
<thead>
<tr>
<th>Pure CSS Example (will be visible if your browser supports <code>border-image</code></th>
<th>Firefox Screenshot (Opera and Webkit are similar, except for the <code>round</code> effect, which Chrome and Safari currently don&#8217;t support.)</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div id="stretchExample" class="example2">
This is an example of a stretched border.  Note that the square in the corner remains intact, while the other squares are the ones that stretch.
</div>
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/03/stretch.png" alt="Screenshot of border-image with stretch effect." title="stretch" class="alignnone size-full wp-image-2600" />
</td>
</tr>
<tr>
<td>
<div id="repeatExample" class="example2">
This is an example of a repeated border.   You&#8217;ll note that the browser will apply symmetry  on the border, so that it looks &#8220;balanced&#8221;.
</div>
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/03/repeat.png" alt="Screenshot of border-image with repeat effect." title="repeat" class="alignnone size-full wp-image-2600" /></p>
</td>
</tr>
<tr>
<td>
<div id="roundExample" class="example2">
This is an  example of a rounded border.  In this example, the browser tries to &#8220;round&#8221; the widths and lengths of the squares so they are not abruptly cut off.  <strong>Currently, this property is only supported by Firefox and Opera.</strong>
</div>
</td>
<td>
<img src="http://www.useragentman.com/blog/wp-content/uploads/2011/03/round.png" alt="Screenshot of border-image with round effect." title="round" class="alignnone size-full wp-image-2600" />
</td>
</tr>
</tbody>
</table>
<h2>But I <em>Hate</em> Counting Pixels!</h2>
<p>If you are the laziest developer in the world (i.e. me), you don&#8217;t want to crack open your graphics editor, open up a image file and count the pixels by hand &#8211; you want a tool that will generate the CSS for you.  After all, don&#8217;t we use computers so that they will do things for us?  At least, <a href="http://www.youtube.com/watch?v=bBBw9E2Q_aY">until they take over the world?</a></p>
<p>I was in the middle of creating my own tool, but I noticed that  <a href="http://www.incaseofstairs.com/">Kevin Decker</a> beat me to it with his excellent <a href="http://www.border-image.com/">Border Image Generator</a>.  You can take any image, from the web or your desktop, drag a few sliders around, and <em>voil&aacute;!</em>, you have your code, vendor-prefixes and all. You should definitely check it out if you are as lazy as I am.</p>
<h2>Percentage Widths</h2>
<p>The <code>border-image</code> property can also take percentage values, which correspond to the image&#8217;s width in height.  For example, let&#8217;s take this 81&#215;81 image:</p>
<div class="centered">
<img src="/border-image/images/borders/chain.png" alt="image of a border" />
</div>
<p>As you recall, we used the following pixel dimensions:</p>
<blockquote class="code">
<pre>
border-image: url('/border-image/images/borders/chain.png') 23 22 22 26 round;
</pre>
</blockquote>
<p>If you wanted to convert the pixel widths to percentages, you must take each value and divide it by either the entire width of the <code>border-image</code> (for the left and right widths) or by the height of the <code>border-image</code> (for the top and bottom widths).  In the above case:</p>
<ul>
<li>The top border width percentage = (top border width in pixels) / (<code>border-image</code> height) = 23 / 81 = 0.283&#8230; = 28%</li>
<li>The right border width percentage = (right border width in pixels) / (<code>border-image</code> width) = 22 / 81 = 0.271&#8230; = 27%</li>
<li>The bottom border width percentage = (bottom border width in pixels) / (<code>border-image</code> height) = 22 / 81 = 0.271 = 27%</li>
<li>The left border width percentage = (left border width in pixels) / (<code>border-image</code> width) = 26 / 81 = 0.320 = 32%</li>
</ul>
<p>Note that these percentages can only be used in the <code>border-image</code> property.  The <code>border-width</code> property must continue to use the pixel values:</p>
<div id="percentageExample">
This is the CSS used to generate this:</p>
<blockquote class="code">
<pre>
   /*
    * These border widths must match the border-image numbers
    */
    border-width: 23px 22px 22px 26px;
 	border-color: black;
   /*
    * Note that all browsers use their respective vendor prefix.
    */
   -moz-border-image:    url('chain.png') 28% 27% 27% 32% round;
   -webkit-border-image: url('chain.png') 28% 27% 27% 32% round;
   -o-border-image:      url('chain.png') 28% 27% 27% 32% round;
   border-image:         url('chain.png') 28% 27% 27% 32% round;
</pre>
</blockquote>
</div>
<p>Now, why on earth would you want to use percentages, since pixels are probably more accurate?  I don&#8217;t see there being any need for bitmap images, but <strong>Webkit browsers (i.e. Safari and Chrome) can use SVG vector images as a <code>border-image</code> as well</strong>.  Since SVG images are resolution independent, I would assume it is more accurate to use percentages.  It would be worth looking into percentage widths more when SVG border-image support reaches critical mass, since the other browser manufacturers may handle SVG support differently than Webkit.</p>
<h2>Degrading Gracefully and Progressive Enhancement</h2>
<p>It is important that developers ensure their designs degrade gracefully so that pages not only <strong>look decent in browsers that don&#8217;t support <code>border-image</code></strong>, but also look nice when a compliant browser is loading the images, especially <strong>when loading a high-bandwidth page or a page on a slow connection</strong>.  Not only should you ensure the <code>border-color</code> and <code>border-style</code> are set, but it is a good idea to ensure that the look of the fallback border is as close as possible to border-image as possible.  Let&#8217;s take a look at the &#8220;framed border&#8221; we used at the top of this page:</p>
<table class="dataTable">
<thead>
<tr>
<th>Firefox</th>
<th>IE9</th>
</thead>
<tbody>
<td><div id="attachment_2634" class="wp-caption alignnone" style="width: 365px"><a href="http://www.useragentman.com/blog/wp-content/uploads/2011/03/firefoxFallback.png"><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/03/firefoxFallback.png" alt="Screenshot of how the border-image example at the top of the page looks in Firefox." title="Screenshot of how the border-image example at the top of the page looks in Firefox." width="355" height="284" class="size-full wp-image-2634" /></a><p class="wp-caption-text">Screenshot of how the border-image example at the top of the page looks in Firefox.</p></div></td>
<td><div id="attachment_2633" class="wp-caption alignnone" style="width: 372px"><a href="http://www.useragentman.com/blog/wp-content/uploads/2011/03/IEfallback.png"><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/03/IEfallback.png" alt="Screenshot of how the border-image example &#039;falls back&#039; in IE9." title="Screenshot of how the border-image example &#039;falls back&#039; in IE9." width="362" height="291" class="size-full wp-image-2633" /></a><p class="wp-caption-text">Screenshot of how the border-image example 'falls back' in IE9 using the ridge border-style.</p></div></td>
</tbody>
</table>
<p>You can also be fancy and use <a href="http://www.modernizr.com">modernizr</a> to do some extra progressive enhancement styling by using the <br /><code>html.no-borderimage</code> selector.  I have done this using the comments section of my blog posts.</p>
<table class="dataTable">
<thead>
<tr>
<th>Firefox</th>
<th>IE9</th>
</thead>
<tbody>
<td><div id="attachment_2639" class="wp-caption alignnone" style="width: 310px"><a href="http://www.useragentman.com/blog/wp-content/uploads/2011/03/firefoxBalloon.png"><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/03/firefoxBalloon-300x106.png" alt="Screen shot of comment on my blog using the balloon border-image in firefox." title="Screen shot of comment on my blog using the balloon border-image in firefox (Click to see full screenshot)." width="300" height="106" class="size-medium wp-image-2639" /></a><p class="wp-caption-text">Screen shot of comment on my blog using the balloon border-image in firefox (Click to see full screenshot).</p></div></td>
<td><div id="attachment_2638" class="wp-caption alignnone" style="width: 310px"><a href="http://www.useragentman.com/blog/wp-content/uploads/2011/03/ieBalloonFallback.png"><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/03/ieBalloonFallback-300x66.png" alt="Screen shot of the same comment using modernizr to style the comment differently on browsers that don&#039;t support border-image (Click to see full screenshot)." title="Screen shot of the same comment using modernizr to style the comment differently on browsers that don&#039;t support border-image (Click to see full screenshot)." width="300" height="66" class="size-medium wp-image-2638" /></a><p class="wp-caption-text">Screen shot of the same comment using modernizr to style the comment differently on browsers that don't support border-image (Click to see full screenshot).</p></div></td>
</tbody>
</table>
<h2>Using With Background Images</h2>
<p>If you are using a <code>border-image</code> without a transparent colour or alpha channel, the center of your <code>border-image</code> will hide any <code>background-image</code> the object may have.  If you want to have a separate <code>background-image</code>, you must &#8220;cut-out&#8221; the middle of the <code>border-image</code> using your graphics editor with a transparent colour.  For instance, the example at the top of the page with the picture frame <code>border-image</code> has a photo of clouds as a <code>background-image</code>.   This allows developers to create more graphically rich block-level elements.</p>
<h2>Hey! What about IE?</h2>
<p>Unfortunately, IE doesn&#8217;t support <code>border-image</code> natively.  <strong>I <em>may</em> have a workaround for this using cssSandpaper</strong>, but it needs a lot more testing to see if it is a truly viable polyfill for this effect.  If I am successful,  I will post whether that solution as an addendum to this blog post.</p>
<h2>Conclusion</h2>
<p><code>border-image</code> can be used today to make some very interesting effects that can be degraded gracefully in browsers that don&#8217;t support it.  It can speed up design time considerably since you don&#8217;t have to use your graphics editor to cut up images.  And I&#8217;m sure it will waste a lot of your time while you play and see how it can be used effectively.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.useragentman.com/blog/2011/03/29/pixel-perfect-css3-border-image-in-depth/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Converting @font-face Fonts Quickly In Any OS</title>
		<link>http://www.useragentman.com/blog/2011/02/20/converting-font-face-fonts-quickly-in-any-os/</link>
		<comments>http://www.useragentman.com/blog/2011/02/20/converting-font-face-fonts-quickly-in-any-os/#comments</comments>
		<pubDate>Sun, 20 Feb 2011 22:00:00 +0000</pubDate>
		<dc:creator>zoltan</dc:creator>
				<category><![CDATA[@font-face]]></category>
		<category><![CDATA[converting]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[Cygwin]]></category>
		<category><![CDATA[FontForge]]></category>
		<category><![CDATA[Fonts]]></category>

		<guid isPermaLink="false">http://www.useragentman.com/blog/?p=2275</guid>
		<description><![CDATA[<img src="/blog/wp-content/uploads/2011/02/fontConvertSmall.jpg" /> I love experimenting with web fonts, but using the hodgepodge of free and open source desktop tools to convert them manually is time consuming. This inspired me to write a command line tool that would convert them all at once and create the CSS code like <a href="http://www.fontsquirrel.com/">Font Squirrel's generator</a>.  The result is a <a href="http://en.wikipedia.org/wiki/Shell_script">shell script</a> that uses <a href="http://fontforge.sourceforge.net/">FontForge</a>, <a href="http://xmlgraphics.apache.org/batik/">Batik</a> and <a href="http://readableweb.com/">Readable Web's</a> <a href="http://eotfast.com/">EOTFast</a> to do the heavy lifting.]]></description>
			<content:encoded><![CDATA[<p><div id="attachment_2315" class="wp-caption alignleft" style="width: 260px"><a href="http://www.useragentman.com/blog/wp-content/uploads/2011/02/fontConvert.jpg"><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/02/fontConvert.jpg" alt="" title="fontConvert" width="250" height="307" class="size-full wp-image-2315" /></a><p class="wp-caption-text">Converting fonts quickly will help speed up production of your projects and can easily integrate into your workflow.</p></div></p>
<p>I love experimenting with web fonts, but using the hodgepodge of free and open source desktop tools to convert them manually is time consuming.  To speed things up a bit, <a href="http://www.fontsquirrel.com/">Font Squirrel</a> created the excellent <a href="http://www.fontsquirrel.com/fontface/generator">@Font-Face Generator</a> web application which not only generates the fonts for you, but also creates a stylesheet a developer can import and use the font immediately.  I really like this tool and it inspired me to write <strong>a command line tool that would create a package like Font Squirrel&#8217;s generator,</strong>  The result is a <a href="http://en.wikipedia.org/wiki/Shell_script">shell script</a> that uses <a href="http://fontforge.sourceforge.net/">FontForge</a>, <a href="http://xmlgraphics.apache.org/batik/">Batik</a> and <a href="http://readableweb.com/">Readable Web&#8217;s</a> <a href="http://eotfast.com/">EOTFast</a> to do the heavy lifting.  It was originally developed under Windows using <a href="http://www.cygwin.com">Cygwin</a>, but I spent a bit of extra time to ensure that it can run under Linux and Mac OS X (using <a href="http://code.google.com/p/ttf2eot/">ttf2eot</a> instead of the Windows-only EOTFast to generate the <code>.eot</code> fonts).  Since it runs on OS X, it should run under BSD flavours of Unix as well, but I haven&#8217;t confirmed this (I would be grateful to hear from any BSD users on how it works).</p>
<p>This tool is not intended to replace Font Squirrel&#8217;s tool (as a matter of fact, their tool has a few more options than mine).  However, I find it useful when trying out a variety of fonts on my local web server, so I thought I&#8217;d share.  </p>
<p><strong>If you&#8217;re not familiar with the command line</strong> on your particular operating system, this may not be the solution for you. I will, however, give step-by-step instructions on how to install and run the shell script. <strong> If you stumble into any problems</strong>, and especially if <strong>you find any inaccuracies</strong> with the instructions here, please post a comment below and I will try my best to address them.  I find this script quite useful and would love to help the rest of The Community&trade; as much I can if they would like to use it as well.</p>
<p><a href="https://github.com/zoltan-dulac/css3FontConverter" class="exampleLink">Download the CSS3 Font Converter from GitHub</a></p>
<h2>Examples</h2>
<p>Before we start using the tool, I have included a few examples.  They are intended to show situations where a developer may not want to use fonts that are not included on your computer&#8217;s font-stack.</p>
<table class="dataTable">
<thead>
<tr>
<th>Argor Biw Scaqh/Old London</th>
<th>Peanuts</th>
<th>Aaaaight!!!!!</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="/tests/fontConverter/ArgBiwSc.html"><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/02/argor.png" alt="Screenshot of my Argor Biw Scaqh/Old London example" title="argor"  class="alignnone size-full wp-image-2321" /></a></p>
<p>Serif or Sans-serif? How about neither? This example makes heavy use of <a href="http://en.wikipedia.org/wiki/Blackletter">Black Letter</a> fonts, which are not included in most operating systems today.</p>
</td>
<td><a href="/tests/fontConverter/peanuts.html"><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/02/peanuts.png" alt="Screenshot of Peanuts font example." title="peanuts" class="alignnone size-full wp-image-2323" /></a></p>
<p>Why use <a href="http://www.bbc.co.uk/news/magazine-11582548">a font everybody seems to hate</a> when there are other cartoony fonts to choose from?</td>
<td><a href="/tests/fontConverter/aaaiight.html"><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/02/aaaaight.png" alt="Screenshot of Aaaaight!!!!! example page." title="aaaaight" class="alignnone size-full wp-image-2325" /></a></p>
<p>Grafitti style fonts have a unique look all their own.</p>
</td>
</tbody>
</table>
<p>In all cases, the original fonts were in True Type format. The font-converter then converted the fonts into all the other @font-face formats, and created a style sheet containing the appropriate @font-face rules that can be easily imported by the author.</p>
<h2>Usage</h2>
<p>You can convert as many <code>.ttf</code> or <code>.otf</code> fonts in a directory by using the following command:</p>
<blockquote class="code">
<pre>
convertFonts.sh &lt;filelist&gt;
</pre>
</blockquote>
<p>For example, if you wanted to convert all the <code>.ttf</code> files in the directory you are in, you could type in the command:</p>
<blockquote class="code">
<pre>
$ convertFonts.sh *.ttf
</pre>
</blockquote>
<p>The fonts will then be converted to the <code>.eot</code>, <code>.woff</code>, and <code>.svg</code> formats.  It will also generate a stylesheet, <code>stylesheet.css</code>, that will produce the <code>@font-face</code> rules using <a href="http://www.fontspring.com/blog/the-new-bulletproof-font-face-syntax">The New Bulletproof @Font-Face Syntax</a>.</p>
<p>If you are converting <code>.otf</code> fonts, a <code>.ttf</code> font will be generated first before the other fonts. </p>
<h2>Installation</h2>
<p>I have tried to make this tool as easy to use as possible.  If you follow these easy steps, it should work.  If you have trouble installing the tool after you have followed all these steps, please leave a comment at the end of this post &mdash; I really want to make this as bulletproof as possible.</p>
<ol>
<li><strong>If you are using Windows XP/Vista/7, install <a href="http://www.cygwin.com">Cygwin</a> with the FontForge package</strong>. If you have never done this before, <a href="http://www.useragentman.com/blog/?p=2339">I have created a supplementary blog post to walk you through the installation process</a>.  If you have installed Cygwin before, you still may want to read the last half of the article, since installing FontForge can be difficult under Cygwin (at least it was for me until I did some digging).</li>
<li><strong>Download and Install <a href="http://fontforge.sourceforge.net/">FontForge</a> </strong>(if you are a Windows user, this is covered in step one). There are complete instructions on how to do this under <a href="http://fontforge.sourceforge.net/mac-install.html">OS X</a>, and <a href="http://fontforge.sourceforge.net/nix-install.html">Linux</a> as well.  <strong>Update (May 14, 2011):</strong> The Linux page doesn&#8217;t mention this, but if you are an Ubuntu user, you can use <code>apt-get</code> to do the installation for you easily:<br />
<blockquote class="code">
<pre>
sudo apt-get install fontforge
</pre>
</blockquote>
<p>Thanks to Richard Curran for pointing this out.</li>
<li><strong>If you don&#8217;t have it already, <a href="http://www.java.com/en/download/manual.jsp">install Java</a></strong> (it is required for Batik). If you are not sure how to do this, there are installation instuctions available for <a href="http://www.java.com/en/download/help/windows_manual_download.xml">Windows</a>, <a href="http://developer.apple.com/java/faq/">OS X</a>, and <a href="http://www.clickonf5.org/linux/how-install-sun-java-ubuntu-1004-lts/7777">Ubuntu Linux</a>).</li>
<li><strong><a href="http://xmlgraphics.apache.org/batik/download.cgi">Download the latest version of Batik</a>.</strong>  Make sure you remember where you unpack the archive &mdash; you&#8217;ll need this later.</li>
<li><strong>Download <a href="http://eotfast.com/">EOTFast</a></strong> (if you develop using Windows) <strong>or  <a href="http://code.google.com/p/ttf2eot/">ttf2eot</a></strong> (for OS X and Linux, <a href="http://www.tips-tricks.net/tag/ttf2eot/">installation instructions are here</a>).  </li>
<li><strong>Download the <a href="http://people.mozilla.com/~jkew/woff/">sfnt2woff</a> package</strong> (this page has packages for Windows and OS X, as well as the source that one can compile for Linux).</li>
<li><strong>Download the <a href="/downloads/css3FontConverter.zip">CSS3 Font Converter</a></strong> and unpack the contents in your path someplace.</li>
<li><strong>Open up a terminal window</strong> (under Cygwin, that would be the either the &#8220;Cygwin Bash Shell&#8221;, or, better yet, &#8220;rxvt native&#8221; if you have that installed). Then, <code>cd</code> into the directory that you unpacked the CSS3 Font Converter, and edit <code>convertFonts.sh</code> (if you are using Windows, <strong>don&#8217;t use notepad to edit this file</strong>, since shell scripts don&#8217;t like to be saved as Windows text.  If you are familar with it, use <code>vim</code> instead).  You will need to edit the first few lines:<br />
<blockquote class="code">
<pre>
#!/bin/bash

#########################################################################
## CONFIGURATION AREA: This stuff is the only stuff you may need to     #
##                     change.                                          #
#########################################################################

# Linux and Mac users, this directory should be changed to be of this form:
# BATIK_DIR="/Users/webtest/src/batik".  Windows should use the form below.
<span class="hilite">BATIK_DIR='c:\Program Files\Batik\batik-1.7'</span>

# The path should contain the directories where EOTFAST-1.EXE, ttf2eot,
# fontforge, and all the scripts in the @Font-Face Contruction Set reside.
# Uncomment the line below with the right directories.  Remember the
# $PATH at the beginning of the string, or the script will forget what
# was originally in the PATH.
<span class="hilite"># PATH="$PATH:/some/directory:/some/other/directory/"</span>

....
</pre>
</blockquote>
<p>You have to change the value of <code>BATIK_DIR</code> to the directory that contains the Batik code (ensure that it includes the <code>batik-1.7</code> directory at the end). If you haven&#8217;t installed the other packages in directories in your PATH, you must uncomment the <code>PATH</code> line and edit it so that it contains them.
</li>
<li><strong>If all is well, you should now be ready to convert fonts.</strong>  To test, create a new directory, download and unpack the <a href="http://www.dafont.com/old-london.font">Old London Font from Dafont.com</a> into it, and execute the following command:<br />
<blockquote class="code">
<pre>
$ convertFonts.sh *.ttf
</pre>
</blockquote>
<p>If all is successful, you should see output similar to this:</p>
<blockquote class="code">
<pre>
Converting OldLondon to eot
(Using EOTFAST)
Converting font "Old London"
Successfully written "OldLondon.eot"
Converting OldLondon to svg
Converting OldLondon to woff
Converting OldLondonAlternate to eot
(Using EOTFAST)
Converting font "Old London Alternate"
Successfully written "OldLondonAlternate.eot"
Converting OldLondonAlternate to svg
Converting OldLondonAlternate to woff
Writing Stylesheet ...
Extracting SVG ID
Getting Font Name
Extracting SVG ID
Getting Font Name
DONE!
</pre>
</blockquote>
<p>Not only does it convert the TrueType font in all the web formats, it produces a nice style sheet you can<br />
link to:</p>
<blockquote class="code">
<pre>
@font-face {
        font-family: 'OldLondon';
        src: url('OldLondon.eot?') format('eot'),
             url('OldLondon.woff') format('woff'),
             url('OldLondon.ttf')  format('truetype'),
             url('OldLondon.svg#OldLondon') format('svg');
}

@font-face {
        font-family: 'OldLondonAlternate';
        src: url('OldLondonAlternate.eot?') format('eot'),
             url('OldLondonAlternate.woff') format('woff'),
             url('OldLondonAlternate.ttf')  format('truetype'),
             url('OldLondonAlternate.svg#OldLondonAlternate') format('svg');
}
</pre>
</blockquote>
</li>
</ol>
<h2>Notes</h2>
<ol>
<li><strong>FontForge can do way more than convert fonts.</strong>  It is primarily a <strong>font editor</strong>, and I have used it to add accents characters to fonts that don&#8217;t have them (a necessity if you are a Canadian web developer that occasionally has to work with French text).  Play around with it &#8211; it may become as important to you as your graphics editor and your IDE.</li>
<li><strong>The script will use EOTFast when possible</strong> to create the <code>.eot</code> fonts, and failing that, <strong>will use ttf2eot as a fallback</strong>. EOTFast is the preferred solution because it can compress the converted file, but since it only runs under Windows, ttf2eot is needed for the other operating systems.  Note that I have experienced a problem running EOTFast under my copy of Windows 7.  I am not sure if this happens on all Windows 7 installations and I would love to hear comments in this area. I have sent a bug report to the developer, but in the meantime, you can use the Windows version of ttf2eot instead.</li>
<li><strong>I used Batik instead of Fontforge to generate the SVG fonts</strong> because I couldn&#8217;t get the Fontforge SVG fonts to work.  I don&#8217;t know why (to be honest, I didn&#8217;t look into it that much).</li>
<li><strong>I did not build a GUI for this tool.</strong> If anyone wants to, please feel free.  I would love to hear about it if you do.</li>
<li><strong>The first time you run the script under Cygwin, you may get this warning:</strong><br />
<blockquote class="code">
<pre>cygwin warning:
  MS-DOS style path detected: c:\Program Files\Batik\batik-1.7/batik-ttf2svg.jar
  Preferred POSIX equivalent is: /cygdrive/c/Program Files/Batik/batik-1.7/batik-ttf2svg.jar
  CYGWIN environment variable option "nodosfilewarning" turns off this warning.
  Consult the user's guide for more details about POSIX paths:

http://cygwin.com/cygwin-ug-net/using.html#using-pathnames
</pre>
</blockquote>
<p>This error won&#8217;t affect how the script runs &#8211; it is just complaining about the way Java is running Batik.  Since Java needs an MS-DOS path, ignore the warning.</li>
<li>Before using the tool, <strong>make sure you back up files that you don&#8217;t want over-written.</strong>  I am not responsible for any loss of files because you used the tool incorrectly (or because of a bug in the tool itself).</li>
<li><strong>Before you convert any fonts with this tool, please ensure that you have the legal right to do so</strong> by reading the license that comes with the font.</li>
</ol>
<h2>Image Credit</h2>
<p>The image at the top of this post was remixed using works from <a href="http://www.flickr.com/photos/mclabigail/2749884683/">Abigail Elder</a>, <a href="http://www.flickr.com/photos/24oranges/5146148857/sizes/l/in/photostream/">24oranges.nl</a>, <a href="http://www.flickr.com/photos/robbie1/3148808883/sizes/o/in/photostream/">Robbie Sproule</a> and <a href="http://www.flickr.com/photos/evilpeach/107445325/sizes/o/in/photostream/">Lisa Brank</a>.</p>
<p><a href="https://github.com/zoltan-dulac/css3FontConverter" class="exampleLink">Download the CSS3 Font Converter from GitHub</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.useragentman.com/blog/2011/02/20/converting-font-face-fonts-quickly-in-any-os/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>The CSS3 matrix() Transform for the Mathematically Challenged</title>
		<link>http://www.useragentman.com/blog/2011/01/07/css3-matrix-transform-for-the-mathematically-challenged/</link>
		<comments>http://www.useragentman.com/blog/2011/01/07/css3-matrix-transform-for-the-mathematically-challenged/#comments</comments>
		<pubDate>Fri, 07 Jan 2011 05:49:57 +0000</pubDate>
		<dc:creator>zoltan</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[Drag and Drop]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[transform]]></category>

		<guid isPermaLink="false">http://www.useragentman.com/blog/?p=2159</guid>
		<description><![CDATA[<img src="/blog/wp-content/uploads/2011/01/xx2.png" /> The CSS3 <code>transform</code> property can do some really cool things - with it, web designers can rotate, scale, skew and flip objects quite easily.  However, in order for designers to have <strong>fine-grained, pixel level control over their transforms</strong>, the <strong><code>matrix()</code> function</strong> is hard to beat.  This post explains what it does and the math behind the code.  It also includes a tool to help you create <code>matrix()</code> transforms easily using <a href="/blog/2010/01/10/cross-browser-html5-drag-and-drop/">HTML5 Drag and Drop</a> for the user interface and the <a href="http://sylvester.jcoglan.com/">Sylvester JavaScript library</a> to do the mathematics needed to calculate the matrix values so you don't have to (in case you have difficulties with math, or if you just are lazy and don't want to be bothered). 
<br /><br />]]></description>
			<content:encoded><![CDATA[


<div class="importantNotes">
<h3>Notes:</h3>
<ul>
<li><strong>This article was not rendering correctly in Firefox 4.x due to a change in how that browser handles MathML.</strong>  This issue has now been fixed as of May 1, 2011.</li>
<li>If you are not familar with 2D-Transforms, take a look at my other article <cite><a href="http://www.useragentman.com/blog/2010/03/09/cross-browser-css-transforms-even-in-ie/">Cross Browser CSS Transforms – even in IE</a></cite></li>
</ul>
</div>


<div  class="wp-caption alignright" style="width: 419px;"><a href="/matrix"><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/01/matrixConstructionSetScreenshot.png" alt="Screenshot of the Matrix Construction Set" title="matrixConstructionSetScreenshot"  class="size-full wp-image-2055" /></a>
<p class="wp-caption-text"><a href="/matrix">The Matrix Construction Set</a> allows you to make a pixel perfect transformation by just dragging and dropping objects around.</p>
</div>


<p>The CSS3 <code>transform</code> property can do some really cool things - with it, web designers can rotate, scale, skew and flip objects quite easily.  However, in order for deisgners to have <strong>fine-grained, pixel level control over their transforms</strong>, it would be really helpful to understand how the <strong><code>matrix()</code> function</strong> works.  With the <code>matrix()</code> function, designers can position and shape their transformations exactly where they want to.</p>

<p>The problem is, <strong>not many people actually understand what the numbers in the matrix filter actually mean</strong>.  To solve this issue, I have created a tool, which I call the <a href="/matrix/">CSS3 Matrix Construction Set</a> that can take any block-element, positioned anywhere on the page, transform it anywhere else on the page using the <code>matrix()</code> filter, and reveal the correct CSS code for this operation.  <a href="/matrix/">Look at the tool now</a> and if that is all you are interested in, you can stop there.  However, <strong>if you what to know what the numbers in the <code>matrix()</code> function actually mean</strong>, and why you want such knowledge in the first place, read on.  I'll try to explain this as simply as possible (and please feel free to use the feedback form if you have any opinions on how to make this article better).</p>

<a class="exampleLink" href="/matrix/">Take a Look at the CSS3 Matrix Construction Set</a>

<div class="importantNotes">
<p><strong>Note:</strong> This tool works in all modern versions of Firefox, Sarari and Chrome.  Although it is not usable in Opera (due to its lack of support for <a href="http://www.useragentman.com/blog/2010/01/10/cross-browser-html5-drag-and-drop/">HTML5 drag and drop</a>) the CSS code it produces in other browsers <strong>is</strong> usable in that browser.  The tool also does not work in IE since neither that browser, nor my CSS3 polyfill library, <a href="http://www.useragentman.com/blog/csssandpaper-a-css3-javascript-library/">cssSandpaper</a>, support the <code>transform-origin</code> property.  I hope to fix cssSandpaper to implement this in a future release, but in the meantime, please read the note at the end of this article for a workaround for this issue.</p>
</div>

<h2>Matrices: Why Should I Care?</h2>

<p>Matrices are to transforms like RGB hex codes are to colors: they are representations that are easy for computers to understand, but not human beings.  Sure, web designers can use the <code>rotate()</code>, <code>skew()</code>, <code>scale()</code> and <code>translate()</code> functions to fulfill their transformation needs ... why should we bother with <code>matrix()</code> at all?  There are a few cases when you may want to:</p>

<dl>
     <dt>Brevity:</dt>
     <dd>Using matrices, it is possible to represent a complex string of 2D transforms like this:

<blockquote class="code">
<pre>
#object {
    transform-origin: 0 0;
    transform: rotate(15deg) translateX(230px)  scale(1.5, 2.6) skew(220deg, -150deg) translateX(230px)
}
</pre>
</blockquote>

using one <code>matrix()</code> rule like this:

<blockquote class="code">
<pre>
#object {
    transform-origin: 0 0;
    transform: matrix(1.06, 1.84, 0.54, 2.8, 466px, 482px)
}
</pre>
</blockquote>

<p>(<strong>Note:</strong> I have ignored the vendor-specific variants (e.g. <code>moz-transform</code>, etc.) for the sake of brevity).</p>

</dd>
     <dt>Pixel-Perfection:</dt>
     <dd>If you know exactly how you want your transformation to look, it'll take a bit of fiddling around to get it to look how you want using the other transform functions, and it may not be pixel perfect if you lack patience (like I do).  However, using a tool like the Matrix Construction Set, you can place the transform exactly where you want (This is analogous to using a color wheel to choose RGB colors for you, instead of using keywords like <code>red</code>, <code>green</code> or <code><a href="http://www.colordic.org/colorsample/1019.html">peachpuff</a></code>).</dd>

     <dt>JavaScript:</dt>
     <dd>Revealing an object's transform information using JavaScript's <code>getComputedStyle()</code> function will yield a <code>matrix()</code> function in all current web browsers that support CSS3 transforms, <strong>even if it was rendered using other transform functions like <code>rotate()</code></strong>.  For example, the object below has been rotated 45&deg; using <code>transform: rotate(45deg)</code>:


<div class="exampleBackground">
<div id="exampleRotation">
This object has been rotated 45&deg;
</div>
</div>

But <a href="#" onclick="
  if (!window.getComputedStyle) {
     alert('This browser does not support getComputedStyle()');
     return false;
  }
  var props = ['MozTransform', 'WebkitTransform', 'OTransform', 'MSTransform', 'transform'];
  var compStyle = window.getComputedStyle(document.getElementById('exampleRotation'), null);
  for (var i=0; i<props.length; i++) {

    var style = compStyle[props[i]];
    if (style != null) {
       alert('Calling getComputedStyle() on the rotated element gives: ' + style);
       return false;
    }
  }
  alert('This browser doesn\'t support CSS3 Transforms');
    return false;">this link, which shows the object's computed style</a> will reveal that internally it stores a <code>matrix()</code> function.</dd>
</dl>


<h2>Ok, What Does The Markup Look Like?</h2>

<p>The <code>matrix()</code> function takes 6 parameters in order for it to work:</p>
 
<blockquote class="code">
<pre>
#transformedObject {
     -moz-transform:    matrix(1.4488, -0.3882, 0.3882, 1.4489, 400px, -100px);
     -webkit-transform: matrix(1.4488, -0.3882, 0.3882, 1.4489, 400, -100);
     -o-transform:      matrix(1.4488, -0.3882, 0.3882, 1.4489, 400, -100);
     transform:         matrix(1.4488, -0.3882, 0.3882, 1.4489, 400, -100);
}
</pre>
</blockquote>

<p><strong>Note the difference with the Firefox implementation of <code>matrix()</code></strong> &mdash; the last two elements need the <code>px</code> units after it.  For now, think of it is a difference in notation, but we'll explain why this is later.</p>


<h2>But What Do The Numbers Mean?</h2>
 
<p>In order to explain what they mean, I will have to define a few math-concepts here.  <strong>Don't panic if you are mathematically challenged</strong>.  These concepts are not that hard to understand, but there is a bit of explanation needed.  Why should you torture yourself if you hate math?</p>

<dl>
<dt>If you are a designer:</dt>
<dd>Think of the stuff below as informational.  If you use the Matrix Construction Set <strong>you won't need to calculate anything by hand</strong> (but wouldn't you want to have an idea what the numbers mean anyway?)</dd>
<dt>If you are a JavaScript developer:</dt>
<dd><em>This information will be invaluable when optimizing scripts that rely on transformation effects.</em>  Just try to understand the basic concepts here, and if you still need help, use the <a href="http://sylvester.jcoglan.com/">Sylvester JavaScript library</a> to do the heavy lifting for you.</dd>
<dt>If you want to be an &uuml;ber-geek:</dt>
<dd>All those matrix jokes you hear at parties will suddenly start to make sense!</dd>
</dl>

<div class="wp-caption aligncenter" >
<a href="http://xkcd.com/184/"><img src="http://www.useragentman.com/blog/wp-content/uploads/2011/01/matrix_transform.png" alt="In fact, draw all your rotational matrices sideways. Your professors will love it! And then they&#039;ll go home and shrink." title="In fact, draw all your rotational matrices sideways. Your professors will love it! And then they&#039;ll go home and shrink." width="400" height="152" class="aligncenter size-full wp-image-2186" /></a>
<p class="wp-caption-text">Finally you'll be able to understand why all the geeks at work find <a href="http://xkcd.com/184/">this XKCD comic</a> so funny.</p>
</div>


<h2>Terminology</h2>

<h3>Matrix</h3>

<p>The easiest way to think of a matrix is as a group of numbers written in a rectangle or square.  For our purposes, we will be dealing with 3x3 matrices, such as this one below:</p>

<div class="equation">
	<math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>1</mn> </mtd>
		      <mtd> <mn>3</mn> </mtd>
		      <mtd> <mn>5</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>2</mn> </mtd>
		      <mtd> <mn>4</mn> </mtd>
		      <mtd> <mn>6</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow>
	</math>
</div>

<p>That's nine numbers!  So how come the CSS3 <code>matrix()</code> function only has six?</p>

<blockquote class="code">
<pre>
#transformedObject {
     transform:  matrix(1, 2, 3, 4, 5, 6);
}
</pre>
</blockquote>

For CSS3 2D transforms, we only deal with 3x3 matrices that have the <strong>two bottom-left numbers that are equal to zero, and the bottom-right value equal to 1</strong>. As a result, these two notations are equal:

<div class="equation">
<code>matrix(1, 2, 3, 4, 5, 6) = </code>
	<math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>1</mn> </mtd>
		      <mtd> <mn>3</mn> </mtd>
		      <mtd> <mn>5</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>2</mn> </mtd>
		      <mtd> <mn>4</mn> </mtd>
		      <mtd> <mn>6</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow>
	</math>
</div>


<h3>Dot Product</h3>

<p>Next we are going to explain what a <strong>dot product</strong> is.  At first, this may not seem like this is related to matrices at all, but I promise it does ... just read on and you'll understand why in no time.  Trust me. :-)</p>

<p>Let's say you have two (x, y) points,


	<math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>1</mn> </mtd>
		      <mtd> <mn>2</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
	  </mrow>
	</math>
	and
	<math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>4</mn> </mtd>
		      <mtd> <mn>5</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
	  </mrow>
	</math>.  The dot product of these two points (written <math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>1</mn> </mtd>
		      <mtd> <mn>2</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
	  </mrow>
	</math>
	&middot;
	<math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>4</mn> </mtd>
		      <mtd> <mn>5</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
	  </mrow>
	</math>) is what you get when you multiply the two x-coordinates, multiply the two y-coordinates, and then add them together:</p>

<div class="equation">
    <math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn >1</mn> </mtd>
		      <mtd> <mn>2</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
	          <mo>&middot;</mo>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>4</mn> </mtd>
		      <mtd> <mn>5</mn> </mtd>
		    </mtr>
		  </mtable>
                  <mo> ) </mo>
          </mrow> </math>
	         = 1x4 + 2x5 = 4 + 10 = 14
</div>

This doesn't only work for 2-dimensional coordinates, but also in 3-dimensions and higher:

<div class="equation">
    <math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>1</mn> </mtd>
		      <mtd> <mn>2</mn> </mtd>
                      <mtd> <mn>3</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
	  </mrow>
	</math>
	&middot;
	<math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>4</mn> </mtd>
		      <mtd> <mn>5</mn> </mtd>
                      <mtd> <mn>6</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
	  </mrow>
	</math> = 1x4 + 2x5  + 3x6 = 4 + 10 + 18  = 32
<br /><br />
    <math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>1</mn> </mtd>
		      <mtd> <mn>2</mn> </mtd>
                      <mtd> <mn>3</mn> </mtd>
                      <mtd> <mn>10</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
	  </mrow>
	</math>
	&middot;
	<math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>4</mn> </mtd>
		      <mtd> <mn>5</mn> </mtd>
                      <mtd> <mn>6</mn> </mtd>
                      <mtd> <mn>20</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
	  </mrow>
	</math> = 1x4 + 2x5  + 3x6 + 10x20 = 4 + 10 + 18 + 200 = 232
</div>

<p>Got it?  It's pretty simple, right?  Note that when we write (x, y) co-ordinates like <math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>x</mn> </mtd>
		      <mtd> <mn>y</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
	  </mrow>
	</math>, we call <math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>x</mn> </mtd>
		      <mtd> <mn>y</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
	  </mrow>
	</math> a <strong>vector</strong>.  Vector notation can be written horizontally, (e.g. <math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>x</mn> </mtd>
		      <mtd> <mn>y</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
	  </mrow>
	</math>) or vertically (e.g. <math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>x</mn> </mtd>
		      
		    </mtr>
                    <mtr>
                       <mtd> <mn>y</mn> </mtd>
                    </mtr>
		  </mtable>
		  <mo> ) </mo>
	  </mrow>
	</math>).  <strong>When using them in 2D transforms, we always add an extra co-ordinate with a number 1 at the end.</strong>  So (20, 90) would be written 
<math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>20</mn> </mtd>
		      <mtd> <mn>90</mn> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
	  </mrow>
	</math> or like <math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>20</mn> </mtd>
		      
		    </mtr>
                    <mtr>
                       <mtd> <mn>90</mn> </mtd>
                    </mtr>
                    <mtr>
                       <mtd> <mn>1</mn> </mtd>
                    </mtr>
		  </mtable>
		  <mo> ) </mo>
	  </mrow>
	</math> in vector notation.

<h3>Multiplicatying a Matrix with a Vector</h3>

<p>So, what does the dot product have to do with matrices?  Well the idea of the dot product can also be extended to matrices.  Let's say you need to multiply the following together: </p>

<div class="equation">
	<math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr color="#ff0000" fontweight="bold">
		      <mtd mathbackground="#ffcccc"> <mn>1</mn> </mtd>
		      <mtd mathbackground="#ffcccc"> <mn>3</mn> </mtd>
		      <mtd mathbackground="#ffcccc"> <mn>4</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>2</mn> </mtd>
		      <mtd> <mn>4</mn> </mtd>
		      <mtd> <mn>5</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow>
	</math>
	&middot;
	<math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>20</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>30</mn> </mtd>  
		    </mtr>
		    <mtr>
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math> 
</div>

To do this, you need to produce the dot product of each of the matrix's rows with the vector like this:

<div class="equation">
	<math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr color="#ff0000" fontweight="bold">
		      <mtd mathbackground="#ffcccc"> <mn>1</mn> </mtd>
		      <mtd mathbackground="#ffcccc"> <mn>3</mn> </mtd>
		      <mtd mathbackground="#ffcccc"> <mn>4</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>2</mn> </mtd>
		      <mtd> <mn>4</mn> </mtd>
		      <mtd> <mn>5</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow>
	</math>
	&middot;
	<math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>20</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>30</mn> </mtd>  
		    </mtr>
		    <mtr>
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math> =  <math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>1</mn><mo>&#215;</mo><mn>20</mn> <mo>+</mo> <mn>3</mn><mo>&#215;</mo><mn>30</mn> <mo>+</mo> <mn>4</mn><mo>&#215;</mo><mn>1</mn> </mtd>
		     
		    </mtr>
		    <mtr>
		      <mtd> <mn>.</mn> </mtd>
		      
		    </mtr>
		    <mtr>
		      <mtd> <mn>.</mn> </mtd>
		      
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math> 
        = 
 <math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>20</mn><mo>+</mo><mn>90</mn><mo>+</mo><mn>4</mn> </mtd>
		     
		    </mtr>
		    <mtr>
		      <mtd> <mn>.</mn> </mtd>
		      
		    </mtr>
		    <mtr>
		      <mtd> <mn>.</mn> </mtd>
		      
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math> = <math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn> 114</mn> </mtd>
		     
		    </mtr>
		    <mtr>
		      <mtd> <mn>.</mn> </mtd>
		      
		    </mtr>
		    <mtr>
		      <mtd> <mn>.</mn> </mtd>
		      
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math>

</div>

<div class="equation">
    <math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>1</mn> </mtd>
		      <mtd> <mn>3</mn> </mtd>
		      <mtd> <mn>4</mn> </mtd>
		    </mtr>
		    <mtr  color="#ff0000" fontweight="bold">
		      <mtd  mathbackground="#ffcccc"> <mn>2</mn> </mtd>
		      <mtd  mathbackground="#ffcccc"> <mn>4</mn> </mtd>
		      <mtd  mathbackground="#ffcccc"> <mn>5</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow>
	</math>
	&middot;
	<math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>20</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>30</mn> </mtd>  
		    </mtr>
		    <mtr>
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math> =  <math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd > <mn>115</mn> </mtd>
		     
		    </mtr>
		    <mtr>
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>2</mn><mo>&#215;</mo><mn>20</mn> <mo>+</mo> <mn>4</mn><mo>&#215;</mo><mn>30</mn> <mo>+</mo> <mn>5</mn><mo>&#215;</mo><mn>1</mn> </mtd>
		      
		    </mtr>
		    <mtr>
		      <mtd> <mn>.</mn> </mtd>
		      
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math> = <math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd > <mn>115</mn> </mtd>
		     
		    </mtr>
		    <mtr>
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>40</mn> <mo>+</mo> <mn>120</mn> <mo>+</mo> <mn>5</mn> </mtd>
		      
		    </mtr>
		    <mtr>
		      <mtd> <mn>.</mn> </mtd>
		      
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math> = <math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd > <mn>115</mn> </mtd>
		     
		    </mtr>
		    <mtr>
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>165</mn> </mtd>
		      
		    </mtr>
		    <mtr>
		      <mtd> <mn>.</mn> </mtd>
		      
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math> 
</div>


<div class="equation">
    <math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>1</mn> </mtd>
		      <mtd> <mn>3</mn> </mtd>
		      <mtd> <mn>4</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>2</mn> </mtd>
		      <mtd> <mn>4</mn> </mtd>
		      <mtd> <mn>5</mn> </mtd>
		    </mtr>
		    <mtr   color="#ff0000" fontweight="bold">
		      <mtd  mathbackground="#ffcccc"> <mn>0</mn> </mtd>
		      <mtd  mathbackground="#ffcccc"> <mn>0</mn> </mtd>
		      <mtd  mathbackground="#ffcccc"> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow>
	</math>
	&middot;
	<math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>20</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>30</mn> </mtd>  
		    </mtr>
		    <mtr>
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math> =  <math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd > <mn>115</mn> </mtd>
		     
		    </mtr>
		    <mtr>
		      <mtd> <mn>165</mn> </mtd>
		      
		    </mtr>
		    <mtr>
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>0</mn><mo>&#215;</mo><mn>20</mn> <mo>+</mo> <mn>0</mn><mo>&#215;</mo><mn>30</mn> <mo>+</mo> <mn>1</mn><mo>&#215;</mo><mn>1</mn> </mtd>
		      
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math> = <math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd > <mn>115</mn> </mtd>
		     
		    </mtr>
		    <mtr>
		      <mtd> <mn>165</mn> </mtd>
		      
		    </mtr>
		    <mtr>
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>0 + 0 + 1</mn> </mtd>
		      
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math> = <math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd > <mn>115</mn> </mtd>
		     
		    </mtr>
		    <mtr>
		      <mtd> <mn>165</mn> </mtd>
		      
		    </mtr>
		    <mtr>
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"><mn>1</mn> </mtd>
		      
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math> 
</div>

A little bit more complicated that the dot product, but not too bad.

<h2>So, How Does This Relate To CSS3 Transforms?</h2>

A transformation of an block using the <code>matrix()</code> function is done by <strong>multiplying the matrix with each of the corner-coordinates of the block</strong> which will give the corners of the new object <strong>when the <code>transform-origin</code> is set to <code>0 0</code></strong>. For example let's say you have an HTML element styled like this:</p>

<blockquote class="code">
<pre>
#transformedObject {
     position: absolute;
     left: 0px;
     top: 0px;
     width: 200px;
     height: 80px;
     transform:  matrix(0.9, -0.05, -0.375, 1.375, 220, 20);
     transform-origin: 0 0;
}
</pre>
</blockquote>

<p>What is the end result?  Well, first let's take a look at the object <strong>without</strong> the transform CSS:</p>


<div id="originalExample" class="exampleBackground">
    <div class="point top-left-pt"></div>
    <div class="point top-right-pt"></div>
    <div class="point bottom-left-pt"></div>
    <div class="point bottom-right-pt"></div>
    <div class="coord top-left">(0, 0)</div>
      <div class="coord top-right">(200, 0)</div>
      <div class="coord bottom-left">(0, 80)</div>
      <div class="coord bottom-right">(200, 80)</div>
   <div id="exampleObject1">
      
   </div>
</div>

<p>When the browser applies the transform to this block, it takes the matrix and multiplies it to each of the corner coordinates.  For example, taking the bottom-right corner, (200, 80) or 
<math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>200</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>80</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>1</mn> </mtd>
		    </mtr>
                  </mtable>
                <mo> ) </mo>
          </mrow>
</math>, we get:
</p>

<div class="equation">
    <p>
    <math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd   mathbackground="#ffcccc"> <mn>0.9</mn> </mtd>
		      <mtd   mathbackground="#ffcccc"> <mn>-0.375</mn> </mtd>
		      <mtd   mathbackground="#ffcccc"> <mn>220</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>-0.05</mn> </mtd>
		      <mtd> <mn>1.375</mn> </mtd>
		      <mtd> <mn>20</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd > <mn>0</mn> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow>
	</math>
	&middot;
	<math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>200</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>80</mn> </mtd>  
		    </mtr>
		    <mtr>
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math> =  <math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd  color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>0.9</mn><mo>&#215;</mo><mn>200</mn> <mo>+</mo> <mn>-0.375</mn><mo>&#215;</mo><mn>80</mn> <mo>+</mo> <mn>220</mn><mo>&#215;</mo><mn>1</mn> </mtd>
		     
		    </mtr>
		    <mtr>
		      <mtd> <mn>.</mn> </mtd>
		      
		    </mtr>
		    <mtr>
		      <mtd> <mn>.</mn> </mtd>
		      
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math>  = <math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd  color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>180</mn> <mo>-</mo><mn>30</mn> <mo>+</mo> <mn>220</mn> </mtd>
		     
		    </mtr>
		    <mtr>
		      <mtd> <mn>.</mn> </mtd>
		      
		    </mtr>
		    <mtr>
		      <mtd> <mn>.</mn> </mtd>
		      
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math> = <math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd  color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>370</mn> </mtd>
		     
		    </mtr>
		    <mtr>
		      <mtd> <mn>.</mn> </mtd>
		      
		    </mtr>
		    <mtr>
		      <mtd> <mn>.</mn> </mtd>
		      
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math> 
        </p>
        <p>
              <math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>0.9</mn> </mtd>
		      <mtd> <mn>-0.375</mn> </mtd>
		      <mtd> <mn>220</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd    mathbackground="#ffcccc"> <mn>-0.05</mn> </mtd>
		      <mtd    mathbackground="#ffcccc"> <mn>1.375</mn> </mtd>
		      <mtd    mathbackground="#ffcccc"> <mn>20</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd > <mn>0</mn> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow>
	</math>
	&middot;
	<math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>200</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>80</mn> </mtd>  
		    </mtr>
		    <mtr>
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math> = <math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd> <mn>370</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>-0.05</mn><mo>&#215;</mo><mn>200</mn> <mo>+</mo> <mn>1.375</mn><mo>&#215;</mo><mn>80</mn> <mo>+</mo> <mn>20</mn><mo>&#215;</mo><mn>1</mn> </mtd>  
		    </mtr>
		    <mtr>
		      <mtd> <mn>.</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow>
       </math> = <math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd> <mn>370</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>-10</mn> <mo>+</mo> <mn>110</mn> <mo>+</mo> <mn>20</mn> </mtd>  
		    </mtr>
		    <mtr>
		      <mtd> <mn>.</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math> = <math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd> <mn>370</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd  color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>120</mn> </mtd>  
		    </mtr>
		    <mtr>
		      <mtd> <mn>.</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math>
        </p>

          <p>
              <math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>0.9</mn> </mtd>
		      <mtd> <mn>-0.375</mn> </mtd>
		      <mtd> <mn>220</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd > <mn>-0.05</mn> </mtd>
		      <mtd > <mn>1.375</mn> </mtd>
		      <mtd  > <mn>20</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd  mathbackground="#ffcccc"> <mn>0</mn> </mtd>
		      <mtd   mathbackground="#ffcccc"> <mn>0</mn> </mtd>
		      <mtd   mathbackground="#ffcccc"> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow>
	</math>
	&middot;
	<math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>200</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>80</mn> </mtd>  
		    </mtr>
		    <mtr>
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math> = <math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd> <mn>370</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>120</mn> </mtd>  
		    </mtr>
		    <mtr>
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>0&#215;200 + 0&#215;80 + 1&#215;1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow>
       </math> = <math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd> <mn>370</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>120</mn> </mtd>  
		    </mtr>
		    <mtr>
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>0</mn> <mo>+</mo> <mn>0</mn> <mo>+</mo> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math> = <math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd> <mn>370</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>120</mn> </mtd>  
		    </mtr>
		    <mtr>
		      <mtd color="#0000ff" fontweight="bold" mathbackground="#ffcccc"> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math>
        </p>
</div>

<p>Let's look at the results for the other three coordinates.  For (200, 0):</p>

<div class="equation">
    <p>
    <math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>0.9</mn> </mtd>
		      <mtd> <mn>-0.375</mn> </mtd>
		      <mtd> <mn>220</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>-0.05</mn> </mtd>
		      <mtd> <mn>1.375</mn> </mtd>
		      <mtd> <mn>20</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd > <mn>0</mn> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow>
	</math>
	&middot;
	<math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd> <mn>200</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>  
		    </mtr>
		    <mtr>
		      <mtd> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math> =  <math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd> <mn>0.9</mn><mo>&#215;</mo><mn>200</mn> <mo>+</mo> <mn>-0.375</mn><mo>&#215;</mo><mn>0</mn> <mo>+</mo> <mn>220</mn><mo>&#215;</mo><mn>1</mn> </mtd>
		     
		    </mtr>
		    <mtr>
		      <mtd> <mn>-0.05</mn><mo>&#215;</mo><mn>200</mn> <mo>+</mo> <mn>1.375</mn><mo>&#215;</mo><mn>0</mn> <mo>+</mo> <mn>20</mn><mo>&#215;</mo><mn>1</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn><mo>&#215;</mo><mn>200</mn> <mo>+</mo> <mn>0</mn><mo>&#215;</mo><mn>0</mn> <mo>+</mo> <mn>20</mn><mo>&#215;</mo><mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math>  = <math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd> <mn>400</mn> </mtd>
		     
		    </mtr>
		    <mtr>
		      <mtd> <mn>10</mn> </mtd>
		      
		    </mtr>
		    <mtr>
		      <mtd> <mn>1</mn> </mtd>
		      
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math> 
        </p>
</div>


<p>For (0, 80) test:</p>

<div class="equation">
    <p>
    <math display="inline">
	    <mrow>
    <mo>(</mo>
    <mtable>
      <mtr>
        <mtd>
          <mn>0.9</mn>
        </mtd>
        <mtd>
          <mn>-0.375</mn>
        </mtd>
        <mtd>
          <mn>220</mn>
        </mtd>
      </mtr>
      <mtr>
        <mtd>
          <mn>-0.05</mn>
        </mtd>
        <mtd>
          <mn>1.375</mn>
        </mtd>
        <mtd>
          <mn>20</mn>
        </mtd>
      </mtr>
      <mtr>
        <mtd>
          <mn>0</mn>
        </mtd>
        <mtd>
          <mn>0</mn>
        </mtd>
        <mtd>
          <mn>1</mn>
        </mtd>
      </mtr>
    </mtable>
    <mo>)</mo>
  </mrow>
  <mo>&#xB7;</mo>
  <mrow>
    <mo>(</mo>
    <mtable>
      <mtr>
        <mtd>
          <mn>0</mn>
        </mtd>
      </mtr>
      <mtr>
        <mtd>
          <mn>80</mn>
        </mtd>
      </mtr>
      <mtr>
        <mtd>
          <mn>1</mn>
        </mtd>
      </mtr>
    </mtable>
    <mo>)</mo>
  </mrow>

  <mo>=</mo>
  <mrow>
    <mo>(</mo>
    <mtable>
      <mtr>
        <mtd>
          <mn>0.9</mn>
          <mo>&#xD7;</mo>
          <mn>0</mn>
          <mo>+</mo>
          <mn>-0.375</mn>
          <mo>&#xD7;</mo>
          <mn>80</mn>
          <mo>+</mo>
          <mn>220<mn><mo>&#xD7;</mo><mn>1</mn></mn></mn>
        </mtd>
      </mtr>
      <mtr>
        <mtd>
          <mn>-0.05</mn>
          <mo>&#xD7;</mo>
          <mn>0</mn>
          <mo>+</mo>
          <mn>1.375</mn>
          <mo>&#xD7;</mo>
          <mn>80</mn>
          <mo>+</mo>
          <mn>20</mn>
          <mo>&#xD7;</mo>
          <mn>1</mn>
        </mtd>
      </mtr>
      <mtr>
        <mtd>
          <mn>0</mn>
          <mo>&#xD7;</mo>
          <mn>0</mn>
          <mo>+</mo>
          <mn>0</mn>
          <mo>&#xD7;</mo>
          <mn>80</mn>
          <mo>+</mo>
          <mn>20</mn>
          <mo>&#xD7;</mo>
          <mn>1</mn>
        </mtd>
      </mtr>
    </mtable>
    <mo>)</mo>
  </mrow>
<mo>=</mo>	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd> <mn>190</mn> </mtd>
		     
		    </mtr>
		    <mtr>
		      <mtd> <mn>130</mn> </mtd>
		      
		    </mtr>
		    <mtr>
		      <mtd> <mn>1</mn> </mtd>
		      
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math> 
        </p>
</div>



<p>And finally, for (0, 0):</p>

<div class="equation">
    <p>
    <math display="inline">
	  <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>0.9</mn> </mtd>
		      <mtd> <mn>-0.375</mn> </mtd>
		      <mtd> <mn>220</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>-0.05</mn> </mtd>
		      <mtd> <mn>1.375</mn> </mtd>
		      <mtd> <mn>20</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd > <mn>0</mn> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow>
	</math>
	&middot;
	<math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd> <mn>0</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>  
		    </mtr>
		    <mtr>
		      <mtd> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math> =  <math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd> <mn>0.9</mn><mo>&#215;</mo><mn>0</mn> <mo>+</mo> <mn>-0.375</mn><mo>&#215;</mo><mn>0</mn> <mo>+</mo> <mn>220</mn><mo>&#215;</mo><mn>1</mn> </mtd>
		     
		    </mtr>
		    <mtr>
		      <mtd> <mn>-0.05</mn><mo>&#215;</mo><mn>0</mn> <mo>+</mo> <mn>1.375</mn><mo>&#215;</mo><mn>0</mn> <mo>+</mo> <mn>20</mn><mo>&#215;</mo><mn>1</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn><mo>&#215;</mo><mn>0</mn> <mo>+</mo> <mn>0</mn><mo>&#215;</mo><mn>0</mn> <mo>+</mo> <mn>20</mn><mo>&#215;</mo><mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math>  = <math display="inline">	
		<mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr >
		      <mtd> <mn>220</mn> </mtd>
		     
		    </mtr>
		    <mtr>
		      <mtd> <mn>20</mn> </mtd>
		      
		    </mtr>
		    <mtr>
		      <mtd> <mn>1</mn> </mtd>
		      
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow> 
	</math> 
        </p>
</div>

<p>Here is the result:</p>

<div id="transformedExample" class="exampleBackground">
       <div class="point top-left-pt"></div>
      <div class="point top-right-pt"></div>
      <div class="point bottom-left-pt"></div>
      <div class="point bottom-right-pt"></div>
      <div class="coord top-left">(220, 20)</div>
      <div class="coord top-right">(400, 10)</div>
      <div class="coord bottom-left">(190, 130)</div>
      <div class="coord bottom-right">(370, 120)</div>
   <div id="exampleObject2">
      
   </div>
</div>

<p>I don't expect anyone to calculate these by hand on a regular basis (I personally don't).  But now you know what these numbers mean.  :-)</p>

<h2>What About Internet Explorer?</h2>
<p>Although <code>transform-origin</code> doesn't work with IE, it is possible to generate the matrix in another browser and use <a href="http://www.useragentman.com/blog/csssandpaper-a-css3-javascript-library/">cssSandpaper</a> to generate the shape of the transform in that browser.  In order to fix the positioning, one can use <a href="http://paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/">Paul Irish's conditional stylesheet fix</a> to position that block manually in IE only (it is what I used on this page so that the matrix transform in my example above appeared correctly in IE).  I hope to have transform-origin working in cssSandpaper soon so that it will be unnecessary to do this.</p>

<h2>Other Interesting Facts About Matrices</h2>

<ol>
<li>All the other CSS3 transform functions have equivalent matrix notation:

<table class="dataTable">
<thead class="centered">
<tr>
<th>
scale(a)
</th>
<th>
scaleX(x)
</th>
<th>
scaleY(y)
</th>
<th>translateX(x)</th>
<th>translateY(y)</th>
<th>translate(x,y)</th>




</tr>
</thead>

<tbody class="centered">
<tr>
<td>
<math display="inline">
     <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>a</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>a</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd > <mn>0</mn> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow>
</math>
</td>
<td>
<math display="inline">
     <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>x</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd > <mn>0</mn> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow>
</math>
</td>
<td>
<math display="inline">
     <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>1</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>y</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd > <mn>0</mn> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow>
</math>
</td>
<td>
<math display="inline">
     <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>x</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd > <mn>0</mn> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow>
</math>
</td>
<td>
<math display="inline">
     <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>y</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd > <mn>0</mn> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow>
</math>
</td>
<td>
<math display="inline">
     <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>x</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>y</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd > <mn>0</mn> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow>
</math>
</td>


</tr>
</table>

<table class="dataTable">
<thead class="centered">
<tr>
<th>skewX(x)</th>
<th>skewY(y)</th>
<th>skew(x,y)</th>
<th>rotate(θ)</th>

</tr>
</thead>
<tbody class="centered">
<tr>

<td>
<math display="inline">
     <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>1</mn> </mtd>
		      <mtd> <mo>tan</mo><mi>x</mi> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd > <mn>0</mn> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow>
</math>
</td>
<td>
<math display="inline">
     <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>1</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mo>tan</mo><mi>y</mi> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd > <mn>0</mn> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow>
</math>
</td>
<td>
<math display="inline">
     <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>1</mn> </mtd>
		      <mtd> <mo>tan</mo><mi>x</mi> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mo>tan</mo><mi>y</mi> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd > <mn>0</mn> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow>
</math>
</td>
<td>
<math display="inline">
     <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mo>cos</mo><mi>θ</mi> </mtd>
		      <mtd> <mo>-sin</mo><mi>θ</mi> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mo>sin</mo><mi>θ</mi> </mtd>
		      <mtd> <mo>cos</mo><mi>θ</mi> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd > <mn>0</mn> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow>
</math>
</td>
</tr>
</table>


</li>

<li>A list of transforms in CSS3 like this:

<blockquote class="code">
<pre>
#o1 {
   transform-origin: 0px 0px;
   transform: rotate(15deg) translateX(230px) scale(1.5);
}
</pre>
</blockquote>

is the same as multiplying the equivalent matrices together:

<div class="equation">
<math display="inline">
     <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mo>cos</mo><mi>15&#176;</mi> </mtd>
		      <mtd> <mo>-sin</mo><mi>15&#176;</mi> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mo>sin</mo><mi>15&#176;</mi> </mtd>
		      <mtd> <mo>cos</mo><mi>15&#176;</mi> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd > <mn>0</mn> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow>
</math> &middot;
<math display="inline">
     <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>230</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd > <mn>0</mn> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow>
</math> &middot; <math display="inline">
     <mrow>
		  <mo> ( </mo>
		  <mtable>
		    <mtr>
		      <mtd> <mn>1.5</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		      <mtd> <mn>0</mn> </mtd>
		    </mtr>
		    <mtr>
		      <mtd> <mn>0</mn> </mtd>
		      <mtd > <mn>0</mn> </mtd>
		      <mtd> <mn>1</mn> </mtd>
		    </mtr>
		  </mtable>
		  <mo> ) </mo>
		</mrow>
</math>
</div>

(I know, I didn't tell you how to multiply matrices together. 
<a href="http://people.hofstra.edu/stefan_waner/RealWorld/index.html">Stephan Waner</a> has written <a href="http://people.hofstra.edu/stefan_waner/realworld/tutorialsf1/frames3_2.html">a good tutorial for matrix multiplication</a> if you are interested.)</li>


<li><strong>CSS3 2D-Transforms can only transform blocks into parallelograms</strong>.  For example, it is impossible to transform a block into this shape:


<div id="transformedExample" class="exampleBackground">
      <img src="http://www.useragentman.com/blog/wp-content/uploads/2011/01/irregular.png" alt="[Irregular Shape]" title="irregular"  />
</div>

In order to do this, one must use <a href="http://www.w3.org/TR/css3-3d-transforms/">CSS3 3D Transforms</a>.  This is why the Matrix Construction Set only has three control points to drag around, not four.  If you would like to see a version of the Matrix Construction Set to use <code>matrix3d()</code>, please let me know by leaving a comment below.</li>




</ol>

<h2>In Conclusion</h2>

<p>I don't expect anyone to be an expert in matrix artithmetic after reading this article.  But at least you know what those pesky numbers mean, and this information may become useful in the future.</p>

<h2>Acknowledgments</h2>

<ul>
<li>The MathML markup used to display the mathematical equations in this article were rendered by <a href="http://www.mathjax.org/">MathJax</a>, an excellent open-source JavaScript library</li>
<li>The equations on  <a href="http://www.physicsforums.com/showthread.php?t=360963">this Physics Forum post</a> was quite helpful in the creation of the Matrix Construction Set.</li>
<li>The Matrix Construction Set uses <a href="http://sylvester.jcoglan.com/">the Sylvester JavaScript library</a> written by <a href="http://jcoglan.com/">James Coglan</a> for performing matrix calculations.  It also used my own <a href="http://www.useragentman.com/blog/2010/01/10/cross-browser-html5-drag-and-drop/">DragDropHelpers</a> library to smooth out the different browser implementations of HTML5 Drag and Drop.</li>
<li>A blog post that has a bunch of math equations on it may be scary for web designers.  My apologies.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.useragentman.com/blog/2011/01/07/css3-matrix-transform-for-the-mathematically-challenged/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>Cross Browser HTML5 Ruby Annotations Using CSS</title>
		<link>http://www.useragentman.com/blog/2010/10/29/cross-browser-html5-ruby-annotations-using-css/</link>
		<comments>http://www.useragentman.com/blog/2010/10/29/cross-browser-html5-ruby-annotations-using-css/#comments</comments>
		<pubDate>Fri, 29 Oct 2010 04:17:18 +0000</pubDate>
		<dc:creator>zoltan</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Internationalization]]></category>
		<category><![CDATA[Polyfills]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[bopomofo]]></category>
		<category><![CDATA[chinese]]></category>
		<category><![CDATA[furigana]]></category>
		<category><![CDATA[hangul]]></category>
		<category><![CDATA[hanja]]></category>
		<category><![CDATA[hiragana]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[internationalization]]></category>
		<category><![CDATA[japanese]]></category>
		<category><![CDATA[kanji]]></category>
		<category><![CDATA[katakana]]></category>
		<category><![CDATA[korean]]></category>
		<category><![CDATA[multilanguage]]></category>
		<category><![CDATA[multilingual]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[xhtml]]></category>
		<category><![CDATA[xhtml 2.0]]></category>

		<guid isPermaLink="false">http://www.useragentman.com/blog/?p=1658</guid>
		<description><![CDATA[<img src="/blog/wp-content/uploads/2010/10/containerFirefox2.png"  /> Ruby Characters, although used originally to help people read complicated Chinese and Japanese characters, can also be used to annotate all types of information to written text.  This article shows how you can use it in browsers that support it, but also in ones that don't using a simple stylesheet.]]></description>
			<content:encoded><![CDATA[<div id="attachment_1735" class="wp-caption alignright" style="width: 419px"><a href="http://www.flickr.com/photos/eliazar/3193967863/"><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/10/rubyExample.jpg" alt="An example of ruby text, from a photo by Flickr user eliazar" title="screenshot" width="409" height="261" class="size-full wp-image-1619" /></a>
<p class="wp-caption-text">An example of ruby text, from <a href="http://www.flickr.com/photos/eliazar/3193967863/">a photo</a> by Flickr user <a href="http://www.flickr.com/photos/eliazar/">eliazar</a>.&#8221;</p>
</div>
<p>When talking about <strong>Ruby Annotations</strong>, I don&#8217;t mean Ruby on Rails, or anything related to the Ruby programming language.  I am talking about <a href="http://en.wikipedia.org/wiki/Ruby_character"><strong>ruby characters</strong></a> which <strong>are used to annotate text with supplementary information.</strong>  For example if some readers wouldn&#8217;t know what the term &#8220;WWW&#8221; means, we can use ruby annotations to help them out like this:</p>
<div class="rubyExample">
<p>I love the <ruby><rb>WWW</rb><rp> （</rp><rt class="small" style="font-size: 0.37em">World Wide Web</rt><rp>） </rp></ruby>.</p>
</div>
<p>The <strong>ruby base</strong> (in this case &#8220;WWW&#8221;) is annotated by <strong>ruby text</strong> (&#8220;World Wide Web&#8221;).  In this case, the ruby text appears in a small font-size above the base.  Traditionally, ruby annotations have been used in Chinese, Korean and Japanese text-books to help students of those languages sound out more complicated characters:</p>
<div class="rubyExample japanese">
  <ruby><rb>東京</rb><rp> （</rp><rt>とうきょう</rt><rp>） </rp></ruby>に<ruby>行<rp> （</rp><rt>い</rt><rp>） </rp></ruby>きたい。
</div>
<p>In the text above, the <strong>ruby base is written in Kanji</strong>, many of which are only readable by Japanese with a high-school education. The <strong>ruby text is written in Hiragana</strong>, which all Japanese grade-schoolers can understand. </p>
<p>I can hear you saying to yourself <strong>&#8220;Who cares?  I&#8217;m not Japanese!  I can&#8217;t read any of it!&#8221;</strong>. Ruby annotations can also be used to help those who don&#8217;t speak the language at all.  An author can use ruby to help English speakers  pronounce Japanese &#8230; </p>
<div class="rubyExample japanese">
  <ruby><rb>東京</rb><rp> (</rp><rt><span class="romaji">tō kyō</span></rt><rp>) </rp></ruby> <ruby>に<rp> (</rp><rt><span class="romaji">ni</span></rt><rp>) </rp></ruby><ruby>行き<rp> (</rp><rt><span class="romaji">iki</span></rt><rp>) </rp></ruby><ruby>たい<rp> (</rp><rt><span class="romaji">tai</span></rt><rp>) </rp></ruby>。
</div>
<p>.. or, for that matter, any other language, like Ukrainian.</p>
<div class="rubyExample">
<ruby><rb>Золтан </rb><rp> (</rp><rt>zol-tan</rt><rp>)</rp></ruby> <ruby><rb>Євгенович </rb><rp> (</rp><rt>yew-hen-o-vich</rt><rp>)</rp></ruby> <ruby><rb>Гаврилюк </rb><rp> (</rp><rt>how-real-luke</rt><rp>)</rp></ruby>.
</div>
<p>It can also allow an author to give translations on top of foreign words.</p>
<div class="rubyExample japanese">
  <ruby><rb>東京 に 行き たい</rb><rp> (</rp><rt><span class="romaji">I want to go to Tokyo.</span></rt><rp>) </rp></ruby>。
</div>
<h2>But I Have a Hard Enough Time With English!</h2>
<p>Ruby text can also be used for help foreign students pronounce English words that may difficult to read:</p>
<div class="rubyExample">
His <ruby><rb>communication </rb><rp> (</rp><rt class="phonetic">k&#601;-my<span class="long">oo</span>-n&#301;-<strong>k&#257;&#180;</strong>-sh&#601;n</rt><rp>) </rp></ruby> skills are quite bad.
</div>
<p>It can be also be used to help English speakers read intimidating Eastern European surnames transliterated into English:</p>
<div class="rubyExample">
My name is Zoltan <ruby><rb>Hawryluk</rb><rp> (pronounced: </rp><rt>how-real-luke</rt><rp>)</rp></ruby>.
</div>
<p>(<strong>An aside note to telemarketers:</strong> if you call my home and ask my to speak to &#8220;Mister Have &#8212;- um &#8212; uk&#8221; , &#8220;Mister Hawww &#8212; ahh &#8212; uhhh&#8221; <strong><em>or especially &#8220;Mr. Zoltar&#8221;</em></strong>, I will hang up immediately.  If you actually pronounce my name correctly, I&#8217;ll give you at least five minutes of my time.  I mean it.)</p>
<h2>Okay, how is this coded?</h2>
<p>Let&#8217;s take a look at the markup of the above example:</p>
<blockquote class="code">
<pre>
My name is Zoltan
&lt;ruby&gt;
   &lt;rb&gt;Hawryluk&lt;/rb&gt;
   &lt;rp&gt; (&lt;/rp&gt;
   &lt;rt&gt;how-real-luke&lt;/rt&gt;
   &lt;rp&gt;) &lt;/rp&gt;
&lt;/ruby&gt;
</pre>
</blockquote>
<p>Let&#8217;s break down what each of these tags do:</p>
<table class="dataTable">
<thead>
<tr>
<th>Tag</th>
<th>Name</th>
<th>Function</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>&lt;ruby&gt;</code>
</td>
<td>Ruby Tag</td>
<td>Used to specify a Ruby Annotation.</td>
</tr>
<tr>
<td>
<code>&lt;rb&gt;</code>
</td>
<td>Ruby Base Tag</td>
<td>Used to specify the text that is to be annotated.</td>
</tr>
<tr>
<td><code>&lt;rt&gt;</code></td>
<td>Ruby Text</td>
<td>The actual ruby text, which contains the actual annotation.  By default, it appears above the actual text.</td>
</tr>
<tr>
<td><code>&lt;rp&gt;</code></td>
<td>Ruby Parenthesis</td>
<td>These are displayed to browsers that cannot display ruby text, and permits graceful degradation.  It also allows the text to be copied and pasted into another document without the formatting.</td>
</tr>
</tbody>
</table>
<p>To illustrate the last point about the <code>&lt;rp&gt;</code> tag, copy and paste the following ruby text into notepad, vi or any other plain text editor:</p>
<div class="rubyExample">
My name is Zoltan <ruby><rb>Hawryluk</rb><rp> (pronounced: </rp><rt>how-real-luke</rt><rp>)</rp></ruby>.
</div>
<p>You will see the following in your text editor:</p>
<blockquote class="code">
<pre>
My name is Zoltan Hawryluk (pronounced: how-real-luke).
</pre>
</blockquote>
<p>This is because the of how the <code>&lt;rp&gt;</code> tags are defined:</p>
<blockquote class="code">
<pre>
My name is Zoltan &lt;ruby&gt;&lt;rb&gt;Hawryluk&lt;/rb&gt;<span class="hilite">&lt;rp&gt; (pronounced: &lt;/rp&gt;</span>&lt;rt&gt;how-real-luke&lt;/rt&gt;<span class="hilite">&lt;rp&gt;)&lt;/rp&gt;</span>
</pre>
</blockquote>
<h2>Browser Support</h2>
<p>So what browsers support these tags?  Originally, the <code>&lt;ruby&gt;</code> tag was a proprietary Microsoft tag that worked in IE 5+.  Since then it has become a part of HTML5 and WebKit based browsers like Safari and Chrome now support it as well.  In order for Firefox and Opera to join the party, I <a href="http://www.useragentman.com/shared/css/ruby/screen.css">remixed a stylesheet</a> developed for <a href="http://www.princexml.com/bb/viewtopic.php?t=81">Prince XML</a> by <a href="http://www.chavchanidze.com/">George Chavchanidze</a> of Opera Software.  Below are some screenshots of how the ruby text looks in the various browsers with or without the stylesheet.</p>
<table class="dataTable">
<thead>
<tr>
<th></th>
<th>With stylesheet set</th>
<th>Without stylesheet set</th>
</tr>
</thead>
<tbody>
<tr>
<th>IE 6.0+</th>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/10/example-IE-with.png" alt="example screenshot with IE with stylesheet set"  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/10/example-IE-without.png" alt="example screenshot with IE with stylesheet set"   /></td>
</tr>
<tr>
<th>Firefox 3.6+</th>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/10/example-Firefox-with.png" alt="example screenshot with Firefox with stylesheet set" title="example-IE-without"  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/10/example-Firefox-without.png" alt="example screenshot with Firefox with stylesheet set"   /></td>
</tr>
<tr>
<th>Safari 5.0+</th>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/10/example-safari-with.png" alt="example screenshot with Safari with stylesheet set"   /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/10/example-safari-without.png" alt="example screenshot with Safari with stylesheet set"  /></td>
</tr>
<tr>
<th>Chrome 7.0+</th>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/10/example-chrome-with.png" alt="example screenshot with Chrome with stylesheet set" title="example-IE-without"  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/10/example-chrome-without.png" alt="example screenshot with Chrome with stylesheet set" title="example-IE-without"  /></td>
</tr>
<tr>
<th>Opera 10.63+</th>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/10/example-opera-with.png" alt="example screenshot with Opera with stylesheet set"  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/10/example-opera-without.png" alt="example screenshot with Opera with stylesheet set"  /></td>
</tr>
</tbody>
</table>
<p><a class="exampleLink" href="http://www.useragentman.com/shared/css/ruby/screen.css">Download the stylesheet used in the examples on this page</a></p>
<p>I took George&#8217;s <strong>excellent</strong> work and added a few additional features:</p>
<ul>
<li>It tells IE to ignore the Firefox and Opera styles (since they don&#8217;t look so good in IE)</li>
<li>It makes the font size smaller in Chrome and Safari (a personal preference).</li>
<li>It sets the <code>&lt;ruby&gt;</code> tag&#8217;s <code>ruby-align</code> CSS property to <code>center</code>, so that IE mimics the way the WebKit browser display ruby text by default (IE&#8217;s default seems to be <code>distribute-letter</code>, which looks horrible in a lot of situations).</li>
</ul>
<p>Also note that without the stylesheet, the ruby text gracefully degrades in Firefox and Opera, so it is still readable, and illustrates the usefulness of the <code>&lt;rp&gt;</code> tags.  This stylesheet occasionally cause some unusual rendering in some older browsers (such as Safari 4.0 for Mac), but on the whole it does a pretty good job.</p>
<p>Note that in order to make the stylesheet set to work correctly, you must replace the <code>&lt;body&gt;</code> tag with this variation of <a href="http://paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/">Paul Irish&#8217;s Conditional CSS design pattern</a>:</p>
<blockquote class="code">
<pre>
&lt;!--[if lt IE 7 ]&gt; &lt;body class="ie6"&gt; &lt;![endif]--&gt;
&lt;!--[if IE 7 ]&gt;    &lt;body class="ie7"&gt; &lt;![endif]--&gt;
&lt;!--[if IE 8 ]&gt;    &lt;body class="ie8"&gt; &lt;![endif]--&gt;
&lt;!--[if IE 9 ]&gt;    &lt;body class="ie9"&gt; &lt;![endif]--&gt;
&lt;!--[if (gt IE 9)]&gt;&lt;body class="modern"&gt; &lt;![endif]--&gt;
&lt;!--[!(IE)]&gt;&lt;!--&gt;  &lt;body class="notIE modern"&gt; &lt;!--&lt;![endif]--&gt;
</pre>
</blockquote>
<p>Using this declaration of the <code>&lt;body&gt;</code> blocks the Firefox and Opera styles in IE.</p>
<h2>Advanced Ruby Annotations</h2>
<p>Using the stylesheet, it is possible to also <strong>break ruby text into parts (e.g. syllables) without using a separate <code>&lt;ruby&gt;</code> tag for each part</strong>.  This is done with the <code>&lt;rbc&gt;</code> (ruby base container) and <code>&lt;rtc&gt;</code> (ruby text container).  Here is an example:</p>
<div class="rubyExample">
His <ruby class="syllables unicodeRubyText"><rbc><rb>com</rb><rb>mu</rb><rb>ni</rb><rb>ca</rb><rb>tion </rb></rbc><rp> (</rp><rtc><rt >k&#601;m</rt><rt>myoo</rt><rt>n&#301;</rt><rt><strong>k&#257;&#180;</strong></rt><rt  >sh&#601;n</rt></rtc><rp>) </rp></ruby> skills are quite bad.
</div>
<p>Although Internet Explorer does not understand these new tags, it does degrade gracefully.  Here is a comparison of how IE renders the above and how Firefox does.</p>
<table class="dataTable">
<thead>
<tr>
<th>Firefox 3.6</th>
<th>Internet Explorer 6+</th>
</tr>
</thead>
<tbody>
<tr>
<td style="width: 50%"><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/10/containerFirefox.png" alt="[Screenshot of rbc/rtc tag example in Firefox]"  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/10/containerExplorer.png" alt="[Screenshot of rbc/rtc tag example in IE]"  /></td>
</tr>
</tbody>
</table>
<p>Here is the code that generated the example above.  </p>
<blockquote class="code">
<pre>
&lt;ruby class="syllables unicodeRubyText"&gt;
<span class="hilite">  &lt;rbc&gt;
    &lt;rb&gt;com&lt;/rb&gt;&lt;rb&gt;mu&lt;/rb&gt;&lt;rb&gt;ni&lt;/rb&gt;&lt;rb&gt;ca&lt;/rb&gt;&lt;rb&gt;tion &lt;/rb&gt;
  &lt;/rbc&gt;</span>
  &lt;rp&gt; (&lt;/rp&gt;
<span class="hilite">  &lt;rtc&gt;
    &lt;rt&gt;k&#601;m&lt;/rt&gt;&lt;rt&gt;myoo&lt;/rt&gt;&lt;rt&gt;n&#301;&lt;/rt&gt;&lt;rt&gt;&lt;strong&gt;k&#257;&lt;/strong&gt;&lt;/rt&gt;&lt;rt&gt;sh&#601;n&lt;/rt&gt;
  &lt;/rtc&gt;</span>
  &lt;rp&gt;) &lt;/rp&gt;
&lt;/ruby&gt;
</pre>
</blockquote>
<p>Note that the <code>&lt;ruby&gt;</code> tag is a member of the classes <code>syllables</code> and <code>unicodeRubyText</code>, which are defined in the stylesheet.  The <code>syllables</code> class tells the browser to separate the ruby base text into syllables, separated by the <a href="http://en.wikipedia.org/wiki/Middot">&#8220;Interpunct&#8221;</a> symbol, while the <code>unicodeRubyText</code> tells the browser to render the ruby text with a Unicode font, so that the pronunciation symbols are printed correctly (it seems that this is only a requirement in Explorer, since the other browsers handle this automatically).</p>
<p>Here is a rundown of these advanced tags:</p>
<table class="dataTable">
<thead>
<tr>
<th>Tag</th>
<th>Name</th>
<th>Function</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>&lt;rbc&gt;</code>
</td>
<td>Ruby Base Container</td>
<td>Contains a list of <code>&lt;rb&gt;</code> tags.  This list is usually separated into syllables or some other logical order to make the text easier to read.</td>
</tr>
<tr>
<td>
<code>&lt;rtc&gt;</code>
</td>
<td>Ruby Text Container</td>
<td>Contains a list of <code>&lt;rt&gt;</code> tags.  Each <code>&lt;rt&gt;</code> tag in this list corresponds to the respective <code>&lt;rb&gt;</code> tag in the <code>&lt;rtc&gt;</code> list.</td>
</tr>
</tbody>
</table>
</blockquote>
<p>Unfortunately, there is a bug in older WebKit browsers that gives very strange results. Here are screen shots of the above code as viewed in Chrome 7.0 for Windows, with and without my stylesheet:</p>
<table class="dataTable">
<thead>
<tr>
<th>Chrome 7.0 Windows (with stylesheet) </th>
<th>Chrome 7.0 Windows (without stylesheet) </th>
</tr>
</thead>
<tbody>
<tr>
<td style="width: 50%"><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/10/containerChromeWithStylesheet.png" alt="[Screenshot of rbc/rtc tag example in Chrome 7.0 With My Stylesheet]"  /></td>
<td><img src="http://www.useragentman.com/blog/wp-content/uploads/2010/10/containerChromeWithoutStylesheet.png" alt="[Screenshot of rbc/rtc tag example in Chrome 7.0 Without My Stylesheet]"  /></td>
</tr>
</tbody>
</table>
<p>This bug appears in Safari 4.x and lower and the current version of Chrome (7.0), for both Windows and Mac.  Since this has been fixed in Safari 5.0, I am assuming that this will be fixed in the next version of Chrome as well.</p>
<h2>Ruby CSS3 Properties</h2>
<p>There are three main CSS3 properties that can be used today &#8230; but in Internet Explorer only.  Here are a list of them, along with additional properties that the <a href="http://www.w3.org/TR/2001/WD-css3-ruby-20010216/">W3C put in their recommendation back in 2001</a>.</p>
<table class="dataTable">
<thead>
<tr>
<th>Property Name</th>
<th>Description</th>
<th>Support</th>
<th>More Info</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>ruby-align</code></td>
<td>Affects the horizontal alignment of the Ruby Text with respect to the ruby base.   Default value is <code>auto</code> (which is the same as <code>center</code>).  Other values are <code>left</code>, <code>right</code>, as well as <code>distribute-letter</code>, <code>distribute-space</code>, <code>line-edge</code>, <code>start</code> and <code>end</code>.</td>
<td><code>left</code>, <code>right</code>, as well as <code>distribute-letter</code>, <code>distribute-space</code>, <code>line-edge</code> work in IE5+.</td>
<td style="white-space: nowrap">
<ul>
<li><a href="http://www.w3.org/International/articles/ruby/#Slide0210">W3C Reference</a>
<li><a href="http://msdn.microsoft.com/en-us/library/ms531150%28VS.85%29.aspx">MSDN</a></li>
<li><a href="http://www.blooberry.com/indexdot/css/properties/intl/ralign.htm">Index  DOT  Css</a></li>
</ul>
</td>
</tr>
<tr>
<td><code>ruby-overhang</code></td>
<td>
Affects how the ruby text will &#8220;hang&#8221; over the ruby base if the ruby-text is wider than the ruby-base.  Valid values are <code>auto</code>, <code>none</code>, <code>whitespace</code>, <code>start</code> and <code>end</code>.</td>
<td><code>auto</code>, <code>none</code> and <code>whitespace</code> work in IE 5+</td>
<td>
<ul>
<li><a href="http://www.w3.org/International/articles/ruby/#Slide0260">W3C Reference</a>
<li><a href="http://msdn.microsoft.com/en-us/library/ms531151%28VS.85%29.aspx">MSDN</a></li>
<li><a href="http://www.blooberry.com/indexdot/css/properties/intl/roverhang.htm">Index  DOT  Css</a></li>
</ul>
</tr>
<tr>
<td><code>ruby-position</code></td>
<td>Indicates where ruby text should appear relative to the base text.  Default is <code>before</code>. Other values are <code>after</code> (which makes it appear underneath the text), <code>inline</code>, <code>left</code> and <code>right</code>.</td</p>
<td>Only <code>above</code> and <code>inline</code> work in IE5+</td>
<td>
<ul>
<li><a href="http://www.w3.org/International/articles/ruby/#Slide0180">W3C Reference</a>
<li><a href="http://msdn.microsoft.com/en-us/library/ms531152(VS.85).aspx">MSDN</a></li>
<li><a href="http://www.blooberry.com/indexdot/css/properties/intl/rposition.htm">Index  DOT  Css</a></li>
</ul>
</tr>
</tbody>
</table>
<p>Hopefully the other browsers will support these eventually.</p>
<h2>And So, In Conclusion &#8230;</h2>
<p>Here is a quick recap of the various things you should keep in mind when using Ruby Text:</p>
<ul>
<li>Firefox 3.6 and Opera 10.x need the stylesheet in order to show ruby text correctly.</li>
<li>Recent versions of Safari and Chrome don&#8217;t need it, but using the stylesheet won&#8217;t harm the display of simple ruby text.</li>
<li>IE doesn&#8217;t need the styleheet, but if you use the stylesheet to ensure cross-browser display of ruby text, you must use the special body tag declaration above.</li>
<li><code>&lt;rbc&gt;</code> and <code>&lt;rtc&gt;</code> are not recognized in any version of IE, but they will degrade gracefully.</li>
<li>Ruby text inside of <code>&lt;rtc&gt;</code> tags doesn&#8217;t look right in Chrome 7 or Safari 4.  Since they do show up right in Safari 5, I assume/hope this will be fixed in the next version of Chrome.</li>
<li>The advanced CSS3 <code>ruby-</code> properties, such as <code>ruby-align</code>, <code>ruby-overhang</code> and <code>ruby-position</code> are only supported by IE5+.</li>
</ul>
<h2>Additional Reading</h2>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/ff460533%28v=VS.85%29.aspx">[MS-RUBY]: Internet Explorer Ruby Annotation Standards Support Document</a> from the <a href="http://msdn.microsoft.com/">MSDN Web Site</a>.
<li><a href="http://webkit.org/blog/948/ruby-rendering-in-webkit/">Ruby Rendering in WebKit</a> from the <a href="http://webkit.org/blog/">Surfin’ Safari</a> Blog archive
<li><a href="http://www.w3.org/TR/css3-ruby/">The W3C Recommendation document for Ruby Annotations</a>, dated 31 May 2001 with corrections made on 25 June 2008</a></li>
<li><a href="http://www.w3.org/TR/2001/WD-css3-ruby-20010216/">The W3C CSS3 Rub Module Working Draft</a> dated 14 May 2003.</a>.  There is also <a href="http://dev.w3.org/csswg/css3-ruby/">an editor&#8217;s copy</a> dated 04 March 2010.</li>
<li><a href="http://princecss.com/bb/viewtopic.php?f=5&#038;t=81">XHTML Ruby in Prince</a>, the forum thread where the original stylesheet was developerd.  Great to see as a reference.</li>
</ul>
<p><a class="exampleLink" href="http://www.useragentman.com/shared/css/ruby/screen.css">Download the stylesheet used in the examples on this page</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.useragentman.com/blog/2010/10/29/cross-browser-html5-ruby-annotations-using-css/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

