<?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>Nefarious Designs &#187; Browsers</title>
	<atom:link href="http://nefariousdesigns.co.uk/tags/browsers/feed/" rel="self" type="application/rss+xml" />
	<link>http://nefariousdesigns.co.uk</link>
	<description>Nefarious Designs is the web development agency and blog of Tim Huegdon, a web developer with over 5 years experience in the industry.</description>
	<lastBuildDate>Fri, 06 Jan 2012 21:37:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>Sniff my browser: The Modernizr inadequacy</title>
		<link>http://nefariousdesigns.co.uk/archive/2011/05/sniff-my-browser-the-modernizr-inadequacy/</link>
		<comments>http://nefariousdesigns.co.uk/archive/2011/05/sniff-my-browser-the-modernizr-inadequacy/#comments</comments>
		<pubDate>Tue, 17 May 2011 11:03:47 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Accessibility]]></category>
		<category><![CDATA[Browsers]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Thoughts]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Web Standards]]></category>

		<guid isPermaLink="false">http://nefariousdesigns.co.uk/?p=654</guid>
		<description><![CDATA[I&#8217;m currently involved in a project to write a fairly extensive set of best practices for front-end development. Alongside myself, this project includes input from a fair cross-section of my peers in the front-end development community. These best practices will be implemented alongside a coding standard as standards for development within the organisation I work [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m currently involved in a project to write a fairly extensive set of best practices for front-end development. Alongside myself, this project includes input from a fair cross-section of my peers in the front-end development community. These best practices will be implemented alongside a coding standard as standards for development within the organisation I work for, and hopefully many other organisations when they are published.</p>
<p>Of all the standards that a front-end team might want to implement, those that concern the identification and graceful degradation of cross-browser feature sets can be the hardest to define.</p>
<p>With that in mind, I&#8217;ve been poking around the front-end community looking for possible solutions. By far the most common approach&#8212;and one that gains an astounding level of attention in the community&#8212;is to implement <a href="http://www.modernizr.com/">Modernizr</a>, a JavaScript feature sniffer created by <a href="http://farukat.es/">Faruk Ate?</a>, <a href="http://paulirish.com/">Paul Irish</a> and <a href="http://alexsexton.com/">Alex Sexton</a>.</p>
<p>Unfortunately, despite my respect for the developers involved, I just can&#8217;t advocate Modernizr as a solution. Let me explain why; but first, let&#8217;s revisit some concepts that are going to be quite relevant…</p>
<p><span id="more-654"></span></p>
<h2 id="the_web_standards_trifle">The web standards trifle</h2>
<p>The separation of structure, presentation, and dynamic behaviour is imperative to web standards. To that end, Andy &#8220;Malarkey&#8221; Clarke wrote a fantastic post detailing a method he liked to use to explain this fact to clients. He entitled it &#8220;<a href="http://www.stuffandnonsense.co.uk/archives/web_standards_trifle.html">the web standards trifle</a>&#8221;.</p>
<p>In Andy&#8217;s metaphor, the separation of concerns can be imagined as follows:</p>
<ol>
<li>
<p><strong>Sponge</strong></p>
<p>This layer is your content, marked-up with well structured and valid semantic HTML. This HTML provides more information about each piece of content and allows any device reading the code to output as appropriate.</p>
</li>
<li>
<p><strong>Fruity jelly</strong></p>
<p>This is your presentational layer. This separates all your presentational code into CSS, potentially allowing a user to override it with their own, or for you to serve something different based on context, e.g. a print or mobile stylesheet.</p>
</li>
<li>
<p><strong>Custard</strong></p>
<p>This is the layer that accommodates any on-page behaviours. In the world of web standards we use this layer to progressively enhance our HTML and CSS layers with more interactive magic. I&#8217;ll come back to this later.</p>
</li>
</ol>
<p>The true virtue of this divide is that the presentational (jelly) and behavioural (custard) layers can potentially be removed or overridden without affecting each other, or the content and markup beneath. This is hugely important if we want our websites to maintain client agnosticism and improve accessibility.</p>
<h2 id="progressive_enhancement">Progressive enhancement</h2>
<p>Following the publication of this article there have been several suggestions that I explain <a href="http://nefariousdesigns.co.uk/archive/2010/10/object-oriented-javascript-follow-up-part-1-method/#graceful_degradation">the difference between <em>graceful degradation</em> and <em>progressive enhancement</em></a>. Suffice to say, this is something I have covered previously in another article.</p>
<h2 id="browser_vs_feature_sniffing">Browser vs. Feature Sniffing</h2>
<p>Browser &#8220;sniffing&#8221; is the act of attempting to discern a user&#8217;s browser by some means. This &#8220;awareness&#8221; can then be used in conditional code to control output or interaction for a specific browser. This technique was used a great deal in days of yore, when browsers had very different rendering engines and didn&#8217;t all conform to web standards. However, it was only ever really required in JavaScript.</p>
<p>The old school way:</p>
<pre><code>if (document.all) {
    // IE4
    height = document.body.offsetHeight;
} else if (document.layers) {
    // NN4
    height = window.innerHeight;
} else {
    // other
    height = 0;
}
</code></pre>
<h3 id="not_a_good_solution">Not a good solution</h3>
<p>There are problems with the method used above; for one thing, it is not the most direct method of identifying a browser. However, putting that aside for the moment, there are issues even with the <em>theory</em> of browser sniffing:</p>
<p>It&#8217;s quite obvious that browser sniffing does not scale. As new browsers are released, the sniffing code will need updating.</p>
<p>To make matters worse, many manufacturers developed their browsers to identify themselves incorrectly to get around <em>legacy</em> browser sniffing code. This ultimately meant that sometimes browsers were misidentified.</p>
<p>Ultimately browser sniffing is not a good solution. If you adopt it, you will usually end up maintaining separate streams of development whenever you need to add or update features. There are ways to mitigate that pain, but what if there was a better solution?</p>
<h3 id="feature_sniffing">Feature sniffing</h3>
<p>A more scalable approach is to use object detection in JavaScript to discover if a feature is available before you use it. An example of this might be:</p>
<pre><code>if (document.querySelector) {
    element = document.querySelector(selectors);
}
</code></pre>
<p>The obvious advantage here is that it is browser agnostic; there are no assumptions as to which browser is involved at all. Using this technique, we overcome the scalability and maintenance headaches incurred through browser sniffing, and we can develop for graceful degradation from the outset.</p>
<h2 id="css_is_a_dsl_that_lacks_features">CSS is a DSL that lacks features</h2>
<p>Now, that&#8217;s all very well and good when we&#8217;re talking about JavaScript, but what happens when we need to affect the presentation layer?</p>
<p>CSS is a very simple <em>domain specific language</em> (DSL) that functions as a series of rules that override each other in a variety of ways (the cascade). There is no mechanism to detect a specific feature or a user-agent; only <a href="http://www.w3.org/TR/CSS2/media.html">media types</a> and potentially the odd CSS hack where a user-agent has imperfectly implemented an interpreter. There are also no conditionals; you just have to use the cascade to provide alternatives based on specificity or even just source order.</p>
<p>With these limitations, it is <strong>impossible</strong> to implement either browser <em>or</em> feature sniffing in CSS. This means we need to find an alternative method to affect the cascade based on the user&#8217;s feature set.</p>
<h2 id="the_modernizr_method">The Modernizr method</h2>
<p>Step in <a href="http://www.modernizr.com/">Modernizr</a>. In the words of <a href="http://www.modernizr.com/docs/">the documentation</a>:</p>
<blockquote>
<p>Modernizr aims to bring an end to the UA sniffing practice. Using feature detection is a much more reliable mechanic to establish what you can and cannot do in the current browser, and Modernizr makes it convenient for you in a variety of ways:</p>
<ol>
<li>
<p>It tests for over 20 next-generation features, all in a matter of milliseconds.</p>
</li>
<li>
<p>It creates a JavaScript object (named Modernizr) that contains the results of these tests as boolean properties.</p>
</li>
<li>
<p>It adds classes to the <code>html</code> element that explain precisely what features are and are not natively supported.</p>
</li>
</ol>
</blockquote>
<p>Following along so far? For the most part, that all seems fairly good. What&#8217;s more, Modernizr is definitely being pushed as the solution of choice amongst the front-end community:</p>
<ul>
<li><a href="http://diveintohtml5.org/detect.html">Mark Pilgrim&#8217;s Dive into HTML5 &#8220;Detection&#8221; chapter</a></li>
<li><a href="http://www.alistapart.com/articles/taking-advantage-of-html5-and-css3-with-modernizr/">Faruk&#8217;s &#8220;Taking Advantage of HTML5 and CSS3 with Modernizr&#8221; on A List Apart</a></li>
<li><a href="http://webdesignernotebook.com/css/how-to-use-modernizr/">Web Designer Notebook: How to use Modernizr</a></li>
<li><a href="http://blogs.sitepoint.com/build-an-awesome-image-gallery-with-jquery-modernizr-and-css3/">Image Gallery tutorial on Sitepoint</a></li>
</ul>
<p>So with all that in mind, let&#8217;s go back to why I will not be recommending Modernizr as a best practice:</p>
<h3 id="sniffing_css_features_with_javascript">Sniffing CSS features with JavaScript</h3>
<p>The real issue is that Modernizr uses JavaScript to do the feature sniffing. This method is absolutely fine if we were only looking to test for the features in JavaScript. However, Modernizr is marketed on its ability to detect CSS3 and HTML5 features so that you can write gracefully degrading CSS:</p>
<blockquote>
<p>Modernizr is a small and simple JavaScript library that helps you take advantage of emerging web technologies (CSS3, HTML 5) while still maintaining a fine level of control over older browsers that may not yet support these new technologies.</p>
</blockquote>
<p>If Modernizr had sold itself as a JavaScript feature sniffing solution that also detected CSS features perhaps I could be more forgiving. In that context, it would be the developers’ responsibility to use Modernizr correctly. However, since the Modernizr site and documentation are selling it <em>specifically</em> as a CSS feature sniffing solution, for primary use within CSS, the error is clearly with the Modernizr team themselves.</p>
<p>It&#8217;s all down to the final step outlined in the documentation I quoted earlier:</p>
<blockquote><p>
 It adds classes to the <code>html</code> element that explain precisely what features are and are not natively supported.
</p></blockquote>
<p>Modernizr uses JavaScript to add those classes to the <code>html</code> element; one for each of the features detected in the current browser. If we examine the generated source we see the following:</p>
<pre><code>&lt;html lang="en" dir="ltr" id="modernizr-com" class=" js flexbox canvas
canvastext webgl no-touch geolocation postmessage websqldatabase indexeddb
hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize
borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns
cssgradients cssreflections csstransforms csstransforms3d csstransitions
fontface video audio localstorage sessionstorage webworkers applicationcache
svg inlinesvg smil svgclippaths"&gt;
</code></pre>
<p>When I first saw that, I was horrified. Not only is it ridiculously cluttered, it also feels decidedly unsemantic and looks like a terminal case of <a href="http://www.sitekin.com/blogdetail/avoid_CSS_Classitis">classitis</a>. However, let&#8217;s try to be pragmatic here; it&#8217;s a means to an end, potentially a minor side-effect to a process that will win us some power in the bigger picture. In fact, it&#8217;s one step on from <a href="http://paulirish.com/2009/avoiding-the-fouc-v3/">Paul Irish&#8217;s proposed work around to the FOUC (flash of unstyled content)</a> which I&#8217;ve advocated as a reasonable fallback to marking progressively enhanced objects with an &#8220;enhanced&#8221; class.</p>
<h3 id="making_use_of_the_classes">Making use of the classes</h3>
<p>The Modernizr method allows you to assign styles based on these new classes on the document&#8217;s root element like so (example lifted from the Modernizr docs):</p>
<pre><code>button.glossy {
   background: #ccc url(gloss.png) 50% 50% repeat-x;
}
.cssgradients button.glossy {
   background: #ccc -webkit-gradient(linear, left top, left bottom,
         from(rgba(255,255,255, .4)),
         color-stop(0.5, rgba(255,255,255, .7)),
         color-stop(0.5, rgba(0,0,0, .2)),
         to(rgba(0,0,0, .1)));
}
.cssgradients button.glossy:hover {
   background-color: #fff;
}
</code></pre>
<p>Here we can see that <code>button.glossy</code> is first defined with a standard <code>png</code> as its background. The Modernizr-added <code>.cssgradients</code> class is then used to increase specificity and assign a WebKit gradient instead.</p>
<p>What happens if we approach the problem <em>without</em> the .cssgradients class:</p>
<p>CSS allows us to define a property twice in the same rule. It also contains built-in error handling that will ignore a property it doesn&#8217;t understand; so browsers that do not understand <code>-webkit-gradient()</code>, for example, will simply ignore a property that uses it. This allows us to progressively enhance our CSS like so:</p>
<pre><code>button.glossy {
   background: #ccc url(gloss.png) 50% 50% repeat-x;
   background: #ccc -webkit-gradient(linear, left top, left bottom,
         from(rgba(255,255,255, .4)),
         color-stop(0.5, rgba(255,255,255, .7)),
         color-stop(0.5, rgba(0,0,0, .2)),
         to(rgba(0,0,0, .1)));
}
button.glossy:hover {
   background-color: #fff;
}
</code></pre>
<p>However, because we can no longer target the <code>.cssgradients</code> class specifically, we cannot target the <code>button:hover</code> styles only when CSS gradients are detected. Clearly this is an issue we&#8217;ll have to find some way around and is exactly what Modernizr is attempting to solve.</p>
<p>This all seems as if Modernizr is giving us a great deal of power, however, it comes with a significant cost.</p>
<h2 id="dependency_on_javascript_is_bad">Dependency on JavaScript is bad</h2>
<p>Fellow web developer and good friend <a href="http://isolani.co.uk/">Mike Davies</a> wrote a really great article containing a good summary of <a href="http://isolani.co.uk/blog/javascript/DisablingJavaScriptAskingTheWrongQuestion#javascript-obstacles">obstacles potentially preventing JavaScript from executing</a> back in October 2010. This followed a somewhat presumptuous post by <a href="http://www.nczonline.net/">Nicholas Zakas</a> on the YDN regarding the <a href="http://developer.yahoo.com/blogs/ydn/posts/2010/10/how-many-users-have-javascript-disabled/">number of users with JavaScript disabled</a>.</p>
<p>In short, there are a large number of obstacles that can affect the execution&#8212;or even rewrite the source of&#8212;JavaScript included in your pages. Hence, dependancy on JavaScript is bad because it introduces many significant points of failure.</p>
<p>As an example of <em>why</em> dependency on JavaScript can be catastrophic, I recommend you read another of Mike&#8217;s posts on <a href="http://isolani.co.uk/blog/javascript/BreakingTheWebWithHashBangs">Gawker&#8217;s JavaScript dependent URIs and how it broke their sites quite considerably</a>. It&#8217;s worth noting that the Gawker sites have since seen the error of their ways and are <a href="http://kotaku.com/5800365/the-first-of-many-updates-to-kotakucom-design-is-live-right-now">attempting to fix the damage</a>.</p>
<h3 id="styling_dependant_on_javascript">Styling dependant on JavaScript</h3>
<p>By adding styles that are specific to classes that have been inserted with JavaScript, we are making those styles dependant on JavaScript. This means those styles will fail to apply if JavaScript itself has been disabled or, more commonly, the JavaScript file applying the classes has failed to load or execute successfully due to one of the reasons above. In essence, we may just as well add those styles with JavaScript directly because we&#8217;ve already broken the web standards separation of concerns.</p>
<p>Do we really want to remove the majority of CSS items covered by Modernizr if the Modernizr JavaScript include fails for some reason?</p>
<p>It would only be the feature-sniff-dependant CSS rules that would fail, since those classes would now be missing. Potentially this only means the loss of a few nice in-browser rendering optimisations. However, it also means there is a significant loss in the overall structure of specificity within your stylesheets, which could easily cascade unintended effects through to other elements. This could easily result in some content being styled to be unreadable, or worse, incorrectly hidden. This would be very bad indeed.</p>
<h2 id="alternative_solutions">Alternative solutions</h2>
<p>Modernizr is clearly unfit for purpose. If it were simply a JavaScript feature sniffing library for use <em>only</em> in JavaScript, it would be a suitable solution although only really useful for JavaScript progressive enhancement.</p>
<p>With that in mind, what other options are available that allow us to target our CSS?</p>
<h3 id="server_side_browser_sniffing">Server-side browser sniffing</h3>
<p>We could browser sniff on the server and add a class to the <code>html</code> element as we generate the HTML that is delivered in the HTTP response. This could result in something like the following:</p>
<pre><code>&lt;html lang="en" dir="ltr" class="firefox"&gt;
</code></pre>
<p>This means we can target CSS with the <code>.firefox</code> class in much the same way that we used the feature classes that Modernizr provided. There is no way for us to perform feature sniffing on the server; the best we could offer is a feature lookup based on the user-agent string that we&#8217;ve used to sniff the browser, but that would ultimately still be browser sniffing.</p>
<p>In fact, the best browser sniffing solution would allow us a little more flexibility on browser versions:</p>
<pre><code>&lt;html lang="en" dir="ltr" class="moz ff ff3-6"&gt;
</code></pre>
<p>Note I&#8217;ve added several classes this time; one for the rendering engine, one for the browser, and one that contains the major and minor versions. This would allow us more specificity.</p>
<p style="padding:10px;background:#fee;border:1px solid #c00;"><strong>Update:</strong> Matthew Pennell has written an interesting post on <a href="http://www.thewatchmakerproject.com/blog/no-more-css-hacks-browser-sniffing-with-htaccess/">server-side browser sniffing with .htaccess and environment variables</a>. Definitely worth a read.</p>
<h4 id="cache_issues">Cache issues</h4>
<p>However, server-side browser sniffing means that you&#8217;ll run into issues if your pages are publicly cacheable. This server-side solution results in a different HTTP response (the HTML) for each differing browser.</p>
<p>If you utilise any intermediary caching (<a href="http://www.squid-cache.org">Squid</a>, <a href="http://www.varnish-cache.org">Varnish</a>, or a custom origin CDN) for static pages, and you use server-side browser detection, you need to make sure those caches don&#8217;t inadvertently send the wrong content to the wrong browser. To do this you&#8217;ll need to <code>Vary: User-Agent</code> header in the HTTP response. This instructs any intermediary caches to store multiple copies of the page (one for each <code>User-Agent</code> string that it sees) and to inspect the incoming <code>User-Agent</code> string when looking for cached responses to the current request.</p>
<h3 id="ie_targeting_with_conditional_comments">IE targeting with conditional comments</h3>
<p>If we&#8217;re entirely honest with ourselves as web developers, we can probably admit that the majority of woes we experience in CSS are as a direct result of features that any given version of Internet Explorer has not implemented. In fact, I regularly interview developers who advocate maintaining a separate stylesheet for IE that is included through the use of IE&#8217;s conditional comments. Having attempted to use this method in the past, I can confidently say that it is a maintenance nightmare and quickly becomes pretty unmanageable.</p>
<p>A better technique would be to adopt conditional comments to add IE specific classes in much the same way we have with Modernizr or server-side browser sniffing. This method was first proposed by none other than Paul Irish back in 2008 in his article &#8220;<a href="http://paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/">Conditional stylesheets vs. CSS hacks? Answer: neither</a>&#8220;. With that method, our <code>html</code> element would look like this:</p>
<pre><code>&lt;!--[if IE ]&gt;
&lt;html lang="en" dir="ltr" class="ie"&gt;
&lt;![endif]--&gt;
&lt;!--[if !IE]&gt;--&gt;
&lt;html lang="en" dir="ltr"&gt;
&lt;!--&lt;![endif]--&gt;
</code></pre>
<p>This looks a bit odd, and often (for the true markup perfectionist) takes a bit of getting used to. However, it does give us what we need without requiring JavaScript or multiple cache versions.</p>
<p>We can even make it more specific if we so desire:</p>
<pre><code>&lt;!--[if lt IE 7 ]&gt;
&lt;html lang="en" dir="ltr" class="ie ie6"&gt;
&lt;![endif]--&gt;
&lt;!--[if IE 7 ]&gt;
&lt;html lang="en" dir="ltr" class="ie ie7"&gt;
&lt;![endif]--&gt;
&lt;!--[if IE 8 ]&gt;
&lt;html lang="en" dir="ltr" class="ie ie8"&gt;
&lt;![endif]--&gt;
&lt;!--[if IE 9 ]&gt;
&lt;html lang="en" dir="ltr" class="ie ie9"&gt;
&lt;![endif]--&gt;
&lt;!--[if gt IE 9]&gt;
&lt;html lang="en" dir="ltr" class="ie"&gt;
&lt;![endif]--&gt;
&lt;!--[if !IE]&gt;&lt;!--&gt;
&lt;html lang="en" dir="ltr"&gt;
&lt;!--&lt;![endif]--&gt;
</code></pre>
<p>Quite clearly this gets ever uglier, but the solution is entirely encompassed in the structural layer; we will always have the correct class, even if CSS or JavaScript are unavailable for some reason. We also have the same markup regardless of user-agent string, which means caching is not a problem.</p>
<p>The only flaw with this solution is that we can only target versions of Internet Explorer. No other browser implements conditional comments.</p>
<h3 id="use_css_properly_and_make_use_of_the_cascade">Use CSS properly and make use of the cascade</h3>
<p>As previously stated, CSS is designed to cascade. This means the built-in error handling will ignore properties the interpreter does not understand, and we can override rules based on specificity and source order. In most cases, these key features are more than adequate to develop gracefully degrading stylesheets.</p>
<p>Most capable front end developers are already doing this and coping just fine. Add this to the previous IE targeting approach and you&#8217;ll find that you do not need to over-engineer a solution.</p>
<h2 id="in_summary">In summary</h2>
<p>So, in summary then, I absolutely cannot recommend implementing Modernizr as a best practice for front end development. It attempts to solve a problem from the wrong direction, and introduces a new potential point of failure. What&#8217;s more it breaks the fundamental ethic of web standards; the separation of concerns.</p>
<p>I continue to recommend well crafted, gracefully degrading CSS, backed up by conditional commented classes on the <code>html</code> element for targeting IE.</p>
<p>Modernizr may still be a worthy solution for JavaScript-only feature sniffing, if only it allowed the developer to disable the injection of classes on the <code>html</code> element.</p>
]]></content:encoded>
			<wfw:commentRss>http://nefariousdesigns.co.uk/archive/2011/05/sniff-my-browser-the-modernizr-inadequacy/feed/</wfw:commentRss>
		<slash:comments>44</slash:comments>
		</item>
		<item>
		<title>Fixing label in Safari</title>
		<link>http://nefariousdesigns.co.uk/archive/2007/08/fixing-label-in-safari/</link>
		<comments>http://nefariousdesigns.co.uk/archive/2007/08/fixing-label-in-safari/#comments</comments>
		<pubDate>Thu, 30 Aug 2007 09:46:33 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Accessibility]]></category>
		<category><![CDATA[Browsers]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://nefariousdesigns.co.uk/archive/2007/08/fixing-label-in-safari/</guid>
		<description><![CDATA[Safari, the excellent WebKit-based browser from Apple, has long neglected to include functionality that activates a form element (such as an input, a textarea, a select etc.) when its relevant label is clicked. Although this behaviour has been fixed in the beta of version 3, any users still browsing with version 2 or below still [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.apple.com/safari/">Safari</a>, the excellent WebKit-based browser from Apple, has long neglected to include functionality that activates a form element (such as an <code>input</code>, a <code>textarea</code>, a <code>select</code> etc.) when its relevant <code>label</code> is clicked.</p>
<p>Although this behaviour has been fixed in the beta of version 3, any users still browsing with version 2 or below still suffer this needless blight on web accessibility.</p>
<p>I&#8217;ve recently reworked the JavaScript used in <a href="http://nascentguruism.com/journal/search-and-ye-shall-fail">Steve Marshall&#8217;s tasty channelled search solution</a>, which requires the <code>label</code> to be clickable, as it hides the corresponding radio <code>input</code>. For this reason, I&#8217;ve written a quick bit of JavaScript to activate this behaviour.</p>
<p><span id="more-172"></span></p>
<h2>The Requirements</h2>
<p>As a Yahoo! developer, I&#8217;ve written this implementation using the YUI JavaScript library. There&#8217;s really no reason why you couldn&#8217;t re-jig it to work with any other JS library &#8212; including one you&#8217;ve written yourself.</p>
<p>The YUI objects we will require are: <a href="http://developer.yahoo.com/yui/yahoo/">the YAHOO Global Object</a> and <a href="http://developer.yahoo.com/yui/event/">the Event Utility</a>. To include these files (in their minified form), insert the following lines of code in the <code>head</code> of your html document:</p>
<pre><code>&lt;script type="text/javascript" src="http://yui.yahooapis.com/2.3.0/build/yahoo/yahoo-min.js" &gt;&lt;/script&gt;
&lt;script type="text/javascript" src="http://yui.yahooapis.com/2.3.0/build/event/event-min.js" &gt;&lt;/script&gt;</code></pre>
<p>Alternatively, if you wish to include more of the YUI objects, you can use one of the following files:</p>
<pre><code>&lt;script type="text/javascript" src="http://yui.yahooapis.com/2.3.0/build/yahoo-dom-event/yahoo-dom-event.js"&gt;&lt;/script&gt;</code>

or

<code>&lt;script type="text/javascript" src="http://yui.yahooapis.com/2.3.0/build/utilities/utilities.js"&gt;&lt;/script&gt;</code></pre>
<p>The <code>yahoo-dom-event.js</code> file contains only the YAHOO Global Object, <a href="http://developer.yahoo.com/yui/dom/">the DOM collection</a>, and the Event Utility.</p>
<p>The <code>utilities.js</code> file includes the YAHOO Global Object, the DOM collection, the Event Utility, <a href="http://developer.yahoo.com/yui/element/">the Element utility</a>, <a href="http://developer.yahoo.com/yui/connection/">the Connection Manager</a>, <a href="http://developer.yahoo.com/yui/dragdrop/">the Drag &amp; Drog utility</a>, and <a href="http://developer.yahoo.com/yui/animation/">the Animation utility</a>.</p>
<p>Personally, I tend to include the utilities.js file so that I have as much of the YUI functionality included as I may need. In the essence of avoiding script bloat though, I would recommend including only what you need.</p>
<h2>The Method</h2>
<p>We want to activate a form element when its corresponding label is clicked, so we need to bind an <code>onclick</code> event to any <code>label</code> elements within our page. To do this, we can either loop through all <code>label</code> elements in the <acronym title="Document Object Model">DOM</acronym>, and attach a separate event to each of them; or we can attach a single <code>onclick</code> event to the <code>body</code> of our page and use &#8220;<a href="http://icant.co.uk/sandbox/eventdelegation/">event delegation</a>&#8221; to discover our target element (the <code>label</code>) &#8212; a nice side effect of &#8220;event bubbling&#8221;.</p>
<p>If we click a <code>label</code> element in our page, the onclick event doesn&#8217;t occur on just that element alone; it bubbles up the DOM tree through each of the <code>label</code> element&#8217;s parents. This means an onclick event will fire on the <code>form</code> element, any container elements (<code>div</code> elements, for example), and finally the <code>body</code> element because, in effect, we&#8217;ve clicked all these elements as well.</p>
<p>Event delegation is the process of discovering the element at the bottom of the event bubbling tree &#8212; the &#8220;target&#8221; element. This is fairly straight forward and requires only a few lines of code, whether you&#8217;re using a JavaScript library or not.</p>
<p>Using event delegation will require less code, less memory, and will ultimately run much faster. This is because we do not need to discover all <code>label</code> elements in the page in one go. If we used the other method, our script would become slower and slower the more <code>label</code> elements were included in the page.</p>
<p>Once we have our target element, we can make sure it&#8217;s a <code>label</code>, obtain the form element it&#8217;s related to, and finally activate that element.</p>
<h2>The Code</h2>
<p>Firstly, we need to create our namespace. In this case, I&#8217;ve decided to create an extra layer entitled &#8220;browserfix&#8221; because we&#8217;re essentially fixing an oversight in the browser. Creating the extra layer means that I could possibly bind other browser fixes to the same namespace (although, if we were trying to improve <acronym title="Microsoft Internet Explorer">IE</acronym>, that namespace could get pretty big).</p>
<p>To create our namespace, we do the following:</p>
<pre><code>NEF = window.NEF || {};
NEF.browserfix = window.NEF.browserfix || {};</code></pre>
<p>This either reuses existing objects, or creates new ones using the object literal.</p>
<p>Next we bind a method to our browserfix object to encapsulate our code:</p>
<pre><code>NEF.browserfix.Label = function() {
  &hellip;
}</code></pre>
<p>The first thing our method needs to do is bind an event to the <code>body</code> element of our page. To do this, we use the <code>addListener</code> method of the YUI Event Utility:</p>
<pre><code>YAHOO.util.Event.addListener(document.body, "click", function(e) {
  &hellip;
});</code></pre>
<p><a href="http://developer.yahoo.com/yui/docs/YAHOO.util.Event.html#addListener">The <code>addListener</code> method</a> expects three parameters by default; the element we wish to attach our event listener to (<code>document.body</code>), the event we&#8217;re listening for (&#8220;click&#8221; &#8212; we remove the &#8220;on&#8221; because only certain specific browsers require it and the <code>addListener</code> method will handle that for us), and the function we want to bind to that event (in this case, an anonymous &#8212; or &#8220;lambda&#8221; &#8212; function). We can also pass an arbitrary object to that function (should it require parameters), or scope the execution of our listener to a specific object. In this case, we&#8217;re not doing either of those.</p>
<p>Now we&#8217;ve bound a function to the event we need to populate it with some functionality. Incidentally, the <code>e</code> parameter that is passed to our function is an identifier of type &#8220;Event&#8221;. This is a special object that contains contextual information about the event. You can find out more about this in <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventListener">the W3C docs for the EventListener interface</a>.</p>
<p>The first thing we need to do is work out which element we originally clicked; which is surprisingly straightforward. Using the getTarget method of the YUI Event Utility, we can get that element in a single line &#8212; in fact, without the YUI, this code is still surprisingly simple; the YUI just sorts out all those nasty cross-browser differences for us:</p>
<pre><code>YAHOO.util.Event.addListener(document.body, "click", function(e) {
  var target = YAHOO.util.Event.getTarget(e);
  &hellip;
});</code></pre>
<p>The <code>getTarget</code> method returns the element at the bottom of our event bubbling tree and requires only a single parameter; that special &#8220;Event&#8221; object I was talking about earlier. It needs this to identify which event we&#8217;re tracking. In effect, we&#8217;re passing the event from function to function.</p>
<p>If you&#8217;re interested in the code behind <code>getTarget</code>, I&#8217;d recommend delving into the <a href="http://developer.yahoo.com/yui/docs/Event.js.html">YUI Event Utility code in the API documentation</a>.</p>
<p>Now that we&#8217;ve obtained our clicked element, we need to check to see whether it&#8217;s a <code>label</code>; and if it isn&#8217;t, we return harmlessly &#8212; allowing default behaviour and other events to continue regardless. To do this, we&#8217;ll do a comparison on the <code>tagName</code> property of the element, which we&#8217;ll convert to uppercase to combat case sensitivity:</p>
<pre><code>if (target.tagName &#038;&#038; target.tagName.toUpperCase() !== "LABEL") {
  return;
}</code></pre>
<p>To force a best practice of using <em>explicitly</em> defined label elements, we make the assumption that the <code>htmlFor</code> property will exist. If it doesn&#8217;t, the JavaScript will throw an error &#8212; which is a good thing. Obviously, we could check for the existence of the htmlFor property, or even write a DOM walking loop to handle <em>implicitly</em> defined label elements; but, to be honest, that would be slow and cumbersome, and would allow for a situation we don&#8217;t really want. This assumption allows us to return a <em>new</em> target element; that which is referred to in the <code>for</code> attribute of the opening <code>label</code> tag in our HTML:</p>
<pre><code>target = document.getElementById(target.htmlFor);</code></pre>
<p>Finally, we need to activate our new target element. For most elements, this will involve simply firing the <code>focus</code> method, but if our element is an <code>input</code> of <code>type</code> &#8220;radio&#8221; or &#8220;checkbox&#8221;, we&#8217;ll need to fire the <code>click</code> method:</p>
<pre><code>if (target) {
  if (target.type) {
    switch (target.type) {
      case "radio":
      case "checkbox":
        target.click();
        break;
      default:
        target.focus();
        break;
    }
  } else {
    target.focus();
  }
}</code></pre>
<p>First we check for the existence of the target element &#8212; if it doesn&#8217;t exist, we don&#8217;t want to attempt doing anything. Next we check for the existence of a <code>type</code> property &#8212; this will tell us whether we&#8217;re dealing with an <code>input</code> element or not. If we <em>are</em> dealing with an <code>input</code> element, we perform a <code>switch</code> statement on the <code>type</code> property to ascertain what sort of <code>input</code> we&#8217;re dealing with. If we&#8217;re dealing with a &#8220;radio&#8221; or a &#8220;checkbox&#8221;, we utilise the fall-through behaviour of the <code>switch</code> statement to fire the <code>click</code> method. Also, because we&#8217;re using fall-through, we make sure we supply the <code>switch</code> statement with a <code>default</code> clause that fires the <code>focus</code> method. Finally, if our target <em>doesn&#8217;t</em> have the <code>type</code> property, we also fire the <code>focus</code> method.</p>
<p>Lastly, we run our function when the DOM is in a usable state, using the <a href="http://developer.yahoo.com/yui/event/#ondomready">YUI onDOMReady method</a>:</p>
<pre><code>YAHOO.util.Event.onDOMReady(NEF.browserfix.Label);</code></pre>
<p>Rather than waiting for a <code>window.onload</code> event (which will have to wait for images to load etc.), this will trigger our function as soon as the DOM is loaded thus making sure the behaviour is available as soon as possible.</p>
<p>So here&#8217;s all that code in full:</p>
<pre><code>NEF = window.NEF || {};
NEF.browserfix = window.NEF.browserfix || {};
NEF.browserfix.Label = function() {
  YAHOO.util.Event.addListener(document.body, "click", function(e) {
    var target = YAHOO.util.Event.getTarget(e);
    if (target.tagName &#038;&#038; target.tagName.toUpperCase() !== "LABEL") {
      return;
    }
    target = document.getElementById(target.htmlFor);
    if (target) {
      if (target.type) {
        switch (target.type) {
          case "radio":
          case "checkbox":
            target.click();
            break;
          default:
            target.focus();
            break;
        }
      } else {
        target.focus();
      }
    }
  });
};

YAHOO.util.Event.onDOMReady(NEF.browserfix.Label);</code></pre>
<p>And for anyone browsing with Safari, <a href="http://nefariousdesigns.co.uk/projects/labelfix/">here&#8217;s a handy demo of <code>NEF.browserfix.Label</code> in action</a>&hellip;</p>
]]></content:encoded>
			<wfw:commentRss>http://nefariousdesigns.co.uk/archive/2007/08/fixing-label-in-safari/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Semantics and Structure</title>
		<link>http://nefariousdesigns.co.uk/archive/2007/03/semantics-and-structure/</link>
		<comments>http://nefariousdesigns.co.uk/archive/2007/03/semantics-and-structure/#comments</comments>
		<pubDate>Mon, 05 Mar 2007 10:54:12 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Accessibility]]></category>
		<category><![CDATA[Browsers]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Web Standards]]></category>
		<category><![CDATA[XHTML]]></category>

		<guid isPermaLink="false">http://nefariousdesigns.co.uk/archive/2007/03/semantics-and-structure/</guid>
		<description><![CDATA[I&#8217;m currently working on improving nefariousdesigns.co.uk &#8211; both in design and in technology. I&#8217;ve continued to learn lots of great web development &#8220;stuff&#8221; over the past year, and it&#8217;s time I updated my personal site to reflect that burgeoning knowledge. My first port of call is the underlying structure of my HTML &#8211; it&#8217;s ok, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m currently working on improving nefariousdesigns.co.uk &#8211; both in design and in technology. I&#8217;ve continued to learn lots of great web development &#8220;stuff&#8221; over the past year, and it&#8217;s time I updated my personal site to reflect that burgeoning knowledge.</p>
<p>My first port of call is the underlying structure of my HTML &#8211; it&#8217;s ok, but it could definitely be improved.</p>
<p>I recently had a fantastic conversation with <a href="http://www.heavydog.co.uk/">Mike Pearce</a> &#8211; an old colleague (who&#8217;s now a good friend) &#8211; regarding document structure in HTML. Whilst peer-reviewing some of his code, I noticed some not-uncommon structural characteristics that, although not wrong, definitely didn&#8217;t convey the best semantics within the document. For this reason I thought I&#8217;d document some of the stuff I&#8217;ve learned about structured HTML and open it up for comment.</p>
<p><span id="more-161"></span></p>
<h2>The Point</h2>
<p>So what do we gain from enforcing good structure in our HTML documents? Well, to begin with, it aids accessibility by describing and organising our content. This means that screen readers, normal browsers, and even search engines are able to understand our content and can navigate and classify it better.</p>
<p>Good structure is often overlooked as being important because we can easily emulate it visually with styling &#8211; in fact it&#8217;s often the case that a badly structured HTML document is, in fact, <em>inferring</em> structure using paragraphs or table cells <em>styled</em> as headings. This is simply down to developers not understanding the importance of structure within HTML. A well structure HTML document is the base for good web standards, as it allows us to set out an organised template for more semantic content. In fact, it&#8217;s the very <em>beginning</em> of semantics.</p>
<h2>Semantics</h2>
<p>Semantic is one of those words you&#8217;ll hear a lot from web standards developers and standardistas; it defines our existence and, without it, we&#8217;d all suffer an existential crisis and degrade into a depressed rabble of alcoholics&hellip; oh wait&hellip;</p>
<p>In all seriousness, it&#8217;s a word I&#8217;ve heard people use without truly understanding the meaning. So let&#8217;s take a look at a dictionary definition:</p>
<blockquote><p>seÂ·manÂ·tic<br />
<em>adj.</em></p>
<ol>
<li>Of or relating to meaning, especially meaning in language.</li>
<li>Of, relating to, or according to the science of semantics.</li>
</ol>
</blockquote>
<p>Great &#8211; but what does it mean in regard to HTML? Well basically, it means using HTML <em>properly</em> &#8211; to describe our content with the elements supplied in our HTML DocType; rather than describing presentation. Good HTML should be as semantically correct as possible, which means using elements that describe headings, lists, content inflection, and organisation, instead of using elements to arrange content visually. A good example of this would be table-based design. Once our content is described properly using semantic HTML, we can improve presentation using external stylesheets.</p>
<h2>Perception</h2>
<p>To really understand the importance of structure in our HTML documents, you need to alter your perception. I&#8217;m not talking about taking excessive amounts of mind-altering drugs (unless that kind of thing floats your boat &#8211; I&#8217;ve met a few space-cadet web developers in my time), but simply changing your point of view in regard to your vision of the internet.</p>
<p>As humans, we&#8217;ve begun to perceive the internet as a series of sites, when in fact it is nothing more than a complex network of single pages; totally oblivious to the domain and file structures we use to organise them. Each page is mutually exclusive; it exists as a single entity and links to many similar entities. As humans, we perceive <em>sites</em> because they imply organisation; browsers and search engines only see pages and are generally unconcerned with site structure. This means that each page is a unique document and, as such, may require structure to make sense within context.</p>
<p>This is also the case for anyone landing on our sites from search engines &#8211; the site structure is not instantly conveyed, yet the structure of the single page is. If we want people to understand the page they are looking at, we need to organise it accordingly.</p>
<h2>Headings</h2>
<p>Heading elements are our key method of outlining structure. Much like any other type of document we may be writing, headings allow us to develop a document map &#8211; a set of titles for key points or content groupings. This map of our document could be compared to the &#8220;contents&#8221; section of a text book, since it outlines the hierarchy of our content &#8211; and in some cases, could even be used for navigation purposes.</p>
<p>A handy tool I&#8217;ve discovered for viewing the structure of a page is the <a href="https://addons.mozilla.org/firefox/475/">Document Map Extension for Firefox</a>. If you&#8217;re using Firefox, I recommend you install it and have a bit of a play &#8211; it will help you to visualise what I&#8217;m talking about!</p>
<h2>The Heading Elements</h2>
<p>HTML provides us with six heading elements; <code>&lt;h1&gt;</code> through to <code>&lt;h6&gt;</code>. It&#8217;s invalid to start with anything but an <code>&lt;h1&gt;</code> since our heading tags are required <em>in order</em> by the DocType. A basic structure might <em>only</em> need <code>&lt;h1&gt;</code> elements. Here&#8217;s an example:</p>
<pre><code>&lt;h1&gt;Introduction&lt;/h1&gt;

&lt;p&gt;This is the beginning of our document. This could be
any kind of content you so desired - but it would all
fall under the heading "Introduction".&lt;/p&gt;

&lt;h1&gt;Summmary&lt;/h1&gt;

&lt;p&gt;This is another section. Note that, in this example,
both "Summary" and "Introduction" exists at the same
level in the hierarchy&lt;/p&gt;</code></pre>
<p>Should we need to, we can add further layers to our hierarchy using the extra heading elements like so:</p>
<pre><code>&lt;h1&gt;The Ten Word Review&lt;/h1&gt;

&lt;h2&gt;What is it?&lt;/h2&gt;

&lt;p&gt;It's an excellent site where users review various
things in 10 words. No more, no less.&lt;/p&gt;

&lt;h2&gt;What's the point?&lt;/h2&gt;

&lt;h3&gt;Information Resource&lt;/h3&gt;

&lt;p&gt;Find out what other people think about something.&lt;/p&gt;

&lt;h3&gt;Voice Your Opinion&lt;/h3&gt;

&lt;p&gt;Speak your mind as succinctly as possible.
Voice your opinion without all that needless waffle.&lt;/p&gt;

&lt;h2&gt;Where can I find it?&lt;/h2&gt;

&lt;p&gt;That's easy - you can find it here:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://thetenwordreview.com"&gt;
  The Ten Word Review
&lt;/a&gt;&lt;/p&gt;</code></pre>
<p>Here you can see that a good peppering of heading elements allows us to structure our document meaningfully. Obviously it&#8217;s of more use when there&#8217;s a lot more content, but I hope you get the idea.</p>
<p>Notice that the numbers in the heading elements correspond to the level of the heading within the page &#8211; not their order of importance as content. This is a common mistake that I&#8217;ve seen made in the past and it&#8217;s a fundamental misunderstanding of the elements themselves. It&#8217;s also worth pointing out that, even though a site-wide heading (like &#8220;Bedtime Reading&#8221; on this site) may be an <code>&lt;h2&gt;</code> on one page, there&#8217;s no reason it shouldn&#8217;t be a different level on different page. For this reason, it&#8217;s worthwhile thinking about content structure well before you start styling things up with CSS. I&#8217;ve always been a proponent of markup before styling and this is a good example of where this method is particularly valid.</p>
<p>Understanding the heading elements is the key to applying structure. The real problems arise when we try to decide <em>where</em> to place those elements. This is the most common stumbling block for web developers.</p>
<h2>Rules of Engagement</h2>
<p>When trawling through the burgeoning number of standards-based sites on the internet, I&#8217;ve noticed that most developers place the title of the site within an <code>&lt;h1&gt;</code> element. For home pages, this is certainly the correct thing to do; but on other pages in the site, it really isn&#8217;t.</p>
<p>Unfortunately, this phenomenon is a side-effect of visualising site structure instead of page structure &#8211; as developers we&#8217;re always aware that the page we&#8217;re developing is situated <em>within</em> our site, therefore we surmise that the site name is always our top-level heading. This is definitely something I&#8217;m personally guilty of in my current structure and is one of the first things I&#8217;m going to address with my redesign/realign.</p>
<p>If we alter our perception and view our site as a number of unique (yet still related) pages, we begin to understand that the title of the page itself should be our top-level heading (the <code>&lt;h1&gt;</code> element). In fact, as a side-note, if you make sure the <code>title</code> element and your first <code>&lt;h1&gt;</code> element match, you&#8217;re instantly boosting your SEO. This is because, as I pointed out earlier, search engines have less concept of your <em>site</em> structure than they do of your <em>page</em> structure.</p>
<h2>Case Study</h2>
<p>With all this in mind, let&#8217;s take a look at the home page of this site:</p>
<p><a href="/blog/images/nefarious-designs.jpg" rel="lightbox"><img src="/blog/images/nefarious-designs-small.jpg" alt="A small image of Nefarious Designs' home page" class="framed" /></a></p>
<p>So what do I use as the top-level heading on this page? Obviously I don&#8217;t have the words &#8220;home page&#8221; anywhere in the content &#8211; and why should I? It&#8217;d be pretty meaningless in terms of context; the best heading to use here is the title of the site, since the home page is an overview of that. In this particular instance I&#8217;d like to use a logo graphic as the heading, rather than just plain text, so I am presented with a number of options. For instance, I could wrap the text &#8220;Nefarious Designs&#8221; in the <code>&lt;h1&gt;</code> element and then use image replacement in CSS to introduce the logo; or (the option I chose) I can wrap the logo image in the <code>&lt;h1&gt;</code> element &#8211; this is still perfectly valid HTML. I chose this option because the graphic has importance as my logo &#8211; if it were simply a graphical representation of heading text, I&#8217;d probably have used image replacement.</p>
<p>Now that I have defined my top-level heading, I usually do a quick scan of the content to make sure there are no more headings that I wish to exist at the same level. This does not occur often but it&#8217;s always worth checking. In the case of my home page (and for most other home pages), I want the title of the entire site to exist at that level, as discussed before. The next step is to look at the next level of headings.</p>
<p>The next level of headings are associated with my content modules &#8211; these are defined chunks of related information that I organised together when defining my information architecture. These include the latest three posts, my portfolio, my del.icio.us feed, my flickr feed and my bedtime reading &#8211; these are all completely different groups of content and, as such, deserve to be categorised beneath different headings. This method continues within my content &#8211; needless to say I probably don&#8217;t need to go any further for you to understand my methodology; in fact, if you&#8217;re interested in seeing further levels of heading, you&#8217;re probably best off looking at the source behind one of my posts.</p>
<p>Within the text of my posts, the actual post title is the most important element and is marked up as such. In this particular type of page I no longer require the importance I bestowed upon the site title on the home page, since it is not really as relevant here. In fact, I&#8217;m more likely to place the title of the post in the title element, therefore I should think about doing the same in my <code>&lt;h1&gt;</code> element. Further headings beneath this will reflect this change in structure &#8211; this does, however, mean that we can&#8217;t use any headings before our <code>&lt;h1&gt;</code>; but if you think about it, this makes perfect sense since the title of the page should always be the first heading.</p>
<p>Finally our content modules, which are repeated from the homepage, have the choice of being marked up at the same level as my post title; or I could mark them up as a level below since they are content items within a page with that title. In fact, it&#8217;s probably preferable to use this method as the content is repeated throughout the site and should probably maintain a constant structure.</p>
<h2>Summary</h2>
<p>Currently the document map of each page of my site is structured more towards the site than the page itself. This ultimately means that my document structure is inefficient and confusing. By correcting this I will improve both the accessibility of my pages and their search engine optimisation. Both of these goals are key when redesigning my site.</p>
<p>Hopefully, using my own site as an example, I&#8217;ve laid out the fundamentals of document structure; and equally how important it is to good web standards development. By improving our understanding of document maps we can improve our pages for navigation by <em>all</em> our users and their respective internet browsing clients; be they standard browsers, screen-readers, or even search engine robots. You can also see how easy it is to improve your structure by taking these things into account &#8211; and also how easy it is to get it wrong without realising.</p>
]]></content:encoded>
			<wfw:commentRss>http://nefariousdesigns.co.uk/archive/2007/03/semantics-and-structure/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Firefox 2.0</title>
		<link>http://nefariousdesigns.co.uk/archive/2006/10/firefox-20/</link>
		<comments>http://nefariousdesigns.co.uk/archive/2006/10/firefox-20/#comments</comments>
		<pubDate>Thu, 26 Oct 2006 08:46:59 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Browsers]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://nefariousdesigns.co.uk/archive/2006/10/firefox-20/</guid>
		<description><![CDATA[Internet Explorer 7 has been on full release for about a week now and Mozilla have managed to jump on the proverbial bandwagon and release Firefox 2.0. If you haven&#8217;t already downloaded it, you can find it here: http://getfirefox.com I was originally writing a blog post on getting FF2 to run simultaneously with FF1.5 (for [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://getfirefox.com" title="Get Firefox!"><img src="http://nefariousdesigns.co.uk/blog/images/firefox.gif" alt="Firefox Logo" class="framed pos2" /></a></p>
<p><a href="http://www.microsoft.com/windows/ie/default.mspx">Internet Explorer 7</a> has been on full release for about a week now and Mozilla have managed to jump on the proverbial bandwagon and release <a href="http://getfirefox.com">Firefox 2.0</a>. If you haven&#8217;t already downloaded it, you can find it here:</p>
<p><a href="http://getfirefox.com">http://getfirefox.com</a></p>
<p>I was originally writing a blog post on getting FF2 to run simultaneously with FF1.5 (for testing purposes), but <a href="http://muffinresearch.co.uk/archives/2006/10/25/run-firefox-20-and-15-side-by-side/">Stupot beat me to it</a>. So instead, I&#8217;m collating a short list of resources to help you get the most out of Firefox 2.0.</p>
<p><span id="more-139"></span></p>
<h2>Resources</h2>
<ul>
<li><a href="http://muffinresearch.co.uk/archives/2006/10/25/run-firefox-20-and-15-side-by-side/">Run Firefox 2.0 and 1.5 Side-By-Side</a> &#8211; Handy for all that browser compatibility testing.</li>
<li><a href="http://www.lifehacker.com/software/firefox-2/geek-to-live-top-firefox-2-config-tweaks-209941.php">Top Firefox 2.0 Config Tweaks</a> &#8211; Learn how to force FF to restore your tab session even without a crash.</li>
<li><a href="https://addons.mozilla.org/firefox/60/">Web Developer Toolbar Extension</a> &#8211; Invaluable for web developers. If you haven&#8217;t already got this, you need it.</li>
<li><a href="http://ietab.mozdev.org/">IE Tab Extension</a> &#8211; Run IE in a Firefox tab. Brilliant. Saves on all those superfluous browser windows.</li>
<li><a href="http://www.standards-schmandards.com/projects/fangs">Fangs Screen Reader Emulator Extension</a> &#8211; Handy for accessibility testing but not replacement for the real thing.</li>
<li><a href="https://addons.mozilla.org/firefox/1843/">Firebug Error Console/Debugger Extension</a> &#8211; Forget about ConsoleÂ², this is the console of choice.</li>
<li><a href="http://users.skynet.be/mgueury/mozilla/">HTML Validator Extension</a> &#8211; Validates your (X)HTML whilst you work. A wonderful time saver.</li>
<li><a href="http://blog.codeeg.com/tails-firefox-extension-03/">Tails Microformats Extension</a> &#8211; Microformats are the next big thing. Tails will let you know when there are Microformats present.<strong>Update:</strong> It would appear that Tails hasn&#8217;t been properly ported to FF2.0 as yet, and, as a result, suffers some rather strange behaviour.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://nefariousdesigns.co.uk/archive/2006/10/firefox-20/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Debrief d.Construct</title>
		<link>http://nefariousdesigns.co.uk/archive/2006/09/debrief-dconstruct/</link>
		<comments>http://nefariousdesigns.co.uk/archive/2006/09/debrief-dconstruct/#comments</comments>
		<pubDate>Tue, 12 Sep 2006 06:47:00 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Accessibility]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Browsers]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Events]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Thoughts]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Web Standards]]></category>
		<category><![CDATA[XHTML]]></category>

		<guid isPermaLink="false">http://nefariousdesigns.co.uk/archive/2006/09/debrief-dconstruct/</guid>
		<description><![CDATA[Now that I&#8217;m back at work I&#8217;ve probably got just enough time to write up my experiences at d.Construct 2006, so here goes&#8230; Firstly, I&#8217;d like to say a great big nefarious hello to all the developers and designers I met on the day, and a special hello and thanks to Graham Bancroft, Ben Ward, [...]]]></description>
			<content:encoded><![CDATA[<p>Now that I&#8217;m back at work I&#8217;ve probably got just enough time to write up my experiences at <a href="http://2006.dconstruct.org">d.Construct 2006</a>, so here goes&hellip;</p>
<p>Firstly, I&#8217;d like to say a great big nefarious hello to all the developers and designers I met on the day, and a special hello and thanks to Graham Bancroft, <a href="http://ben-ward.co.uk/">Ben Ward</a>, <a href="http://nascentguruism.com/">Steve Marshall</a> and <a href="http://blog.fatbusinessman.com/">Fatty</a> &#8211; it&#8217;s nice to put faces to the names at last guys!</p>
<p>I enjoyed most of the presentations although some more than others. I&#8217;m not going to review them in depth here &#8211; I&#8217;ll just outline my thoughts instead. You should definitely listen to the <a href="http://2006.dconstruct.org/podcast/">d.Construct 2006 podcasts</a> (although the presentations themselves don&#8217;t appear to be live yet) and formulate your own opinions.</p>
<p><span id="more-131"></span></p>
<p>The most pleasant surprise, for me, was <a href="http://www.syndic8.com/weblog/">Jeff Barr</a>&#8216;s talk about Amazon&#8217;s APIs &#8211; I went in expecting nothing but an hour long advert and, although the theme was entirely Amazon based, the content of the talk was pretty educational.</p>
<p><a href="http://boxofchocolates.ca/">Derek Featherstone</a>&#8216;s talk on accessibility was probably of most use since my boss (who also attended) picked up on the potential accessibility nightmares that are JavaScript enhanced interfaces. Nice one Derek; you managed to communicate successfully in one hour what I&#8217;ve been failing to outline to him for years! I shall be taking notes on your technique.</p>
<p><a href="http://www.adactio.com">Jeremy Keith</a> managed to fire up my desire to muck about with API&#8217;s and Microformats over the course of both his talk and the <a href="http://microformats.org">Microformats</a> picnic he hosted in the <a href="http://www.royalpavilion.org.uk/">Brighton Pavilion</a> gardens. Expect to see all kinds of madness incorporated into this site over the coming months (whenever I have time to play). I&#8217;m really looking forward to the <a href="http://microformats.org">Microformats</a> themed <acronym title="Web Standards Group">WSG</acronym> meetup that <a href="http://muffinresearch.co.uk">Stuart</a>&#8216;s planning in the next month or so.</p>
<p>Finally, as expected, <a href="http://www.veen.com/jeff/">Jeff Veen</a>&#8216;s talk on designing the complete user experience was, undoubtedly, the best of the presentations on the day. This probably isn&#8217;t much of a surprise though, as it&#8217;s well known in the industry that Jeff could sell Microsoft products to Mac users (ok, that might be a <em>slight</em> exaggeration but still&hellip;).</p>
<p>Once the event had finished we all wandered down to the seafront to attend the excellent after-party at <a href="http://www.the-terraces.co.uk/">The Terraces</a> on Madeira Drive. It was here that I met up with Graham and gradually got incredibly drunk; which I hadn&#8217;t really noticed until buying the train ticket home became a monumental task of applied concentration. Thanks for that Graham &#8211; it was a top evening!</p>
<p>So, in summary, the event was excellent; the company outstanding; the knowledge obtained exemplary; the after-party awesome; and the hangover unpleasant. Looking forward to next year!</p>
]]></content:encoded>
			<wfw:commentRss>http://nefariousdesigns.co.uk/archive/2006/09/debrief-dconstruct/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Safari for Windows</title>
		<link>http://nefariousdesigns.co.uk/archive/2006/08/safari-for-windows/</link>
		<comments>http://nefariousdesigns.co.uk/archive/2006/08/safari-for-windows/#comments</comments>
		<pubDate>Tue, 08 Aug 2006 12:37:21 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Accessibility]]></category>
		<category><![CDATA[Browsers]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Web Standards]]></category>

		<guid isPermaLink="false">http://nefariousdesigns.co.uk/archive/2006/08/safari-for-windows/</guid>
		<description><![CDATA[Swift is the first WebKit based browser for Windows &#8211; WebKit is the rendering engine behind the popular Mac browsers Safari and Shiira. As any Windows web developer knows, cross-browser compatibility can be a real nightmare to test without a Mac handy. Hopefully the release of Swift will make things a little easier. You can [...]]]></description>
			<content:encoded><![CDATA[<p><img src="/blog/images/swift-1.jpg" alt="The toolbars of Swift, the first WebKit-based browser for Windows" class="framed" /></p>
<p><a href="http://www.getwebkit.org/">Swift</a> is the first WebKit based browser for Windows &#8211; WebKit is the rendering engine behind the popular Mac browsers <a href="http://www.apple.com/macosx/features/safari/">Safari</a> and <a href="http://hmdt-web.net/shiira/en">Shiira</a>.</p>
<p>As any Windows web developer knows, cross-browser compatibility can be a real nightmare to test without a Mac handy. Hopefully the release of Swift will make things a little easier.</p>
<p><span id="more-120"></span></p>
<p>You can download the current alpha release from the website; although the last time I checked, the download seemed to be unavailable. This is probably due to bandwidth limits being exceeded &#8211; I notice <a href="http://annevankesteren.nl/2006/08/swift">Ann van Kesteren has just linked to the site</a> and <a href="http://www.thinkvitamin.com/">Vitamin</a> linked there earlier (which is how I discovered it myself).</p>
<p>Here&#8217;s a nice screeny of it running on my Windows 2000 Pro machine at work:</p>
<p><img src="/blog/images/swift-2.jpg" alt="An image of Swift, the first WebKit-based browser for Windows, running on Windows 2000 Pro" class="framed" /></p>
]]></content:encoded>
			<wfw:commentRss>http://nefariousdesigns.co.uk/archive/2006/08/safari-for-windows/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Yahoo UI &#8211; Fonts</title>
		<link>http://nefariousdesigns.co.uk/archive/2006/05/yahoo-ui-fonts/</link>
		<comments>http://nefariousdesigns.co.uk/archive/2006/05/yahoo-ui-fonts/#comments</comments>
		<pubDate>Thu, 11 May 2006 13:00:58 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Accessibility]]></category>
		<category><![CDATA[Browsers]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Typography]]></category>
		<category><![CDATA[Web Standards]]></category>

		<guid isPermaLink="false">http://nefariousdesigns.co.uk/archive/2006/05/yahoo-ui-fonts/</guid>
		<description><![CDATA[This morning I sat down at my computer, started browsing my feeds to see what had appeared over night and discovered CSS Beauty had placed a link to the Yahoo UI&#8217;s Fonts CSS file. Having already downloaded the UI, I decided to have a closer look at this particular aspect since I&#8217;d missed it in [...]]]></description>
			<content:encoded><![CDATA[<p>This morning I sat down at my computer, started browsing my feeds to see what had appeared over night and discovered <a href="http://www.cssbeauty.com/archives/2006/May/foundational_fonts_css_file_according_to_yahoo/">CSS Beauty</a> had placed a link to the <a href="http://developer.yahoo.com/yui/fonts/">Yahoo UI&#8217;s Fonts CSS</a> file. Having already downloaded the UI, I decided to have a closer look at this particular aspect since I&#8217;d missed it in my first pass.</p>
<p>Oh what a shock <em>I</em> got!</p>
<p><span id="more-97"></span></p>
<p>The Fonts CSS file is billed as offering <q>cross-browser typographical normalization and control</q>. A nice ideal but I&#8217;m not sure I agree with the method adopted.</p>
<p>You see, the first rule in the Fonts CSS file is as follows (I&#8217;ve added some carriage returns and indented to make it a little easier to read):</p>
<pre><code>body
{
  font:13px arial,helvetica,clean,sans-serif;
  *font-size:small;
  *font:x-small;
}</code></pre>
<p>This is nasty, in my opinion, for one major reason; it&#8217;s using hacks to get around IE&#8217;s problem with resizing fonts declared using pixels.</p>
<p>I&#8217;m not going to get up on my soap box about this (neither do I wish to pontificate &#8211; you never know when you might be wrong), but I&#8217;m pretty certain most of us are aware that hacks are a bad method to adopt when trying to solve cross-browser issues. If you&#8217;re interested in reading a little more, there&#8217;s some informative posts at <a href="http://www.thinkvitamin.com/features/css/stop-css-hacking">Vitamin</a>, <a href="http://www.digital-web.com/articles/keep_css_simple/">Digital Web</a> and <a href="http://muffinresearch.co.uk/archives/2005/05/10/a-beginners-guide-to-css-hack-avoidance/">Muffin Research</a>.</p>
<p>It&#8217;s a real shame, in this particular instance, because the Yahoo UI is <em>so</em> good for so many other things.</p>
<h2>Another Method</h2>
<p>Unfortunately, I&#8217;m not sure there is one perfect method for solving this particular problem. In most cases, I personally make a major assumption to solve the issue &#8211; that the user has never changed the size of the default fonts in their browser. This is not a <em>great</em> solution but I certainly think it&#8217;s better than using hacks.</p>
<p>If this is the case, most browser defaults (at least that I&#8217;m aware of) are 16px, which means the following rule sets all font sizes to 10px:</p>
<pre><code>body
{
  font: 62.5%/1.0 "Trebuchet MS", tahoma, verdana, sans-serif;
}</code></pre>
<p>This then means that you can size everything else using percentages and still easily understand what their pixel equivalents would be:</p>
<pre>
100% = 10px
140% = 14px
160% = 16px
200% = 20px
</pre>
<p>This allows you to improve your typography easily &#8211; a good example would be <a href="http://www.markboulton.co.uk/new/index.php/journal/comments/five_simple_steps_to_better_typography_part_4/">Mark Boulton&#8217;s excellent tutorial on weight and size</a>.</p>
<p>It&#8217;s also worth resizing fonts for form elements. This is something the Yahoo Fonts CSS does too. To acheive this, you should use something like this:</p>
<pre><code>
select,
input,
textarea
{
  font-size: 99%;
}
</code></pre>
<p>I&#8217;m using 99% in that rule simply because Safari doesn&#8217;t seem to like 100% for some reason.</p>
<h2>So using Yahoo&#8217;s Fonts CSS is bad?</h2>
<p>Not really, it&#8217;s just that <em>I</em> prefer the above method. You should definately make up your own mind about it.</p>
<p>In summary, it&#8217;s just the Fonts CSS part of the Yahoo UI that I disagree with &#8211; the rest of the interface is awesome and I&#8217;m a particular fan of their javascript event handling functions. They&#8217;ve brought all kinds of new features to the table with the newest release and, if you&#8217;re a web developer, you should definately download it and take a look.</p>
<p>However, when it comes to font-size normalisation (English spelling please), don&#8217;t just trust their method because it&#8217;s <strong>not perfect</strong>.</p>
<p>But then, neither is mine&hellip;</p>
]]></content:encoded>
			<wfw:commentRss>http://nefariousdesigns.co.uk/archive/2006/05/yahoo-ui-fonts/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Listen and learn</title>
		<link>http://nefariousdesigns.co.uk/archive/2005/09/listen-and-learn/</link>
		<comments>http://nefariousdesigns.co.uk/archive/2005/09/listen-and-learn/#comments</comments>
		<pubDate>Fri, 30 Sep 2005 11:44:38 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Accessibility]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Browsers]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Web Standards]]></category>
		<category><![CDATA[XHTML]]></category>

		<guid isPermaLink="false">http://www.nefariousdesigns.co.uk/blog.php/?p=25</guid>
		<description><![CDATA[This week, I will be mostly listening to the podcasts from Web Essentials 2005. I can&#8217;t heartily recommend them if, like me, you couldn&#8217;t get to the web development conference &#8220;Web Essentials 2005&#8221; in Sydney.]]></description>
			<content:encoded><![CDATA[<p>This week, I will be mostly listening to <a href="http://we05.com/podcast/">the podcasts from Web Essentials 2005</a>.</p>
<p>I can&#8217;t heartily recommend them if, like me, you couldn&#8217;t get to the web development conference &#8220;<a href="http://we05.com/">Web Essentials 2005</a>&#8221; in Sydney.</p>
]]></content:encoded>
			<wfw:commentRss>http://nefariousdesigns.co.uk/archive/2005/09/listen-and-learn/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IE Developer Toolbar</title>
		<link>http://nefariousdesigns.co.uk/archive/2005/09/ie-developer-toolbar/</link>
		<comments>http://nefariousdesigns.co.uk/archive/2005/09/ie-developer-toolbar/#comments</comments>
		<pubDate>Wed, 21 Sep 2005 09:45:05 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Browsers]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.nefariousdesigns.co.uk/blog.php/?p=20</guid>
		<description><![CDATA[So Microsoft have finally released a developer toolbar for IE and I&#8217;ve just installed it (after a c**king reboot! WTF?). Unfortunately, although it has some nice features (like the Ruler &#8211; love it), it still isn&#8217;t as comprehensive as Web Developer for Firefox. Ah well. Nice start though Microsoft &#8211; I&#8217;m afraid there&#8217;s quite a [...]]]></description>
			<content:encoded><![CDATA[<p>So Microsoft have finally released a <a href="http://www.microsoft.com/downloads/details.aspx?familyid=e59c3964-672d-4511-bb3e-2d5e1db91038&#038;displaylang=en">developer toolbar for IE</a> and I&#8217;ve just installed it (after a c**king reboot! WTF?).</p>
<p>Unfortunately, although it has some nice features (like the Ruler &#8211; love it), it still isn&#8217;t as comprehensive as Web Developer for Firefox.</p>
<p>Ah well.</p>
<p>Nice <em>start</em> though Microsoft &#8211; I&#8217;m afraid there&#8217;s quite a lot more for you to do to get us developers back into using your browsers though.</p>
]]></content:encoded>
			<wfw:commentRss>http://nefariousdesigns.co.uk/archive/2005/09/ie-developer-toolbar/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Night at the Opera</title>
		<link>http://nefariousdesigns.co.uk/archive/2005/09/a-night-at-the-opera/</link>
		<comments>http://nefariousdesigns.co.uk/archive/2005/09/a-night-at-the-opera/#comments</comments>
		<pubDate>Tue, 20 Sep 2005 10:53:21 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Accessibility]]></category>
		<category><![CDATA[Browsers]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.nefariousdesigns.co.uk/blog.php/?p=19</guid>
		<description><![CDATA[The web browser Opera has always been a bit of a niggle with me. It supplies superior options for it&#8217;s users as well as some nice advanced accessibility features. Unfortunately, it also featured a nasty banner advert in the top right hand corner of your screen unless you decided to pay a one-off download fee. [...]]]></description>
			<content:encoded><![CDATA[<p>The web browser Opera has always been a bit of a niggle with me. It supplies superior options for it&#8217;s users as well as some nice advanced accessibility features. Unfortunately, it also featured a nasty banner advert in the top right hand corner of your screen unless you decided to pay a one-off download fee.</p>
<p>However, as of today, that has changed. In a move that will instigate a little competition for the many other free browsers out there (such as Firefox, Safari, Internet Explorer, Netscape etc) Opera has dropped the advert and the download fee.</p>
<p><a href="http://www.opera.com/">Get your free Opera here&hellip;</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nefariousdesigns.co.uk/archive/2005/09/a-night-at-the-opera/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

