How did the IE Conditional Classes Get on the HTML Element in HTML5 Boilerplate?

Since it comes up from time to time on Github (See #1288 and #1187) and I was involved in part of the discussion I thought I’d try to clarify the timeline and reasoning for the placement of the IE conditional comments in the HTML5 Boilerplate project (and anywhere else that uses the HTML element for the conditional classes.)

For those of you unfamiliar with the pattern, it looks like this:

<!DOCTYPE html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->

These different versions of the <html> element are displayed in IE6, IE7, IE8 and modern browsers allowing you to target Internet Explorer conditionally based on a CSS class at the very top of the cascade.

Anyway, for such a small block of code it actually generates a lot of discussion in the repo and is the subject of at least one, long-standing issue.

Also, removing them is an open issue right now.

Anyway, since I was involved in some of the original discussion and still actively watch activity on the HTML5 Boilerplate repo and participate where it makes sense; I often find myself chiming in on issues discussing the conditional comments with a series of links trying to illustrate the long and tortuous journey they took to get to the state they’re currently in.

While those links contain all the information needed to follow the thread, it’s not all that easy to put the trail together without having lived through it.

To that end, here’s how the comments ended up where they are- presented in chronological order with just the most important details.

  1. On October 20 2008, Paul Irish kicked the whole thing off with the post “Conditional stylesheets vs CSS hacks? Answer: Neither!. In it’s original form the conditional comments wrapped the <body> element
  2. I ended up learning about the technique in December of 2009 when I interviewed at Molecular (where Paul worked at the time) and Nick Cooley mentioned it during the interview. “Cool” I thought. Since I didn’t actually read the post and just had the technique described to me, I ended up implementing it in a way that made sense to me during the redesign of my (other) site (which is once again on the block to be redesigned.) I placed the comments around the <html> element. I was already using the <body> element for classes, so I probably never even considered using the <body> element for that purpose.
    That version of the site launched March 1, 2010.
  3. On May 20, 2010 Markus Leptien posted IE 6 slowing down IE 8. In which he details the curious case of IE8 blocking downloads because of the presence of an IE6 specific conditional comment.
  4. Stoyan Stefanov took up the cause on May 23, 2010 with his post http://www.phpied.com/conditional-comments-block-downloads/ where he outlines the even curiouser case of IE blocking downloads even if the conditional comment isn’t for a CSS resource. This spelled trouble for the conditional comments on the body element.
  5. On May 24th, 2010 Markus Leptien posted a solution to the issue which required an empty conditional comment high up in the DOM.
  6. Paul added the empty conditional fix to HTML5 Boilerplate on June 3, 2010
  7. For whatever reason, I got hooked into the discussion and pointed out that “My variation of Paul’s pattern works out of the box. Instead of applying classes to the body, I apply them to the HTML element. No need for empty comments” The same day Paul updated his blog post with that news and the pattern settled on the HTML element
  8. On September 9, 2010 Divya Manian moved the comments to the HTML element in the HTML5 Boilerplate repo.

And that’s the origin story. It’s not exactly as exciting as how Bruce Wayne went from being a rich kid seeing the Mask of Zorro to being Gotham’s Dark Knight Detective, but at least now people be confused by how the placement came to be.

I’ll be Presenting At HTML5 Developer Conference in San Francisco

I just got word that my presentation was accepted. I’ll be presenting alongside people who are really super smart. I’m hoping to not embarrass myself.

I promise I won’t pick a fight with Douglas Crockford just as a goof.

Here’s the pitch for my talk:

We’re awash in data. Making sense of that flood of information is impossible without the aid of visualizations to simplify the information, amplify the important points and educate at a glance. The open web platform has two main technologies for working with interactive visualizations: SVG and Canvas. This presentation will outline the optimal use cases for each, will talk about the current state of each technology and will show detailed examples of each in action.

In detail I’m going to cover the core differences between the technologies, the support landscape and then look a little bit at coding in each. Since this is a practical talk, I’ll likely cover some core canvas, D3, Raphael, and Stockcharts/Highcharts. I will probably show a CanvasJS slide since I’ve been working on it again and it’s actually going to be a thing at some point- even if that “thing” is just a novelty me, Bob and Marc worked on.

Reuse and Recycle: SVG

SVG has had a long and strange journey to the world of ‘emerging technologies” SVG was actually defined in 1999, so it’s not exactly the new kid on the block. Still, it took a while to catch on, so in some ways it feels like the new kid on the block. Like Canvas, SVG allows developer sot create graphics in the browser using native web technologies. Unlike Canvas SVG is a vector based grammar and, since it’s defined as XML it also allows for access using common DOM manipulation tools. One of the most difficult issues when dealing with Canvas is the need to manually manage the state, properties and events of individual elements. Since SVG elements are simple DOM elements, properties are stored as part of the regular DOM and access to individual elements is available using traditional DOM access methods like document.geElementById and document.getElementsByTagName.

One driver of popularity for SVG has been the emergence the RaphaelJS library. Raphael provides a convenient API on top of the specification and provides some measure of support for legacy IE browsers by rendering the output of Rapehl instructions as Vector Markup Language (VML.)

The following example shows Raphael and SVG in action. Example output can be seen in the following figure.
Created with Raphaël 2.1.0

The following code sample illustrates using Raphael to draw 10 random circles on an SVG element, filling them with a random gradient fill. The code is quite simple, with a new paper variable containing the instance of Raphael in use and then straightforward methods circle() and attr() used to create circles and fill them with the fancy gradient fill.

<!DOCTYPE html>
<html>
<head>
  <meta charset=UTF-8">
  <title>SVG</title>
</head>
 <style type='text/css'>
    #svg {
    width:100%;
    height:600px;
}
  </style>
</head>
<body>
  <div id="svg"></div>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js'></script>
  <script src='demo.js'></script>

</body>
</html>
window.onload=function(){
var svg = document.getElementById("svg"),
    paper = Raphael( svg ),
    circle,
    width = svg.offsetWidth,
    height = svg.offsetHeight;

for (var i = 0; i < 10; i++) {
  circle = paper.circle(
    parseInt(Math.random() * width), 
    parseInt(Math.random() * height ), 
    parseInt(Math.random() * 200));
  circle.attr({
    "fill": "r" + hex() + "-" + hex(),
    "fill-opacity": "0.5",
    "stroke": "none"
  });
  circle.click(function() {
    console.log(this);
    this.animate({
      cx: parseInt(Math.random() * width),
      cy: parseInt(Math.random() * height),
      r: parseInt(Math.random() * 200)
    }, 1000, "bounce")
  });
}

function hex() {
  //http://paulirish.com/2009/random-hex-color-code-snippets/
  return '#' + Math.floor(Math.random() * 16777215).toString(16);
  }
}

Inspecting the output the underlying markup isn’t quite so succinct, although it should be readable if you’re familiar with XML syntax and can follow along with the code that generated the example. The following code sample shows a single circle marked up using SVG syntax.
The interesting pieces to note are the definition of the radialGradient in the defs element. defs are used for reusable content. You can see it referred to in the circle element’s fill url.

<svg height="400" version="1.1" width="400" xmlns="http://www.w3.org/2000/svg" style="overflow: hidden; position: absolute; left: 0px; top: 0px;">
  <desc>Created with Raphaël 2.1.0</desc>
  <defs>
    <radialGradient id="0r_7d7f2f-_bbb372" fx="0.5" fy="0.5">
      <stop offset="0%" stop-color="#7d7f2f"/>
      <stop offset="100%" stop-color="#bbb372" stop-opacity="0.5"/>
    </radialGradient>
  </defs>
  <circle cx="170" cy="68" r="61" 
          fill="url(#0r_7d7f2f-_bbb372)" 
          stroke="none" 
          style="opacity: 1; fill-opacity: 1;" 
          opacity="1" fill-opacity="1"/>
</svg>

Reuse and Recycle: The Canvas 2D API

The canvas element and associated API started life as an Apple extension to HTML. From there it blossomed into one of the early stars of the HTML5 era. The canvas element provides a scriptable interface for drawing two-dimensional images in the browser. Even without full browser support on the desktop, developers have embraced canvas fully. It’s been used for everything from high traffic visualizations to game engines, a popular system for delivering custom fonts, and a port of the Processing programming language into JavaScript.

While the true power of the Canvas 2d API is beyond the scope of this higher level introduction, it’s worth looking at the API in brief, if just to get a flavor for what it looks like. The following code sample shows a small canvas element and associated JavaScript that draws out a tic-tac-toe game. The simplest piece is the canvas element itself. A canvas element operates much like any other replaced element like a video tag or an image. The big difference is that it lacks a src attribute. The “src” of the canvas image is provided by JavaScript.

<!doctype html>
<html class="no-js" lang="en">
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="_assets/css/style.css">
</head>
<body>
<header>
  <h1>Mobile Web App Cookbook, Canvas</h1>
</header>
<canvas id="ctx" height="300" width="300"></canvas>
<footer>
  <p>&copy; <a href="https://htmlcssjs.wpengine.com/" rel="me">Rob Larsen</a></p>
</footer>
<script src="_assets/js/libs/jquery-1.7.1.min.js"></script>
<script>
//canvas script follows below
</script>

</body>
</html>

The Canvas API is illustrated the in the following script block. It starts by getting a reference to the context of the canvas element. The context is where information about the current rendering state of the element is stored. It contains both the pixel level state of the image as well as various properties and access to core canvas methods used to further manipulate the image. After that you’ll see a variety of basic drawing commends. A path is created using the ctx.beginPath() method and then several context level styles are set. Following that a simple for loop is used to draw lines at regular intervals on the screen. The combination of moving the insertion x/y point of the drawing using ctx.moveTo and drawing the actual line using ctx.lineTo is enough to illustrate the familiar tic-tac-toe board. Following that the “game” is played using a series of text insertions, alternating different fillStyle colors between “turns.”

$( document ).ready(function(){
  var ctx = document.getElementById( "ctx" ).getContext( "2d" ),
  width =  document.getElementById( "ctx" ).width;
  //draw the board
  ctx.beginPath();
  ctx.strokeStyle = '#000';
  ctx.lineWidth = 4;
  for ( var i=1; i < 3; i++ ){   
    ctx.moveTo( ( width / 3 ) * i, 0 );
    ctx.lineTo( ( width / 3 ) * i , width );
    ctx.moveTo( 0, ( width / 3 ) * i );
    ctx.lineTo( width, ( width / 3 ) * i );
  }
  ctx.stroke();
  ctx.closePath(); 
  //"play" the game in order
  ctx.font="80px Arial, Helvetica, sans-serif";
  ctx.fillStyle="#c00";
  ctx.fillText( "x", 130, 170 );
  ctx.fillStyle="#000";
  ctx.fillText( "0", 30, 70 );
  ctx.fillStyle="#c00";
  ctx.fillText( "x", 30, 170 );
  ctx.fillStyle="#000";  
  ctx.fillText( "0", 230, 170 )
  ctx.fillStyle="#c00";;
  ctx.fillText( "x", 130, 70 );
  ctx.fillStyle="#000";  
  ctx.fillText( "0", 130, 270 );
  ctx.fillStyle="#c00";
  ctx.fillText("x", 230, 70 );
  ctx.fillStyle="#000";  
  ctx.fillText( "0", 30, 270 )
  ctx.fillStyle="#c00";;
  ctx.fillText( "x", 230, 270 );
});

This is a simplistic example but it should illustrate the flavor of the API and, hopefully, will get you excited to use some more advanced features.

#$#@ It, We’ll Do It Live.

First off, Happy New Year!

Second off, I finished my second book.

Third off, I’m starting a new job on Monday. More on that later. Teaser? I’ll no longer have to worry about looking too nice at work.

Fourth off, I’m going to try to rework all of my sites this year. Oh snap. I’m starting with this site since it should be a manageable task. I’m working with Skeleton to create a fancy, modern, responsive web site.

Just like the big kids.

As you can see, I’ve already flipped the switch. Release early and often? Something like that. I’m going to customize it over the next few weeks, but after a few hours of tinkering it’s fine for human consumption (that means you, human.)

And, there you have it.

And… the source for the title of this post (NSFW)