<?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>The Bright Lines &#187; CSS</title>
	<atom:link href="http://www.thebrightlines.com/category/css/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.thebrightlines.com</link>
	<description>HTML, CSS, Javascript and more</description>
	<lastBuildDate>Tue, 17 Jan 2012 22:00:35 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Crucial stuff for your company&#8217;s internal projects</title>
		<link>http://www.thebrightlines.com/2012/01/17/1028/</link>
		<comments>http://www.thebrightlines.com/2012/01/17/1028/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 20:49:44 +0000</pubDate>
		<dc:creator>Wouter Bos</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Documentation]]></category>
		<category><![CDATA[Web development in general]]></category>

		<guid isPermaLink="false">http://www.thebrightlines.com/?p=1028</guid>
		<description><![CDATA[I was musing about what is crucial to make an internal project like Bootstrap from Twitter work.]]></description>
			<content:encoded><![CDATA[<p>Reading the <a href="http://www.alistapart.com/articles/building-twitter-bootstrap/">article on Twitter&#8217;s Bootstrap</a> on A List Apart definitely gave me positive vibe. Twitter and above all its team proved that you can create cool and useful tools if you think further ahead than just pondering how you&#8217;re going to write your 20th incarnation of a sitemap link list for some project.</p>
<p>Yes, it takes some time and discussions between the disciplines but you can win so much time in the future if done right. Doing stuff right depends on some crucial things:</p>
<ul>
<li><strong>Work interdisciplinary and as (almost) equals.</strong> It&#8217;s easy to say what you think out the whole plan yourself, but if you do that, others are not inclined to think with you. Each new idea becomes just another bump in the project instead of a good contribution to a discussion to get a better understanding of a problem. By putting your problem on the table and make team members <em>real</em> team members, you get a real discussion. And a better product in the end</li>
<li><strong>Make your work public.</strong> You also get a whole other situation if you know that other people (clients or the community) are keeping an eye on you. In the positive sense of the word, that is. You have to think (just like Twitter) what is really useful outside your little bubble. And you might get good feedback to make your code even better/stable/useful.<br />
By thinking hard how to make stuff usable for the outside world, you&#8217;re instantly making a very usable and learnable tool for anyone who&#8217;s going to work at your firm.<br />
Making open source software could also motivate people. They&#8217;re not just working hard for the company anymore, they&#8217;re also working on something that can also be useful outside of the company and the greater good. That can be the motivation to work a more on it outside work time.</li>
<li><strong>Results before deadlines or budget.</strong> Ok, projects with limitless budgets aren&#8217;t realistic. But making reusable code or applications without keeping an eye on its usability or not even testing isn&#8217;t realistic either. To get quality reusable code you do not only need to write it, you have to think it out, write it <em>and</em> rewrite it <em>and</em> rewrite it. If you&#8217;re not prepared to do that, just save yourself the trouble.</li>
<li><strong>Continuous testing.</strong> Don&#8217;t wait until the very end of the project to measure its quality. You cannot remove the concrete slabs below an ill-constructed house either. Everybody has to at least check the end result of the finished component before moving on to the next target.</li>
<li><strong>Reusability is epic.</strong> Don&#8217;t kid yourself: Most of the stuff you do now has been done in the past as well. Talk with designers, programmers and developers to aim for reusability while preventing that all websites start to look the same. Getting some framework that works for everybody is everybody&#8217;s priority.</li>
<li><strong>Keep it simple.</strong> Some projects need solid plans. Others don&#8217;t. Some stuff does not have to be written out in threefold as long as the basics are known and the outer borders have been drawn. Be wary if the 5th version of the plan is mailed in PDF form to all team members, project time already gets out of hand and no real work is done yet.</li>
</ul>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.thebrightlines.com/2012/01/17/1028/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MSIE filter styles in Less</title>
		<link>http://www.thebrightlines.com/2011/11/25/filter-styles-in-less/</link>
		<comments>http://www.thebrightlines.com/2011/11/25/filter-styles-in-less/#comments</comments>
		<pubDate>Fri, 25 Nov 2011 20:07:01 +0000</pubDate>
		<dc:creator>Wouter Bos</dc:creator>
				<category><![CDATA[Less]]></category>

		<guid isPermaLink="false">http://www.thebrightlines.com/?p=1004</guid>
		<description><![CDATA[A quick tip on how to use MSIE filters in Less without throwing an exception.]]></description>
			<content:encoded><![CDATA[<p>The filter style property is not only MS specific, but also does not validate. That does not only pose problems if you want to create a valid CSS file, but also when writing Less code. That&#8217;s because Less throws an exception every time you write invalid code. Now that&#8217;s what I call an effective validator. <img src='http://www.thebrightlines.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>But since we live in the real world we really need filter styling. At least for now anyway. And yes, Less can handle MSIE filters although you may have to dig a bit deeper. The following <a href="http://lesscss.org/#-mixins">mixin</a> works in <a href="http://www.dotlesscss.org/">.Less</a> (Less for ASP.NET):</p>
<pre name="code" class="css:nogutter">
.gp_opacity(@opacity: 0.5) {
	opacity: @opacity;
	-ms-filter: ~"'progid:DXImageTransform.Microsoft.Alpha(Opacity=" @opacity*100 ~")'";
	filter: ~"alpha(opacity=" @opacity*100 ~")";
}
</pre>
<p>Happy programming!</p>


<p>Related posts:<ol><li><a href='http://www.thebrightlines.com/2009/12/03/using-ies-filter-in-a-cross-browser-way/' rel='bookmark' title='Permanent Link: Cool cross-browser styling with CSS and IE&#8217;s filter'>Cool cross-browser styling with CSS and IE&#8217;s filter</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.thebrightlines.com/2011/11/25/filter-styles-in-less/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tips for using and debugging of Less CSS code</title>
		<link>http://www.thebrightlines.com/2011/11/21/debugging-less-css/</link>
		<comments>http://www.thebrightlines.com/2011/11/21/debugging-less-css/#comments</comments>
		<pubDate>Mon, 21 Nov 2011 11:35:48 +0000</pubDate>
		<dc:creator>Wouter Bos</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Less]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.thebrightlines.com/?p=965</guid>
		<description><![CDATA[Less CSS is cool. No doubt about it. But with all those cool advantages like functions, variables and mixins there <i>must</i> be some disadvantages as well, right? It took me some time to find a major but really obvious drawback: you cannot debug CSS the way you used to.]]></description>
			<content:encoded><![CDATA[<p>Just think of it: normally I find the right line of code from within the browser in an instance by opening Firebug (or something similar) and look up the line number and CSS file that holds the style code that I would like to edit. Another option is to just copy the selector (if your developer tools hasn&#8217;t rewritten that) and search it using Ctrl+F in my editor.</p>
<p>But with <a href="http://lesscss.org/">Less</a> the CSS code gets parsed, combined and most likely minified. <strong>With <a href="http://lesscss.org/">Less</a> or <a href="http://sass-lang.com/">Sass</a> you cannot trace back styling via your developer tools in a simple manner.</strong></p>
<p>At the moment I&#8217;m building a <a href="https://github.com/WouterBos/graphite">HTML/CSS/JavaScript framework based on Less</a> and ASP.NET. Because that framework will get a solid code convention I&#8217;m convinced that I can keep the issue of not being able to find the right CSS code to a minimum. But I&#8217;m pessimistic about the solidness of Less-code that is written uniquely for each website. Such code does not get the same tender love and care as the reusable code of a framework. Furthermore: it is often bound to deadlines and budgets which may lead to sloppy code. </p>
<p>In worst case scenarios the Less code becomes a black box that magically generates styling but cannot be edited because it hides its inner workings. The only way to edit the style is to add an exception at the end of the Less file and maybe adding an <code>!important</code>.</p>
<p>In short: the ability trace back code styling might get close to null.</p>
<h2>My personal guidelines for Less</h2>
<h3>Make your styling findable</h3>
<p>Use a code convention which enables you to trace back the original Less code. As an example: I&#8217;m creating a lot of components for a framework. Each component is a block of code written as a <a href="http://lesscss.org/#-nested-rules">nested rule</a> like this:</p>
<pre name="code" class="css:nogutter">
/**
 * Root styling for menu
 */
.gp_menu {
	ul {
		background: @gp_colorLow;
	}

	> ul > li > a {
		display: inline-block;
	}
}
</pre>
<p>In my personal code convention I committed myself to make only one level in a nested rules block and to use a unique root selector. So if I see in <a href="http://getfirebug.com/">Firebug</a> a selector like <code>.gp_menu > ul > li > a</code>, I can search in my project for <code>.gp_menu {</code> to get to the right nested rules block. Then I can use <code>> ul > li > a</code> to finally get to the right point in the code to edit.</p>
<p>Now the code you see up there is just the base styling. It needs more styling to make it a real menu. In my framework there are many components that share the same basic styling. Let&#8217;s add some code to create a horizontal and a vertical menu:</p>
<pre name="code" class="css:nogutter">
/**
 * Horizontal menu
 */
.gp_menu.gp_menu_typeHorizontal {
	min-height: 0;

	&#038;:after {
		.clear;
	}

	/* ... lots of more styling */
}

/**
 * Verical menu
 */
.gp_menu.gp_menu_typeVertical {
	li.gp_active > ul {
		display: block;
	}

	/* ... lots of more styling */
}
</pre>
<p>Now if I open up my Firebug and find a selector like <code>.gp_menu.gp_menu_typeVertical li li</code>, I know I have to search for <code>.gp_menu.gp_menu_typeVertical {</code>. This way code conventions helps me to find the right Less code.</p>
<h3>Be cautious using Less in quick &#8216;n dirty projects</h3>
<p>Deadline pressure can easily make a person write bad, unstructured code. With Less it gets even worse: bad, unstructured code <i>and</i> really hard to debug. You should think twice about letting that intern build the base styling of a website, but think three times if you let that intern write Less code for a website. You will be the one who has to debug it at the end of the project!</p>
<h3>Better like your Less parser, it might be your only one</h3>
<p>Do you like your Less parser? That&#8217;s good, because your Less code might not get parsed by other Less libraries. I&#8217;ve written my Less code with <a href="http://www.dotlesscss.org/">.less</a> for ASP.NET and tried to parse my code with <a href="http://wearekiss.com/simpless">SimpleLess</a>. It failed to compile the whole bunch without a proper error message.</p>
<p>Part of the problem is that a bug in CSS (or differences in interpretation for that matter) are ignored in browsers, but Less parsers will throw a big fat exception. Exceptions can be a good thing but not if it differs between parsers. Maybe Less has to be adopted as a standard by the W3C?</p>
<p>Having a solid standard would be a good thing since Google just presented their own take on Less CSS with <a href="http://google-opensource.blogspot.com/2011/11/introducing-closure-stylesheets.html">Closure Stylesheets</a>. They already bended the informal <a href="http://code.google.com/p/jsdoc-toolkit/">JSDoc</a> spec towards their own standards with previous Closure releases.</p>
<h2>Update: LessCSS LinkedIn group</h2>
<p>I created a <a href="http://www.linkedin.com/groups/Less-CSS-4189176">LinkedIn group for LessCSS</a>.</p>


<p>Related posts:<ol><li><a href='http://www.thebrightlines.com/2011/09/08/the-last-resort-in-css-debugging/' rel='bookmark' title='Permanent Link: The last resort in CSS debugging'>The last resort in CSS debugging</a></li>
<li><a href='http://www.thebrightlines.com/2009/10/22/css-debugging/' rel='bookmark' title='Permanent Link: CSS debugging'>CSS debugging</a></li>
<li><a href='http://www.thebrightlines.com/2010/02/12/useful-filezilla-tips/' rel='bookmark' title='Permanent Link: Useful FileZilla tips'>Useful FileZilla tips</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.thebrightlines.com/2011/11/21/debugging-less-css/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Redirect to a mobile website</title>
		<link>http://www.thebrightlines.com/2011/09/29/redirect-to-a-mobile-website/</link>
		<comments>http://www.thebrightlines.com/2011/09/29/redirect-to-a-mobile-website/#comments</comments>
		<pubDate>Thu, 29 Sep 2011 21:29:54 +0000</pubDate>
		<dc:creator>Wouter Bos</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[Usability]]></category>
		<category><![CDATA[redirect]]></category>

		<guid isPermaLink="false">http://www.thebrightlines.com/?p=946</guid>
		<description><![CDATA[If you built a mobile website you just automatically redirect mobile visitors on your main website to the mobile version, right?]]></description>
			<content:encoded><![CDATA[<p>Well, not always. I built a few mobile websites that need a more sophisticated redirection. In some cases I&#8217;d argue you might not want to redirect at all.</p>
<div class="wp-caption alignnone" style="width: 450px"><a href="/article-data/images/flowchart-mobile.png"><img title="How to do mobile redirection" src="/article-data/images/flowchart-mobile-thumb.png" alt="How to do mobile redirection" width="440" height="328" /></a><p class="wp-caption-text">How to do mobile redirection</p></div>
<h2>Mobile website != desktop website</h2>
<p>In many cases the mobile website just contains a subset of the content that&#8217;s available on the main website. That&#8217;s because mobile websites are made with the mobile context in mind. This results in very short texts and location based services.</p>
<p>Moreover: there just isn&#8217;t much web traffic from mobile devices if you compare it to the traffic that browsers on traditional computers generate. So many organizations don&#8217;t see the necessity for a mobile website that is as comprehensive as the desktop variant.</p>
<p>This means that if you would land on a some web page, there will most likely be no mobile equivalent of that content. So there&#8217;s no reason to redirect the user. Unless mobile devices are likely to crash.</p>
<h2>Users can redirect themselves</h2>
<p>In the early days the differences in capabilities between handhelds and PC&#8217;s was very large. But now those devices are smartphones and are powerful hardware. Users can now choose between the predictable security of the main websites and the usability of mobile websites. It&#8217;s, bar some exceptions, a matter of preference now, not a necessity.</p>
<p>You can get away with redirecting users to a mobile website once, but don&#8217;t redirect them all the time. A user that visits the main website with a smartphone most likely just prefers the main website, so don&#8217;t keep him away from the content you want to disclose on the web.</p>
<p>Even better than redirecting: just add a link to your main page to your mobile website and vice versa. That&#8217;s a strategy that works as long both websites can be viewed on a smartphone.</p>


<p>Related posts:<ol><li><a href='http://www.thebrightlines.com/2010/09/11/helping-browsers-with-media-queries/' rel='bookmark' title='Permanent Link: Extending media queries with JavaScript'>Extending media queries with JavaScript</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.thebrightlines.com/2011/09/29/redirect-to-a-mobile-website/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Considerations on building a frontend codebase</title>
		<link>http://www.thebrightlines.com/2011/09/22/considerations-on-building-a-frontend-template-in-html-css-and-javascript/</link>
		<comments>http://www.thebrightlines.com/2011/09/22/considerations-on-building-a-frontend-template-in-html-css-and-javascript/#comments</comments>
		<pubDate>Thu, 22 Sep 2011 20:46:34 +0000</pubDate>
		<dc:creator>Wouter Bos</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Documentation]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Optimization]]></category>
		<category><![CDATA[Web development in general]]></category>

		<guid isPermaLink="false">http://www.thebrightlines.com/?p=933</guid>
		<description><![CDATA[This article is about my thoughts on how to build a solid codebase for your (frontend) web development.]]></description>
			<content:encoded><![CDATA[<p>Every developer at one time stops looking for code from previous built websites and starts building his own standardized code to cut down on production time and repetative work. Call it a boiler plate, codebase, template, scaffolding, framework or whatever. The bottom line is that every developer needs one.</p>
<h2>Problems with my current codebase</h2>
<p>Well, I already have a codebase, but it has some problems. The important one is that it only covers the very basics. That&#8217;s because designs can be very diverse and as a developer I want to stay true to the design. So it&#8217;s hard to build a codebase with grids and blocks if all design differ from eachother.</p>
<p>Another problem major issue is something I have more control over: the codebase and the documentation is a bit scattered. The last problem I have is that I have no demo page of my standard CSS code, so there&#8217;s no easy way to check the template on browser compatibilities.</p>
<p>Now my <a href="/onopager/website/">jQuery plugin project</a> has reached version 1.1, I had the time to do some thinking about a new codebase that would be solid, extendable, easy to deploy and would replace all other codebases and documentation.</p>
<p>Let me make it clear: this article is about my considerations about building a solid framework for myself. It may not apply to you and my ideas not unique either. It still may be helpful for you to get an idea of what sort of codebase you need.</p>
<h2>Existing examples</h2>
<p>The most important thing about a codebase is to decide how to set it up and how to store it. I like the way open source grids like <a href="http://960.gs/">Grid960</a> and <a  href="http://developer.yahoo.com/yui/grids/">YUI</a> have organized their code into little reusable bits and have created a demo and test page for each and every component.</p>
<p>I must admit: I hardly ever used these grids. Most of those grids talk the language of the web developer, not of the designer. And the designers I know don&#8217;t have to limit themselves to a 24-column grid system. Not to mention the designers that are totally ignorant of such a system and whose task is to design a website and mail the Photoshop file to some other company that has to build it. Although I have my reservations towards grids, I like the way these codebases are organized. It can serve as a good <a href="http://www.blueprintcss.org/">Blueprint</a> for my own codebase.</p>
<p>I also get my inspiration from Nicole Sullivan&#8217;s talk on Object Oriented CSS (OOCSS). OOCSS basically means that you build your components in such a way that they become extendable objects. Just like in real object oriented programming. Just have a look at <a href="http://www.stubbornella.org/content/2009/03/23/object-oriented-css-video-on-ydn/">her talk about OOCSS on Yahoo! Developer Network</a>.</p>
<h2>Prefix classes</h2>
<p>By adding a (relatively) unique string before the name of the class you have created your own CSS namespace. It will minimize any interference of other CSS styling that is not part of your own code. Some real life examples can be found in the code that is generated by the CMS systems I have experience with: <a href="http://www.sitefinity.com">Sitefinity</a> and <a href="http://www.sitecore.com">Sitecore</a>. The CMS Sitefinity for example prefixes all CSS classes with &#8220;sf_&#8221;.</p>
<h2>Grids, blocks and text</h2>
<p>All CSS code will be split into different categories that work relatively independently of each other. Until now I can come up with 3 of them.</p>
<h3>Grids</h3>
<p>Grids are the frameworks of placeholders in which we put our content. You know: header, visual, column1, column2, column3 and footer. There are lots of grid templates around like <a href="http://960.gs/">Grid960</a> and <a href="http://www.blueprintcss.org/">Blueprint</a>. My view is that those templates only work if the designer agrees to work within the limits of that framework. My ambition is to write a framework that makes my work easier while still being flexible enough to keep the designers happy.</p>
<h3>Blocks</h3>
<p>There are as many block as the designer can come up with. I think it will be a real time saver to talk with the designer and write down all the types of blocks he thinks he&#8217;ll like to use often. Or even better: just open the last 20 or so web designs he/she made and destil the common blocks and its common features. like menus, news article lists, homepage spotlights, etc. Finally you create basic blocks of it in your template system.</p>
<p>Standarization is not always popular with designers but if it means that projects can be created cheaper there may eventually be budget left to build cool stuff. At least, I hope&#8230;</p>
<h3>Text</h3>
<p>Basic text styling is also a relatively independent component in CSS code. You always define a basic font color, family, size and line height that serves as a base styling for the whole websites. More specific text styling in blocks should be kept to a minimum and preferably relatively to the base text style. So if you have a base style of <code>font: 1em/1.5em normal Arial, sans-serif</code>, you ideally should style a header in a block like this: <code>font-size: 1.5em; line-height: 1.2em;</code>.</p>
<p>Although <code>font-weight</code> is not something you can set relative to a base style, it&#8217;s not likely that it will look ugly in combination with some design if you add <code>font-weight</code> styling to a block. Setting the <code>font-family</code> in the styling of blocks on the other hand will most likely interfere with design, since designs tend to depend heavily on a particular font.</p>
<h2>Create base templates and extend themes</h2>
<p>The code for each grid system and each block will be stored in a seperate base CSS file. Each grid or block can be extended with extra themes or styles. Each style extension will have its own CSS file and presumes that the base file is already loaded.</p>
<h2>Optimizing CSS</h2>
<p>Having all code seperated in small snippets is great for maintaining an overview. As long as you can see what a CSS file does by looking at its filename, its will be easy to add and extend styling to a website.</p>
<p>The template code is not optimized for speed, though. If we don&#8217;t do anything about the fragmentation, the server will have to load a bunch of little CSS files. It&#8217;s important to stress this: It&#8217;s not just the total filesize that matters, each http request costs time. Check out <a href="http://developer.yahoo.com/yslow/">YSlow</a> if you want to know more about this and if it affects your site.</p>
<h3>YUI</h3>
<p>That&#8217;s why all CSS in the website has to be exported, merged and its code minified to one single CSS file. Normally I use <a href="http://developer.yahoo.com/yui/compressor/">YUI compressor</a> for it.</p>
<h3>Less</h3>
<p>But you can do more than just minification. <a href="http://lesscss.org/">Less</a> is a system that extends the CSS syntax with stuff like variables, nested rules and mixins. Less was originally built in Ruby, but there&#8217;s also an <a href="http://www.dotlesscss.org/">ASP.NET port</a>. I hope it will help me create very flexible grids.</p>
<p>By exporting CSS into optimized code, you can focus on making the most readable CSS source file because all comments and spaces in the code will be removed in the end. This is also what I do with JavaScript code and certainly will continue to do.</p>


<p>Related posts:<ol><li><a href='http://www.thebrightlines.com/2009/12/24/too-advanced-css-selectors/' rel='bookmark' title='Permanent Link: Too advanced CSS selectors'>Too advanced CSS selectors</a></li>
<li><a href='http://www.thebrightlines.com/2011/09/08/the-last-resort-in-css-debugging/' rel='bookmark' title='Permanent Link: The last resort in CSS debugging'>The last resort in CSS debugging</a></li>
<li><a href='http://www.thebrightlines.com/2011/11/21/debugging-less-css/' rel='bookmark' title='Permanent Link: Tips for using and debugging of Less CSS code'>Tips for using and debugging of Less CSS code</a></li>
<li><a href='http://www.thebrightlines.com/2012/01/17/1028/' rel='bookmark' title='Permanent Link: Crucial stuff for your company&#8217;s internal projects'>Crucial stuff for your company&#8217;s internal projects</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.thebrightlines.com/2011/09/22/considerations-on-building-a-frontend-template-in-html-css-and-javascript/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>The last resort in CSS debugging</title>
		<link>http://www.thebrightlines.com/2011/09/08/the-last-resort-in-css-debugging/</link>
		<comments>http://www.thebrightlines.com/2011/09/08/the-last-resort-in-css-debugging/#comments</comments>
		<pubDate>Thu, 08 Sep 2011 10:32:52 +0000</pubDate>
		<dc:creator>Wouter Bos</dc:creator>
				<category><![CDATA[Browsers]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Web development in general]]></category>

		<guid isPermaLink="false">http://www.thebrightlines.com/?p=910</guid>
		<description><![CDATA[CSS is in essence relatively simple: you point to one or more nodes in the DOM with a rule and apply some styles to it. That is the theory. In practice debugging CSS can be hard sometimes. Most of the time it's because either the code lacks the neccesary structure or you don't have arcane knowledge of browser bugs.]]></description>
			<content:encoded><![CDATA[<p>Even when you&#8217;re a structured CSS coder and know all the browser glitches (or <em>think</em> you do), it can happen you find yourself between a rock and a hard place. You know, when you stare at the screen, glancing over all the style properties in Firebug and still don&#8217;t have a clue about what&#8217;s going on.</p>
<h2>DEL is your friend</h2>
<p>Those cases happen rarely but when they do, I always resort to a tested and tried technique: isolate the problem by removing or commenting all unneeded markup. Isolating the problem may take some time but when you have a web page with a minimum of HTML while keeping the styling bug intact, you get in most cases the bug fixed in no time.</p>
<p>Why does isolating code work so well? Well, most of the time you can find styling bugs by experience, but when you&#8217;re stuck, every bit of styling on a tag becomes suspicious and that&#8217;s just too much to test. The bug becomes a needle in a hay stack.</p>
<h2>Removing the easy way</h2>
<p>The best way to remove blocks in a page is by just adding a <code>display: none</code> to its styling via a developer tool like Firefox&#8217;s Firebug, Opera&#8217;s Dragonfly, Webkits developer tools or IE&#8217;s Web Developer Toolbar. Just cut away big blocks and each time you remove something, you test if the bug still persists. You continue until you find the block that is triggering the bug. Most of the time you&#8217;ll have to continue the same technique of removing bits of code <em>within</em> that block until you can isolate the problem.</p>
<div class="wp-caption alignnone" style="width: 450px"><img title="Hiding block by adding a display: none" src="http://www.thebrightlines.com/article-data/images/debug1.png" alt="Hiding block by adding a display: none" width="440" height="221" /><p class="wp-caption-text">Hiding a block by adding a &#39;display: none&#39;</p></div>
<div class="wp-caption alignnone" style="width: 450px"><img title="Removing a block of HTML completely" src="http://www.thebrightlines.com/article-data/images/debug2.png" alt="Removing a block of HTML completely" width="440" height="221" /><p class="wp-caption-text">Removing a block of HTML completely</p></div>
<h2>Removing the source code</h2>
<p>Sometimes it&#8217;s better to have direct access to the source HTML than doing temporary changes in the developer tool. But if the HTML is (partly) created server side it&#8217;s hard to easily remove stuff. In those cases when I&#8217;m <em>really</em> desperate, I request the HTML source from the browser and save it in the directory the original web page resides. Then I can make dramatic changes to the code and test in multiple browsers without affecting the site itself.</p>
<p>Is this an efficient way of debugging? Definitely not, but sometimes you just need to do it. It happens to me once or twice a year or so and by debugging that way I always managed to find the root of the problem.</p>


<p>Related posts:<ol><li><a href='http://www.thebrightlines.com/2009/10/22/css-debugging/' rel='bookmark' title='Permanent Link: CSS debugging'>CSS debugging</a></li>
<li><a href='http://www.thebrightlines.com/2011/11/21/debugging-less-css/' rel='bookmark' title='Permanent Link: Tips for using and debugging of Less CSS code'>Tips for using and debugging of Less CSS code</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.thebrightlines.com/2011/09/08/the-last-resort-in-css-debugging/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The grey areas of progressive enhancement</title>
		<link>http://www.thebrightlines.com/2011/09/03/the-grey-areas-of-progressive-enhancement/</link>
		<comments>http://www.thebrightlines.com/2011/09/03/the-grey-areas-of-progressive-enhancement/#comments</comments>
		<pubDate>Sat, 03 Sep 2011 05:42:12 +0000</pubDate>
		<dc:creator>Wouter Bos</dc:creator>
				<category><![CDATA[Browsers]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Web development in general]]></category>
		<category><![CDATA[Adaptive]]></category>
		<category><![CDATA[corporate identity]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[Progressive enhancement]]></category>

		<guid isPermaLink="false">http://www.thebrightlines.com/?p=889</guid>
		<description><![CDATA[Stepping up for the designers here: progressive enhancement is not always in the best interest of your client.]]></description>
			<content:encoded><![CDATA[<p>Yesterday I found the <a href="http://boagworld.com/design/where-are-my-rounded-corners/">PDF of Paul Boag on why progressive enhancement is better</a> than making sure that a website looks the same in all browsers, even older browsers like IE7. It&#8217;s just a 5-minute read and it&#8217;s a good stuff. But I can&#8217;t help feeling that the document presents a bit too black and and white picture. And it&#8217;s a picture in favor of frontend web developers.</p>
<p>For example: progressive enhancement in practice means that if you want to implement rounded corners, you&#8217;d use the <code>border-radius</code> style instead of a stack of images of rounded corners. But what if rounded corners are one of the corner stones of the corporate design of the client? Loads of users on IE7 and IE8 would miss that recognizable feature of that corporate design.</p>
<p>The design choice of rounded corners are sometimes a matter of taste, but most clients care for their corporate identity. So if you are ready to slaughter someones design in IE7/IE8 with progressive enhancement as your alibi, make sure that the features that will be missed in those browsers are not an important part of their corporate identity.</p>


<p>Related posts:<ol><li><a href='http://www.thebrightlines.com/2010/01/07/do-you-create-your-design-in-photoshop-or-notepad/' rel='bookmark' title='Permanent Link: Do you create your design in Photoshop or Notepad?'>Do you create your design in Photoshop or Notepad?</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.thebrightlines.com/2011/09/03/the-grey-areas-of-progressive-enhancement/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Estate Developer Tools</title>
		<link>http://www.thebrightlines.com/2010/12/16/estate-developer-tools/</link>
		<comments>http://www.thebrightlines.com/2010/12/16/estate-developer-tools/#comments</comments>
		<pubDate>Thu, 16 Dec 2010 18:18:15 +0000</pubDate>
		<dc:creator>Wouter Bos</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Web development in general]]></category>
		<category><![CDATA[Estate]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.thebrightlines.com/?p=745</guid>
		<description><![CDATA[The Estate Developer Tool is a JavaScript library that helps front-end developers building websites. I wrote these tools in order to use them at Estate Internet and are now published as open source under the FreeBSD license.]]></description>
			<content:encoded><![CDATA[<p><a target="_blank" href="/article-data/demo/estate-developer-tools/example/index.html" class="button demo"><span> </span>View demo</a></p>
<div class='clear'></div>
<p><a class="button download" href="/article-data/downloads/EstateDeveloperTools.zip"><span> </span>Download Estate Developer Tools</a></p>
<div class='clear'></div>
<h2>Features</h2>
<ul>
<li><strong>Compare page with original design fast:</strong> You can compare the current page with an image of the original design within the browser.</li>
<li><strong>CSS reload:</strong> Reload the stylesheets without reloading the page. Extremely useful when designing websites with many Ajax calls.</li>
<li><strong>Console.log fallback:</strong> If you use <code>clog()</code>, debug messages will be routed to <code>console.log()</code> if available. If not (eg. you&#8217;re developing in IE), the message will be printed in a log box in the web page itself.</li>
<li><strong>Autofill and test forms:</strong> Auto fill forms with text that might cause errors like non-western characters, malformed HTML, JS injection and SQL injection. Autofill also works with the new HTML5 form fields.</li>
<li><strong>Timer:</strong> Do performance test by checking how long some operation takes.</li>
<li><strong>Works in:</strong> IE6+ and all recent versions of Firefox, Chrome, Safari and Opera. I did not check all possible browser versions, but it should work. let me know if you have problems with older browsers. The developer tools do <em>not</em> work in IE&#8217;s <a href="http://en.wikipedia.org/wiki/Quirks_mode">Quirks mode</a>, but that&#8217;s something you should avoid anyway.</li>
</ul>
<h2>Quick overview</h2>
<p>Sorry for the bad sound quality.<br />
<object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/PnuFfs0zOgk?fs=1&amp;hl=nl_NL"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/PnuFfs0zOgk?fs=1&amp;hl=nl_NL" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object></p>
<h2>Installation</h2>
<p>Step one is to <a href="#TODO">download</a> the tool. If you unpack the zip, you&#8217;ll find example page in the (what else) &#8220;example&#8221; directory.</p>
<p>Open the file called &#8220;index.html&#8221;. The developer tools are loaded just before the closing body tag: <code>&lt;script type="text/javascript" src="devtools/javascript/estate-devtools.min.js">&lt;/script></code>.</p>
<p>If you want to change the library to your own needs, you can load the source code instead. It&#8217;s in 4 seperate files that are in the same directory: <code>Estate.js</code>, <code>Estate.Develop.js</code>, <code>Estate.Develop.FormTester.js</code> and <code>Estate.Develop.DesignTester.js</code>.</p>
<p>After the library has been loaded, you can add items to the top right menu like this:</p>
<pre name="code" class="js:nogutter">
	Estate.Events.AddEvent(window, Estate.Develop.ToggleVisibility.Init, "onload")
	Estate.Events.AddEvent(window, Estate.Develop.ReloadCSS.Init, "onload")
	Estate.Events.AddEvent(window, Estate.Develop.FormTester.Init, "onload")
	Estate.Events.AddEvent(
		window,
		function() {
			Estate.Develop.DesignTester.Init({
				designAnchor: document.getElementById('DesignTester'),
				xOffset: 10,
				yOffset: 5
			})
		},
		"onload"
	)
</pre>
<p>The example above will most likely be enough in most cases. The only thing you might have to configure is the Design Tester. That&#8217;s because the design image needs to be positioned relative to the main body of the page. Therefore you need to define an anchor by supplying a reference to an HTML element and define the optional offset.</p>
<p>You can also use jQuery to supply an HTML element like this: <code>designAnchor: jQuery('#DesignTester')[0]</code>. The Form Tester is also configurable. Please refer to the <a href="/article-data/demo/estate-developer-tools/documentation/index.html">object reference</a> for more information.</p>
<p>To install the Estate Developer Tools into your own website, you&#8217;ll have to copy the JavaScript code at the bottom of the page to your own and copy the <code>devtools</code> folder to the root of your own website.</p>
<p>After that you only need to create PNG files of the original design and save them in the folder<code>/devtools/design-images/</code>. If a page is loaded, the Design Tester looks for a PNG file which file name resembles the URL of the page. If that image cannot be found, the Design Tester will asks for that file either by printing a message in the console log or in its own fallback log box in the page. You just have to look up the right file and rename so that the Design Tester can pick it up.</p>
<h2>Helper functions</h2>
<p>Some functionality is not included in the menu</p>
<h3>console.log fallback</h3>
<p>After the library has been loaded, two global functions are available: <code>clog()</code> and <code>dlog()</code>. You use <code>clog()</code> to send a string to <code>console.log()</code> if available. If console.log is not available, the debug message will be printed in the log box in the website. If you can also choose to always use the log box of the Estate Developer Tools by calling <code>dlog()</code>.</p>
<h3>Timer</h3>
<p>If you you want to optimize, you can use the timer to see how much time JavaScript needs to complete an operation. You just create a new instance of the timer object, set an ID so you can distinguish multiple alert from an another, start the timer, run some function or lines of code and the stop the timer. By stopping the timer, you&#8217;ll get a message how much milliseconds the operation costs. Here below is an example:</p>
<pre name="code" class="js:nogutter">
var oTimer = new Estate.Develop.Timer()
oTimer.SetID('Your time to response')
oTimer.Start()
alert('Press "ok" to see how much time it took to respond')
oTimer.End()
</pre>
<h2>Reference</h2>
<p>All public objects and methods have been documented with JsDoc Toolkit. Read the <a href="http://www.thebrightlines.com/article-data/demo/estate-developer-tools/documentation/index.html">documentation</a>.</p>
<h2>Adding more tools</h2>
<p>It&#8217;s possible to integrate your own developer tools in the menu of the Estate Developer Tool. This code will create an extra menu item and runs some code when a user clicks on it:</p>
<pre name="code" class="js:nogutter">
/**
 * @namespace Creates extra menu
 */
Estate.Develop.ExtraMenuItem = ( function() {
	var menuButton

	function doSomething() {
		dlog('Menu item pressed')
	}

	/* START PUBLIC */
	return {
		/**
		 * Initializes extra menu button
		 *
		 * @example
		 * Estate.Develop.ExtraMenuItem.Init()
		 */
		Init: function() {
			menuButton = Estate.Develop.Menu.AddMenuItem('Extra item')

			menuButton.onclick = function() {
				doSomething()
			}
		}
	}
	/* END PUBLIC */
})();
</pre>
<p>It&#8217;s also possible to attach a keypress event to it</p>
<pre name="code" class="js:nogutter">
/**
 * @namespace Creates extra menu
 */
Estate.Develop.ExtraMenuItem = ( function() {
	var menuButton

	function doSomething() {
		dlog('Menu item pressed')
	}

	function pageKeyPress(KeyID){
		dlog('KeyID: '+ KeyID)
	}

	/* START PUBLIC */
	return {
		/**
		 * Initializes extra menu button
		 *
		 * @example
		 * Estate.Develop.ExtraMenuItem.Init()
		 */
		Init: function() {
			menuButton = Estate.Develop.Menu.AddMenuItem('Extra item', 'Press any key')

			menuButton.onclick = function() {
				doSomething()
			}

			// Handle global key events
			Estate.Events.AddEvent (
				document,
				function(e) {
					var KeyID = (window.event) ? event.keyCode : e.which;
					pageKeyPress(KeyID)
				},
				"onkeypress"
			)
		}
	}
	/* END PUBLIC */
})();
</pre>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.thebrightlines.com/2010/12/16/estate-developer-tools/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extending media queries with JavaScript</title>
		<link>http://www.thebrightlines.com/2010/09/11/helping-browsers-with-media-queries/</link>
		<comments>http://www.thebrightlines.com/2010/09/11/helping-browsers-with-media-queries/#comments</comments>
		<pubDate>Fri, 10 Sep 2010 22:21:25 +0000</pubDate>
		<dc:creator>Wouter Bos</dc:creator>
				<category><![CDATA[Browsers]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Mobile]]></category>

		<guid isPermaLink="false">http://www.thebrightlines.com/?p=677</guid>
		<description><![CDATA[Media queries are cool: you can decide what CSS file to serve to a browser based its width. But although it works perfect in many modern browsers, there are always some browsers or some versions of it lagging. Let's give them a hand.]]></description>
			<content:encoded><![CDATA[<div>
<a target="_blank" href="/article-data/demo/mqFallback" class="button demo"><span> </span>View demo</a><br />
<a style="clear: both" class="button download" href="/article-data/downloads/mqFallback.zip"><span></span>Download demo</a>
</div>
<div style="clear: both;"></div>
<h2>What are media queries</h2>
<p>To explain what media queries are, it&#8217;s best to start with the standard media types. Media types were introduced as part of the CSS2 specification way back in 1998 and is supported by all major browsers. The most common are &#8220;screen&#8221; (desktop PC&#8217;s), &#8220;handheld&#8221; (mobile devices), and &#8220;print&#8221;. Here&#8217;s an example of how to link a CSS file to a media type:</p>
<pre name="code" class="xhtml:nogutter">
<link rel="stylesheet" type="text/css" href="/screen.css" media="screen" />
<link rel="stylesheet" type="text/css" href="/handheld.css" media="handheld" />
<link rel="stylesheet" type="text/css" href="/print.css" media="print" />
</pre>
<p>This looks pretty straightforward and it is. But most mobile browsers don&#8217;t consider themselves &#8220;handheld&#8221; when choosing a CSS file. Devices like iPhone, Android and Nokia behave like a desktop computer and select the CSS that&#8217;s reserved for the &#8220;screen&#8221;-devices.</p>
<p>This was in some way a logical step, since most websites don&#8217;t have a CSS file for handheld devices. The drawback is also very clear: You cannot cram a web page optimized for desktop monitors in a 2&#8242; handheld monitor without paying a price. Usability suffers. Users are given crutches like the ability to zoom in to a specific part of the page, but that&#8217;s like watching TV through a keyhole.</p>
<p>To address this problem the W3C came with media queries. Now you can check properties like screen size and resolution. So now you get something like this:</p>
<pre name="code" class="xhtml:nogutter">
<link rel="stylesheet" type="text/css" href="/screen.css" media="only screen and (min-width: 481px)" />
<link rel="stylesheet" type="text/css" href="/handheld.css" media="only screen and (max-width: 480px)" />
<link rel="stylesheet" type="text/css" href="/handheld.css" media="handheld" />
<link rel="stylesheet" type="text/css" href="/print.css" media="print" />
</pre>
<p>Now we have all our ducks back in a row. If the browser width is larger than 480 pixels, it will select &#8220;screen.css&#8221;. If the width is smaller or equal to 480 pixels, it will go for &#8220;handheld.css&#8221;. We keep our CSS link with <code>media="handheld"</code> as a fallback for handheld devices that don&#8217;t do media queries, most notably IE Mobile and Blackberry&#8217;s browser. Checkout <a href="http://www.quirksmode.org/m/css.html#t021">PPK&#8217;s compatibility table</a> to see which browser does not support Media Queries yet.</p>
<h2>Filling the gaps</h2>
<p>But this still is not enough to have your site render well in all browsers. IE and many older browsers do not handle the new media queries.</p>
<p><a href="http://www.alistapart.com/articles/return-of-the-mobile-stylesheet" target="_blank">Some sort of solution was proposed on ALA</a>, but that technique requires an extra CSS file called <code>antiscreen.css</code> that cancels some of all styles that were created in the <code>screen.css</code>. Most of the websites I make just have too much CSS styling to make that technique usable.</p>
<p>JavaScript can also detect the screen width, so I decided to use it to help browsers in choosing the right CSS. The script I created also checks the screen width after a window resize, just like Media Queries. Just open the demo and you will see that the page will switch to the mobile stylesheet if the window gets too narrow. Even in browsers that don&#8217;t support Media Queries (yes, I&#8217;m looking at you, IE!).</p>
<h2>How it works</h2>
<p>In the demo the script expects that <em>if</em> Media Queries are supported by the browser, a div with the class <code>cssLoadCheck</code> should be 100 pixels in width. To check that it this is true it will insert a div with that class into the DOM, check its width and then removes it from the DOM again. If the width of that test div isn&#8217;t 100 pixels we know that Media Queries are not supported and that JavaScript has to supply a CSS file depending on its width.</p>
<p>Each time the pages refreshes it removes the dynamically added link-tags in the head and adds new ones.</p>
<h2>Possible improvements</h2>
<p>This is just a simple script and there is lots of room for improvement. I could also built a script that figures out itself what CSS to load by looking at the media query statements in the markup. The current state of the script is good enough for my needs, so I&#8217;ll keep it like this for now.</p>


<p>Related posts:<ol><li><a href='http://www.thebrightlines.com/2010/09/27/codeview-update/' rel='bookmark' title='Permanent Link: Codeview update'>Codeview update</a></li>
<li><a href='http://www.thebrightlines.com/2011/09/29/redirect-to-a-mobile-website/' rel='bookmark' title='Permanent Link: Redirect to a mobile website'>Redirect to a mobile website</a></li>
<li><a href='http://www.thebrightlines.com/2010/05/06/new-template-for-jsdoctoolkit-codeview/' rel='bookmark' title='Permanent Link: Codeview, a new template for JSDoc Toolkit'>Codeview, a new template for JSDoc Toolkit</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.thebrightlines.com/2010/09/11/helping-browsers-with-media-queries/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>CSS performance, who cares?</title>
		<link>http://www.thebrightlines.com/2010/07/28/css-performance-who-cares/</link>
		<comments>http://www.thebrightlines.com/2010/07/28/css-performance-who-cares/#comments</comments>
		<pubDate>Wed, 28 Jul 2010 05:11:40 +0000</pubDate>
		<dc:creator>Wouter Bos</dc:creator>
				<category><![CDATA[Browsers]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Optimization]]></category>
		<category><![CDATA[efficiency]]></category>
		<category><![CDATA[rendering]]></category>
		<category><![CDATA[selector]]></category>

		<guid isPermaLink="false">http://www.thebrightlines.com/?p=648</guid>
		<description><![CDATA[You probably didn't notice it, but the way you write CSS affects the rendering speed of the browser. Should you care about that? Most likely not, but it is possible to freeze your web page with inefficient selectors.]]></description>
			<content:encoded><![CDATA[<p>Lately I read the following text in <em>Building iPhone Apps with HTML, CSS, and JavaScript</em> (O&#8217;Reilly) on using ID&#8217;s in CSS:</p>
<blockquote cite="http://oreilly.com/catalog/9780596805784?cmp=il-orm-ofps-iphoneapps"><p>&#8220;There are differences between class and id. Class attributes should be used when you have more than one item on the page with the same class value. Conversely, id values have to be unique to a page.</p>
<p>When I first learned this, I figured I’d just always use class attributes so I wouldn’t have to worry about whether I was duping an id value. However, selecting elements by id is much faster than selecting them by class, so you can hurt your performance by overusing class selectors.&#8221;</p></blockquote>
<p>Huh? I never use ID&#8217;s in CSS selectors, but I never experienced slow rendering either. I wanted to test if it&#8217;s stupid not to use ID&#8217;s.</p>
<p>First I wanted to see if it was even able to create a CSS that was hard to parse. Google has a nice article about <a href="http://code.google.com/speed/page-speed/docs/rendering.html#UseEfficientCSSSelectors">writing efficient CSS selectors</a>, so that seemed like a good start before setting up a test. In short there are 2 things that make a fast CSS selector:</p>
<ul>
<li><strong>Make rules as specific as possible</strong><br />
This means that <code>div.content</code> is faster than <code>*</code>.<br />
You have to be especially specific with the rightmost selector, since the browser reads CSS selector from right to left.</li>
<li><strong>Avoid (large) descendant rules</strong><br />
An example of a descendant rule is <code>div.content div.column1 div.columnHeader h2</code>. Descendant rules are less efficient than rules with a single selector, like <code>h2</code>.</li>
</ul>
<h2>Test 1: setting up extremely inefficient CSS</h2>
<p>The most inefficient selector by far is <code>*</code>. Combined with large descendant rules you get extremely inefficient selectors:</p>
<pre name="code" class="css:nogutter">
* * * * * * * * * {
	background: #ff1;
}
* * * * {
	background: #ff2;
}
* * * * * * * {
	background: #ff3;
}
</pre>
<p>I created a CSS file of about 20KB in size with 3600 asterisks characters (*). I combined it with a very large HTML file (1MB) with 9000 opening HTML brackets (<). Because I only wanted to test the CSS rendering, I added the following JavaScript to be able to load the CSS file on my local computer <em>after</em> the page was loaded.</p>
<pre name="code" class="javascript:nogutter">
	<a href="javascript:loadCSS('default.css')">Load CSS</a>
	<script type="text/javascript">
		function loadCSS(url) {
			var fileref=document.createElement("link");
			fileref.setAttribute("rel", "stylesheet");
			fileref.setAttribute("type", "text/css");
			fileref.setAttribute("href", url);
			document.getElementsByTagName("head")[0].appendChild(fileref);
		}
	</script>
</pre>
<h3>Results Test 1</h3>
<table>
<thead>
<tr>
<th>Browser</th>
<th>Render time (sec)</th>
</tr>
</thead>
<tbody>
<tr>
<td>Firefox 3.6</td>
<td>2</td>
</tr>
<tr>
<td>IE 8</td>
<td>4</td>
</tr>
<tr>
<td>IE 7</td>
<td>6</td>
</tr>
<tr>
<td>IE 6</td>
<td>11</td>
</tr>
<tr>
<td>Chrome 6</td>
<td>4</td>
</tr>
</tbody>
</table>
<p><em>All tests were done on my computer (Vista with Intel Duo Core @ 2.4GHz) except for IE7 and IE6. IE7 was tested on a Vista machine with Intel Core Duo SPU @ 2.67Ghz. IE6 was tested on my machine with Virtual PC and on a PC with Windows XP SP3 and a Pentium 3 CPU 3GHz.</em></p>
<p>The results show that browsers freeze for at least 2 seconds in order to render the CSS. So it <em>is</em> possible to screw up your rendering, but you really have to make an effort for it with large HTML files and unrealistic CSS selectors.</p>
<h2>Test 2: setting up a more realistic scenario</h2>
<p>In this test I created a more realistic scenario. I took an existing CSS file and altered it until it was 113KB in size and contained about 1050 selectors. I changed the CSS rules until the bulk of the code looked like this:</p>
<pre name="code" class="css:nogutter">
.Homepage .containerText {
	position: relative;
	margin: 15px auto 0px auto;
	width: 960px;
	background:#ffffff;
}
.Homepage .containerText .containerLeft {
	float:left;
	width:450px;
	padding:10px 20px 45px 10px;
}
.Homepage .containerText .containerLeft p {
	margin:0px 0px 5px 0px;
	color:#414a49;
	line-height:1.286em;
}
</pre>
<p>So most of the code in the CSS file consisted of descendant selectors with classes and hardly any tag names. The corresponding HTML page was also created from existing code and copy-pasted until the file was 107KB in size with almost 600 opening HTML brackets (<). Now we have a relatively large HTML and CSS, but not unrealistic. Once again I tested it in different browsers:</p>
<h3>Results Test 2</h3>
<table>
<thead>
<tr>
<th>Browser</th>
<th>Render time (sec)</th>
</tr>
</thead>
<tbody>
<tr>
<td>Firefox 3.6</td>
<td>0</td>
</tr>
<tr>
<td>IE 8</td>
<td>0</td>
</tr>
<tr>
<td>IE 7</td>
<td>0.5</td>
</tr>
<tr>
<td>IE 6</td>
<td>1.5</td>
</tr>
<tr>
<td>Chrome 6</td>
<td>0</td>
</tr>
</tbody>
</table>
<p>All modern browsers responded so fast that I couldn&#8217;t really notice it needed rendering time. This means that the CSS file does not need any optimization by utilizing ID&#8217;s. The only browser that could profit from more efficient CSS selectors is IE 6. But since I don&#8217;t have to support IE 6 anymore, it&#8217;s not worth my time.</p>
<h2>Conclusion</h2>
<p>Writing fast CSS certainly will help some browsers on slow PC&#8217;s. But that is a minority of the users. So unless you have special requirements for your website, you&#8217;ll be better off focusing on writing logical, maintainable code than trying to get the browser to render a few milliseconds faster. There are some considerations though:</p>
<h3>Being more specific</h3>
<p>A few years ago I switched from writing <code>.foo</code> to writing <code>a.foo</code>. Adding the tag name in the selector gives me a better idea <em>what</em> I&#8217;m styling. Now I know that this coding style is also faster in rendering.</p>
<h3>Descendant selectors</h3>
<p>Descendent selectors (using more than one element in a CSS rule) are inefficient in rendering, but I won&#8217;t give that up. I like to be specific about what element I want to select in CSS. I rather write <code>div.column1 div.article span.date</code> than <code>span.date</code>. The latter is more efficient, but that only works with very small websites because only then you&#8217;d still have an overview of the all classes that are in the HTML code.</p>
<p>When I write JavaScript code I try not to &#8216;pollute&#8217; the global namespace. I try to do the same with CSS by using descendent selectors.</p>
<p>If you need faster rendering, you could alter descendant selectors by making one class that incorporates the whole path. So you&#8217;ll get <code>span.column1_article_date</code> instead of <code>div.column1 div.article span.date</code>. Although it would render faster, it also has some drawbacks. Renaming a class afterwards is tedious work, the class names can become very long and the classes can be used <em>outside</em> it&#8217;s intended containers, so a class called <code>div.column1_article_date</code> could be used anywhere in the DOM and not just inside div with the class <code>column1</code>.</p>
<h2>ID&#8217;s and JavaScript</h2>
<p>I do use ID&#8217;s by the way, Not in CSS though, but for JavaScript for these reasons:</p>
<ul>
<li>Specific elements can be easily accessed in plain JavaScript with <code>getElementById</code>.</li>
<li>If an element has an ID, I can be pretty surre that there is a bit of JavaScript attached to it.</li>
<li>Using ID&#8217;s in your jQuery selectors makes the selectors less dependent on the current HTML structure. It&#8217;s easy to break existing jQuery selectors by removing a class in the DOM.</li>
</ul>


<p>Related posts:<ol><li><a href='http://www.thebrightlines.com/2009/12/24/too-advanced-css-selectors/' rel='bookmark' title='Permanent Link: Too advanced CSS selectors'>Too advanced CSS selectors</a></li>
<li><a href='http://www.thebrightlines.com/2010/01/31/hack-how-to-enable-first-child-in-ie6/' rel='bookmark' title='Permanent Link: Hack: how to enable :first-child in IE6'>Hack: how to enable :first-child in IE6</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.thebrightlines.com/2010/07/28/css-performance-who-cares/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

