<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <link href="https://friendlybit.com/feed/" rel="self" type="application/atom+xml" />
    <link href="https://friendlybit.com/" rel="alternate" type="text/html" />
    <updated>2012-01-08T15:28:49+01:00</updated>
    <id>https://friendlybit.com</id>
    <title type="html">Friendly Bit - Web development blog</title>
    <subtitle>Friendly Bit is a blog by Emil Stenström, a Swedish web developer that occasionally gets ideas of how to improve the internet.</subtitle>
    
        <entry>
            <title type="html">Partial XMLHttpRequest responses?</title>
            <link href="http://friendlybit.com/js/partial-xmlhttprequest-responses/" rel="alternate" type="text/html" title="Partial XMLHttpRequest responses?" />
            <published>2012-01-08T15:28:49+01:00</published>
            <updated>2012-01-08T15:28:49+01:00</updated>
            <id>http://friendlybit.com/js/partial-xmlhttprequest-responses/</id>
            <author>
                <name>Emil Stenström</name>
            </author>
            <summary type="text">We all know how to make an AJAX request, and fetch some data. But as soon as you need to fetch data incrementally, have the server push data to you, you...</summary>
            <content type="html" xml:base="http://friendlybit.com/js/partial-xmlhttprequest-responses/">
                &lt;p&gt;We all know how to make an AJAX request, and fetch some data. But as soon as you need to fetch data incrementally, have the server push data to you, you have to resort to all sorts of complicated stuff. Websockets; with all their different versions and shady support, different kinds of polling, hidden iframes, ActiveX for IE?&lt;/p&gt;
&lt;p&gt;The simplest way, that almost workds is partial XMLHttpRequest responses. I first read about them as &lt;a href=&#34;http://www.kylescholz.com/blog/2010/01/progressive_xmlhttprequest_1.html&#34;&gt;progressive xmlhttprequests on Kyle Schulz blog&lt;/a&gt;, but really think that method should get more recognition.&lt;/p&gt;
&lt;p&gt;Note: I&#39;ve only tested this with Webkit, against Twitter&#39;s Streaming API, with a XMLHttpRequest that allows cross-domain requests. I think it works with Firefox too, but it will definitely not work in IE. Sorry.&lt;/p&gt;
&lt;div class=&#34;highlight&#34; data-language=&#34;JS&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;xhr&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;ow&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;XMLHttpRequest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;&amp;lt;streaming-url-on-you-own-domain-or-CORS&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;nx&#34;&gt;xhr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;GET&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;nx&#34;&gt;xhr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;send&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;// Define a method to parse the partial response chunk by chunk&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;last_index&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;parse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;curr_index&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;xhr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;responseText&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;length&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;last_index&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;curr_index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// No new data&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;xhr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;responseText&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;substring&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;last_index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;curr_index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;last_index&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;curr_index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;// Check for new content every 5 seconds&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;setInterval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;parse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;5000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;// Abort after 25 seconds&lt;/span&gt;
&lt;span class=&#34;nx&#34;&gt;setTimeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;clearInterval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;parse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;xhr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;abort&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;25000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The biggest problem with this method is that the responseText property keeps filling up with data. The longer you receive data, the bigger the data in memory will be. The only way I can see this fixed (today) is to simply kill the connection after a certain amount of data has been received, and open it up again.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I would love to see a better way to do this&lt;/strong&gt;, from native javascript, without all the numerous hacks that are out there. If you know of a way that fills these requirements, please let me know:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Easy to implement on the &lt;strong&gt;client side&lt;/strong&gt;. Ideally I would like to use XMLHttpRequest, and just get a callback each time the client sends data, with the NEW data specified as a callback parameter.&lt;/li&gt;
&lt;li&gt;Easy to implement on the &lt;strong&gt;server-side&lt;/strong&gt;. I can set some headers if you make me, but ideally I would like to use this against existing Streaming APIs (like Twitter&#39;s), without adding custom stuff.&lt;/li&gt;
&lt;li&gt;As cross-browser, cross-platform as possible.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Is there a way to get this working? It&#39;s so annoying to see something that&#39;s a curl one-liner, be 100s of lines of code with web technologies…&lt;/p&gt;
&lt;div class=&#34;highlight&#34; data-language=&#34;BASH&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://stream.twitter.com/1/statuses/filter.json?track&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&amp;lt;your-keyword&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-u&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;your-twitter-nick&amp;gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Is the web really that far behind?&lt;/strong&gt;&lt;/p&gt;

            </content>
        </entry>
    
        <entry>
            <title type="html">Geolocation and Google maps</title>
            <link href="http://friendlybit.com/js/geolocation-and-google-maps/" rel="alternate" type="text/html" title="Geolocation and Google maps" />
            <published>2011-06-18T14:11:11+02:00</published>
            <updated>2011-06-18T14:11:11+02:00</updated>
            <id>http://friendlybit.com/js/geolocation-and-google-maps/</id>
            <author>
                <name>Emil Stenström</name>
            </author>
            <summary type="text">Image by heiwa4126 via Flickr Google Maps has has geolocation support for a long time, but I still find people surprised of how it all works. So here&#39;s a...</summary>
            <content type="html" xml:base="http://friendlybit.com/js/geolocation-and-google-maps/">
                &lt;div class=&#34;zemanta-img&#34;&gt;
  &lt;figure style=&#34;width: 240px&#34; class=&#34;wp-caption alignright&#34;&gt;&lt;a href=&#34;http://www.flickr.com/photos/57552634@N00/3791431635&#34;&gt;&lt;img title=&#34;Google Maps Marker in Tokyo&#34; src=&#34;/files/post-media/3791431635_c722c1d51a_m.jpg&#34; alt=&#34;Google Maps Marker in Tokyo&#34; width=&#34;240&#34; height=&#34;120&#34; /&gt;&lt;/a&gt;&lt;figcaption class=&#34;wp-caption-text&#34;&gt;Image by heiwa4126 via Flickr&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;Google Maps has has geolocation support for a long time, but I still find people surprised of how it all works. So here&#39;s a short writeup, skip it if you already know all about geolocation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lets start&lt;/strong&gt; at the &lt;a title=&#34;Google Maps&#34; rel=&#34;homepage&#34; href=&#34;http://maps.google.com/&#34;&gt;Google Maps&lt;/a&gt; frontpage. Among the zoom controls, above the little old man, there&#39;s a button in the form of a small circle. It does not look like much, but what it&#39;s doing is incredibly cool. Click it and the map moves to where you are, with an accuracy of ~20 meters. Sci-fi crazy!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How does it work?&lt;/strong&gt; In the newer browsers (all but IE6, IE7, or IE8) may ask you for your positioning information from the browser. It usually shows up as a bar at the top of the browser. The browser then gathers two specific forms of positioning information from your computer: your &lt;strong&gt;IP address&lt;/strong&gt; and the &lt;strong&gt;signal strength of any wireless network&lt;/strong&gt; near you. That information is then sent, if you approve it, to Google, which returns the coordinates you are at the moment.&lt;/p&gt;
&lt;p&gt;Google can do this because they&#39;ve been driving around with their street view cars all over the world, and measured signal strength of WiFi networks (public and private) at each specific location. Now they can use that information, combined with your local signal strength conditions, to triangulate their way to where you are. And it&#39;s both accurate and fast.&lt;/p&gt;
&lt;p&gt;If your wireless reciever is turned off, or you&#39;re at a stationary computer, all calculations are based on the IP number. These kind of lookups are quite arbitrary and inaccurate, I just get to the nearest big city when trying to use it over a non-wireless line. But mobile connections are slowly taking over landlines, so I guess this problem will solve itself automatically.&lt;/p&gt;
&lt;p&gt;The best kind of technology throws you forward in time, and make your realize that we&#39;re actually making progress. Geolocation has feel to it.&lt;/p&gt;
&lt;p&gt;Looking for the techy explaination of geolocation? Have a look at &lt;a href=&#34;http://robertnyman.com/2010/03/15/geolocation-in-web-browsers-to-find-location-google-maps-examples/&#34;&gt;Robert Nyman&#39;s writeup&lt;/a&gt;.&lt;/p&gt;

            </content>
        </entry>
    
        <entry>
            <title type="html">Animate from one element to another (jQuery plugin)</title>
            <link href="http://friendlybit.com/js/animate-from-one-element-to-another-jquery-plugin/" rel="alternate" type="text/html" title="Animate from one element to another (jQuery plugin)" />
            <published>2011-05-05T22:52:14+02:00</published>
            <updated>2011-05-05T22:52:14+02:00</updated>
            <id>http://friendlybit.com/js/animate-from-one-element-to-another-jquery-plugin/</id>
            <author>
                <name>Emil Stenström</name>
            </author>
            <summary type="text">Image via Wikipedia Have you even tried clicking an &#34;Add to cart&#34;-button and not understood what happened? I have. An although I understand the idea of...</summary>
            <content type="html" xml:base="http://friendlybit.com/js/animate-from-one-element-to-another-jquery-plugin/">
                &lt;div class=&#34;zemanta-img&#34;&gt;
  &lt;figure style=&#34;width: 215px&#34; class=&#34;wp-caption alignright&#34;&gt;&lt;a href=&#34;http://commons.wikipedia.org/wiki/File:Stencil_shopping_cart.jpg&#34;&gt;&lt;img title=&#34;Stencil of a shopping cart with the head of th...&#34; src=&#34;/files/post-media/300px-Stencil_shopping_cart31.jpg&#34; alt=&#34;Stencil of a shopping cart with the head of th...&#34; width=&#34;215&#34; height=&#34;162&#34; /&gt;&lt;/a&gt;&lt;figcaption class=&#34;wp-caption-text&#34;&gt;Image via Wikipedia&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;Have you even tried clicking an &amp;quot;Add to cart&amp;quot;-button and not understood what happened? I have. An although I understand the idea of adding a product to the cart, and then letting the user continue browsing from where he is, I still get stumped when &amp;quot;nothing happens&amp;quot; when I click the button. So what to do?&lt;/p&gt;
&lt;p&gt;Simple: Add a &lt;strong&gt;animation from the add button to the cart&lt;/strong&gt;. That way you communicate what just happened. &amp;quot;The product moved in there, and by clicking the cart you&#39;ll find it again. Now continue buying stuff!&amp;quot;.&lt;/p&gt;
&lt;p&gt;Somebody must have done this before, so I started looking for a &lt;a class=&#34;zem_slink&#34; title=&#34;JQuery&#34; rel=&#34;homepage&#34; href=&#34;http://jquery.com/&#34;&gt;jQuery&lt;/a&gt; plugin to do this (jQuery was already on the page, so why not?). I found add2cart - A plugin that looks good, but that misses a few features I wanted:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;animation duration&lt;/strong&gt; is set in seconds, meaning products further down the page will move faster than those further up. I wanted constant speed.&lt;/li&gt;
&lt;li&gt;It didn&#39;t allow me to &lt;strong&gt;customize the look&lt;/strong&gt; of the animated element.&lt;/li&gt;
&lt;li&gt;The code rely on concatenating strings of CSS and generally could use &lt;strong&gt;lots of improvement&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So I did what anyone would do: rewrote the code from scratch, and posted it on GitHub.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Get the code: &lt;a href=&#34;https://github.com/EmilStenstrom/jQuery-animate_from_to&#34;&gt;Animate From To 1.0&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It&#39;s my first jQuery plugin ever, and my first public GitHub project, so let me know if I&#39;ve done something wrong. Is this something that could be useful in one of your projects?&lt;/p&gt;

            </content>
        </entry>
    
        <entry>
            <title type="html">Lazy Loading Asyncronous Javascript</title>
            <link href="http://friendlybit.com/js/lazy-loading-asyncronous-javascript/" rel="alternate" type="text/html" title="Lazy Loading Asyncronous Javascript" />
            <published>2010-05-08T00:15:06+02:00</published>
            <updated>2010-05-08T00:15:06+02:00</updated>
            <id>http://friendlybit.com/js/lazy-loading-asyncronous-javascript/</id>
            <author>
                <name>Emil Stenström</name>
            </author>
            <summary type="text">Update: This is no longer the best way to load scripts. Use a script tag with async and defer set instead. Like many of you might know, I&#39;m working on a...</summary>
            <content type="html" xml:base="http://friendlybit.com/js/lazy-loading-asyncronous-javascript/">
                &lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; This is no longer the best way to load scripts. Use a &lt;a href=&#34;https://www.igvita.com/2014/05/20/script-injected-async-scripts-considered-harmful/&#34;&gt;script tag with async and defer set&lt;/a&gt; instead.&lt;/p&gt;
&lt;p&gt;Like many of you might know, I&#39;m working on a site called &lt;a href=&#34;http://kundo.se&#34;&gt;Kundo&lt;/a&gt; with a couple of friends. It&#39;s kinda like a Swedish version of &lt;a href=&#34;http://getsatisfaction.com/&#34;&gt;Getsatisfaction&lt;/a&gt;, which means we have a javascript snippet that people add to their site to get feedback functionality. Cut-and-paste instead of writing the code yourself. Simple.&lt;/p&gt;
&lt;p&gt;The problem is, how do you load an external javascript with minimal impact on your customer&#39;s sites? Here are my requirements:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Small&lt;/strong&gt;. I don&#39;t want a big mess for them to include on their sites. 10-15 lines, tops.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stand-alone&lt;/strong&gt;. The environment is unknown, so we can&#39;t rely on any external dependencies, like javascript libraries.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cross-browser&lt;/strong&gt;. I have no idea what browsers my customer&#39;s customers have, so I can&#39;t do anything modern or fancy that isn&#39;t backwards compatible. I assume at least IE6 and up though.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Asynchronous download&lt;/strong&gt;. The download of my script should not block the download of any script on their sites.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lazy Loading&lt;/strong&gt;. If my site is temporarily slow, I don&#39;t want to block the onload event from triggering until after our site responds.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Preserve events&lt;/strong&gt;. Any events used should not override any events on the customer&#39;s site. Minimal impact, like I said.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don&#39;t pollute namespace&lt;/strong&gt;. Global variables should be avoided, since they could conflict with existing javascript.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Note: I did not make all of this up myself. Lots of people did, I&#39;m just writing it down for you. Thanks: Jonatan, &lt;a href=&#34;http://stevenbenner.com/&#34;&gt;Steven&lt;/a&gt;, &lt;a href=&#34;http://fleecelabs.se/&#34;&gt;Peter&lt;/a&gt;, and &lt;a href=&#34;http://hanssonlarsson.se/&#34;&gt;Linus&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;script-tag&#34;&gt;Script tag&lt;a href=&#34;#script-tag&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&#34;highlight&#34; data-language=&#34;HTML&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;script&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;http://yourdomain.com/script.js&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;script&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;While being the stand-alone, cross-browser, and the shortest piece of code possible; it doesn&#39;t download asynchronously and doesn&#39;t lazy load. &lt;strong&gt;Fail&lt;/strong&gt;.&lt;/p&gt;
&lt;div style=&#34;overflow: auto;&#34;&gt;
  &lt;img class=&#34;alignnone size-full wp-image-619&#34; title=&#34;Firebug screenshoot with script tag&#34; src=&#34;/files/post-media/script11.png&#34; alt=&#34;&#34; width=&#34;725&#34; height=&#34;70&#34; /&gt;
&lt;/div&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Screenshot from Firebug&#39;s net console:&lt;/strong&gt; The script (set to load in 2 seconds) blocks the download of the big image (added after the above script tag, and used throughout this article as a test). Onload event (the red line) triggers after 2.46 seconds.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;async-pattern-a-script-tag-written-with-javascrip&#34;&gt;Async pattern (A script tag written with javascript)&lt;a href=&#34;#async-pattern-a-script-tag-written-with-javascrip&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;http://stevesouders.com&#34;&gt;Steve Souders&lt;/a&gt;, the web performance guru, has compiled a decision tree over &lt;a href=&#34;http://stevesouders.com/efws/images/0405-load-scripts-decision-tree-04.gif&#34;&gt;different ways to achieve non-blocking downloads&lt;/a&gt;. Have a look at that graph.&lt;/p&gt;
&lt;p&gt;Since we&#39;re on a different domain, and only have one script (order doesn&#39;t matter), the solution is given: We should create a script tag with inline javascript, and append it to the document. Voila! Non-blocking download!&lt;/p&gt;
&lt;div class=&#34;highlight&#34; data-language=&#34;JS&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;createElement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;script&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;text/javascript&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;http://yourdomain.com/script.js&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getElementsByTagName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;script&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)[&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;parentNode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;insertBefore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;})();&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: &lt;code&gt;async&lt;/code&gt; is a &lt;a href=&#34;http://www.whatwg.org/specs/web-apps/current-work/#attr-script-async&#34;&gt;HTML5 attribute&lt;/a&gt;, doing exactly what we&#39;re trying to simulate with our hack, so it&#39;s added for good measure. Also, wrapping the code in an anonymous function prevents any variables to leak out to the rest of the document.&lt;/p&gt;
&lt;p&gt;This is a pattern that is getting more and more popular nowadays, especially since &lt;a href=&#34;http://code.google.com/apis/analytics/docs/tracking/asyncTracking.html&#34;&gt;Google Analytics uses it&lt;/a&gt;. But there&#39;s an important distinction here: The above snipped &lt;strong&gt;blocks onload from triggering&lt;/strong&gt; until the referenced script is fully loaded. &lt;strong&gt;Fail&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update 2010-09-01&lt;/strong&gt;: &lt;a href=&#34;#comment-34047&#34;&gt;Steve Souders&lt;/a&gt; adds that the above is only true for Firefox, Chrome, and Safari, but not IE and Opera. So for a IE-only site, this might be the best method.&lt;/p&gt;
&lt;div style=&#34;overflow: auto;&#34;&gt;
  &lt;img class=&#34;alignnone size-full wp-image-617&#34; title=&#34;Firefox screenshoot with the async pattern&#34; src=&#34;/files/post-media/asyncload11.png&#34; alt=&#34;&#34; width=&#34;726&#34; height=&#34;69&#34; /&gt;
&lt;/div&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Screenshot from Firebug&#39;s net console:&lt;/strong&gt; The script (set to load in 2 seconds) downloads in parallell with the big image. Onload event (the red line) triggers after 2.02 seconds.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;lazy-load-pattern-async-pattern-triggered-onload&#34;&gt;Lazy load pattern (Async pattern triggered onload)&lt;a href=&#34;#lazy-load-pattern-async-pattern-triggered-onload&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;So, how to you make sure you don&#39;t block onload? Well, you wrap your code inside a function that&#39;s called on load. When the onload event triggers, you know you haven&#39;t blocked it.&lt;/p&gt;
&lt;div class=&#34;highlight&#34; data-language=&#34;JS&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;window&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;onload&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;createElement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;script&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;text/javascript&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;http://yourdomain.com/script.js&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getElementsByTagName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;script&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)[&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;parentNode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;insertBefore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This works, but it overrides the onload event of the site that uses the script. This could be OK in some cases, where you have control over the site referencing the script, but I need to cater for that. &lt;strong&gt;Fail&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&#34;unobtrusive-lazy-load-pattern&#34;&gt;Unobtrusive lazy load pattern&lt;a href=&#34;#unobtrusive-lazy-load-pattern&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The logical solution to the above problem is to use an incarnation of addEvent. addEvent is simply a common name for an cross browser way to take the current function tied to onload, add it to a queue, add your function to the queue, and tie the queue to the onload event. So which version of addEvent should we use?&lt;/p&gt;
&lt;p&gt;There&#39;s been competitions for writing a &lt;a href=&#34;http://www.quirksmode.org/blog/archives/2005/10/_and_the_winner_1.html&#34;&gt;short and compact version of addEvent&lt;/a&gt;, and the winner of that competition was John Resig, with this little beauty:&lt;/p&gt;
&lt;div class=&#34;highlight&#34; data-language=&#34;JS&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;addEvent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;attachEvent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;e&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(){&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;e&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;](&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;window&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;attachEvent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;on&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;addEventListener&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This is unsafe code, since it relies on serializing a function to a string, something that &lt;a href=&#34;http://my.opera.com/hallvors/blog/2007/03/28/a-problem-with-john-resigs-addevent&#34;&gt;Opera mobile browsers have disabled&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Thing is, we don&#39;t need all that generic event stuff, we&#39;re only dealing with onload here. So if we first replace the type attribute with hardcoded &#39;load&#39;, replace obj with &#39;window&#39;, and remove the fix for making &#39;this&#39; work in IE, we&#39;ve got four lines of code left. Let&#39;s combine this with the above lazy load pattern:&lt;/p&gt;
&lt;div class=&#34;highlight&#34; data-language=&#34;JS&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;async_load&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(){&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;createElement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;script&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;text/javascript&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;http://yourdomain.com/script.js&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getElementsByTagName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;script&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)[&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;parentNode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;insertBefore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;window&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;attachEvent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;window&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;attachEvent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;onload&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;async_load&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;window&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;addEventListener&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;load&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;async_load&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;})();&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is exactly what we&#39;re looking for here. &lt;strong&gt;Finally!&lt;/strong&gt;&lt;/p&gt;
&lt;div style=&#34;overflow: auto;&#34;&gt;
  &lt;img class=&#34;alignnone size-full wp-image-618&#34; title=&#34;Firebug screenshoot with the lazy load pattern&#34; src=&#34;/files/post-media/lazyload11.png&#34; alt=&#34;&#34; width=&#34;726&#34; height=&#34;71&#34; /&gt;
&lt;/div&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Screenshot from Firebug&#39;s net console:&lt;/strong&gt; The script (set to load in 2 seconds) downloads after the onload event has triggered. Onload event (the red line) triggers after 0.41 seconds.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;And that wraps up this article: Different tactics works for different scenarios, and only understanding them all makes you capable of picking the right one for your problem. As always, I&#39;m waiting for your feedback in the comments. Thanks for reading!&lt;/p&gt;

            </content>
        </entry>
    
        <entry>
            <title type="html">Rendering a web page – step by step</title>
            <link href="http://friendlybit.com/css/rendering-a-web-page-step-by-step/" rel="alternate" type="text/html" title="Rendering a web page – step by step" />
            <published>2010-01-11T01:04:33+01:00</published>
            <updated>2010-01-11T01:04:33+01:00</updated>
            <id>http://friendlybit.com/css/rendering-a-web-page-step-by-step/</id>
            <author>
                <name>Emil Stenström</name>
            </author>
            <summary type="text">Have you ever thought about what happens when you surf the web? It&#39;s not as simple as it seems: You type an URL into address bar in your preferred browser....</summary>
            <content type="html" xml:base="http://friendlybit.com/css/rendering-a-web-page-step-by-step/">
                &lt;p&gt;Have you ever thought about what happens when you surf the web? It&#39;s not as simple as it seems:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;You &lt;strong&gt;type an URL&lt;/strong&gt; into address bar in your preferred browser.&lt;/li&gt;
&lt;li&gt;The browser &lt;strong&gt;parses the URL&lt;/strong&gt; to find the protocol, host, port, and path.&lt;/li&gt;
&lt;li&gt;It &lt;strong&gt;forms a HTTP request&lt;/strong&gt; (that was most likely the protocol)&lt;/li&gt;
&lt;li&gt;To reach the host, it first needs to &lt;strong&gt;translate&lt;/strong&gt; the human readable host &lt;strong&gt;into an IP number&lt;/strong&gt;, and it does this by doing a DNS lookup on the host&lt;/li&gt;
&lt;li&gt;Then a &lt;strong&gt;socket needs to be opened&lt;/strong&gt; from the user&#39;s computer to that IP number, on the port specified (most often port 80)&lt;/li&gt;
&lt;li&gt;When a connection is open, the &lt;strong&gt;HTTP request is sent&lt;/strong&gt; to the host&lt;/li&gt;
&lt;li&gt;The host &lt;strong&gt;forwards the request&lt;/strong&gt; to the server software (most often Apache) configured to listen on the specified port&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;server inspects the request&lt;/strong&gt; (most often only the path), and &lt;strong&gt;launches the server plugin needed&lt;/strong&gt; to handle the request (corresponding to the server language you use, PHP, Java, .NET, Python?)&lt;/li&gt;
&lt;li&gt;The plugin gets access to the full request, and starts to prepare a HTTP response.&lt;/li&gt;
&lt;li&gt;To construct the response a &lt;strong&gt;database&lt;/strong&gt; is (most likely) &lt;strong&gt;accessed&lt;/strong&gt;. A database search is made, based on parameters in the path (or data) of the request&lt;/li&gt;
&lt;li&gt;Data from the database, together with other information the plugin decides to add, is &lt;strong&gt;combined into a long string&lt;/strong&gt; of text (probably HTML).&lt;/li&gt;
&lt;li&gt;The plugin &lt;strong&gt;combines&lt;/strong&gt; that data with some meta data (in the form of HTTP headers), and &lt;strong&gt;sends the HTTP response&lt;/strong&gt; back to the browser.&lt;/li&gt;
&lt;li&gt;The browser receives the response, and &lt;strong&gt;parses the HTML&lt;/strong&gt; (which with 95% probability is broken) in the response&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;DOM tree is built&lt;/strong&gt; out of the broken HTML&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;New requests are made&lt;/strong&gt; to the server for each new resource that is found in the HTML source (typically images, style sheets, and JavaScript files). Go back to step 3 and repeat for each resource.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stylesheets are parsed&lt;/strong&gt;, and the rendering information in each gets attached to the matching node in the DOM tree&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Javascript is parsed and executed&lt;/strong&gt;, and DOM nodes are moved and style information is updated accordingly&lt;/li&gt;
&lt;li&gt;The browser &lt;strong&gt;renders the page&lt;/strong&gt; on the screen according to the DOM tree and the style information for each node&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;You&lt;/strong&gt; &lt;strong&gt;see&lt;/strong&gt; the page on the screen&lt;/li&gt;
&lt;li&gt;You get annoyed the whole process was too slow.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I, too, get annoyed when the above steps take longer than one tenth of a second. But now at least I have some documentation to look at, while waiting the remaining fractions of a second before the page renders.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.flickr.com/photos/amboo213/115034446/sizes/s/&#34;&gt;&lt;img class=&#34;alignnone&#34; title=&#34;Spoiled dog - by amboo213 on Flickr&#34; src=&#34;http://farm1.static.flickr.com/45/115034446_8bf43c2273_m.jpg&#34; alt=&#34;Spoiled dog&#34; width=&#34;240&#34; height=&#34;180&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Spoiled we are, all of us.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(Feel free to add more steps, through the comments…)&lt;/em&gt;&lt;/p&gt;

            </content>
        </entry>
    
        <entry>
            <title type="html">Make a div clickable</title>
            <link href="http://friendlybit.com/js/make-a-div-clickable/" rel="alternate" type="text/html" title="Make a div clickable" />
            <published>2009-06-30T22:53:25+02:00</published>
            <updated>2009-06-30T22:53:25+02:00</updated>
            <id>http://friendlybit.com/js/make-a-div-clickable/</id>
            <author>
                <name>Emil Stenström</name>
            </author>
            <summary type="text">We all dislike that links are so small, and hard to click. So of course we want to make the clickable areas bigger. Some would think that doing this with...</summary>
            <content type="html" xml:base="http://friendlybit.com/js/make-a-div-clickable/">
                &lt;p&gt;We all dislike that links are so small, and hard to click. So of course we want to make the clickable areas bigger. Some would think that doing this with some CSS on the a-tag would be a good way, but then you can&#39;t have block level elements inside it (you&#39;ll get a validation error if you try to put headings or paragraph tags inside of links). So what&#39;s a more general solution?&lt;/p&gt;
&lt;p&gt;My take is to use a div instead, and use javascript, of course together with a good fallback. When clicking the div, find the first link inside it, and go to that URL. It&#39;s simple, and with a few additional quirks, it gets really useful.&lt;/p&gt;
&lt;p&gt;Javascript code (requires jQuery):&lt;/p&gt;
&lt;div class=&#34;highlight&#34; data-language=&#34;JS&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ready&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(){&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;block&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;.teaser&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;block&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;click&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(){&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;window&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;location&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;find&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;a:first&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;attr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;href&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;block&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;addClass&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;clickable&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;block&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;hover&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(){&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;window&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;status&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;find&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;a:first&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;attr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;href&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(){&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;window&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;status&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;CSS for showing that the div actually is clickable:&lt;/p&gt;
&lt;div class=&#34;highlight&#34; data-language=&#34;CSS&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;clickable&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;cursor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;pointer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;clickable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;hover&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;background&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mh&#34;&gt;#efefef&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A &lt;a href=&#34;/files/clickable_block/&#34; data-no-instant&gt;clickable div demo&lt;/a&gt; is of course available.&lt;/p&gt;
&lt;h2 id=&#34;how-it-works&#34;&gt;How it works&lt;a href=&#34;#how-it-works&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;When the div (or other tag, you choose) is clicked, find the &lt;strong&gt;first anchor tag&lt;/strong&gt;, get it&#39;s href attribute, and go there. Relying on an actual link means you always have a fallback, so no cheating.&lt;/li&gt;
&lt;li&gt;When &lt;strong&gt;javascript is disabled&lt;/strong&gt;, it just falls back to a regular block, where only the links are clickable.&lt;/li&gt;
&lt;li&gt;A class called &amp;quot;clickable&amp;quot; is set on the block to allow for &lt;strong&gt;javascript-specific styling&lt;/strong&gt;, such as changing the cursor with cursor: pointer, something you don&#39;t want to happen when the block isn&#39;t clickable.&lt;/li&gt;
&lt;li&gt;The changing background color on &lt;strong&gt;hover is done with CSS&lt;/strong&gt;, which I think is fair, considering the small percentage of users using IE6. Changing background color isn&#39;t a must feature.&lt;/li&gt;
&lt;li&gt;Lastly, since we&#39;re simulating a link here, it should show where the link is going. I&#39;ve done this by setting the statusbar to the link location on hover, something that&#39;s useful when it works (users can disable this in some browsers).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Hope that little snippet is useful for someone out there, I think it&#39;s a good example of good use of javascript.&lt;/p&gt;

            </content>
        </entry>
    
        <entry>
            <title type="html">Interface developers and security</title>
            <link href="http://friendlybit.com/css/interface-developers-and-security/" rel="alternate" type="text/html" title="Interface developers and security" />
            <published>2009-01-24T00:30:44+01:00</published>
            <updated>2009-01-24T00:30:44+01:00</updated>
            <id>http://friendlybit.com/css/interface-developers-and-security/</id>
            <author>
                <name>Emil Stenström</name>
            </author>
            <summary type="text">You live in a new era, when demanding that people register on your site is no longer enough. There&#39;s far too many other sites out that that you&#39;re already a...</summary>
            <content type="html" xml:base="http://friendlybit.com/css/interface-developers-and-security/">
                &lt;p&gt;You live in a &lt;strong&gt;new era&lt;/strong&gt;, when demanding that people register on your site is no longer enough. There&#39;s far too many other sites out that that you&#39;re already a member of, you don&#39;t need another one. You need to trust people.&lt;/p&gt;
&lt;p&gt;You also want people to contribute to your sites with content somehow. Text is not enough, you want all kinds of &amp;quot;rich&amp;quot; content, and you want people to be able to place them how they want on your page. I mean, we live in a &lt;strong&gt;new era&lt;/strong&gt; after all.&lt;/p&gt;
&lt;p&gt;Problem is, this &lt;strong&gt;new era thingie talk&lt;/strong&gt; makes people forget the basics. Even though this is the future, and we&#39;re all bored with &amp;quot;just&amp;quot; hypertext, we can&#39;t allow random people to add HTML to our sites. Why? Ask myspace about the &lt;a href=&#34;http://namb.la/popular/tech.html&#34;&gt;Samy worm&lt;/a&gt; from 2005, a little piece of clever front-end code that took their servers flying. What did they do wrong? They tried to let untrusted people embed HTML on their profile pages.&lt;/p&gt;
&lt;p&gt;But they even had this clever filter, which cleaned the code first! Well, long story short, using a div with the style attribute set to a background image that points to a javascript url actually execute the javascript in IE6. Didn&#39;t think of that did you? So what about the fact that both IE6 and IE7 execute vbscripts in urls prefixed with &amp;quot;vbscript:&amp;quot;, just like with javascript. Didn&#39;t know that? Ohhh. Perhaps then you shouldn&#39;t be trying to let unknown people embed HTML on your site?&lt;/p&gt;
&lt;p&gt;Many of these security issues stem from the fact that ordinary well-educated computer scientists &lt;strong&gt;don&#39;t know enough about interface development&lt;/strong&gt;, HTML, CSS and javascript, and discount them as being something that &amp;quot;anyone&amp;quot; could do. &amp;quot;Even my aunt made this puppy site in like 3 days, how hard can it be?!&amp;quot;.&lt;/p&gt;
&lt;p&gt;I&#39;ve always thought that interface development have an undeserved reputation of being easier than &amp;quot;real programming&amp;quot;; something that you can let rookies work with, something that no &amp;quot;real&amp;quot; programmer would ever want. &amp;quot;No, I want to work with hard stuff, not that webby stuff&amp;quot;.&lt;/p&gt;
&lt;p&gt;If you are in a position where people actually think that, perhaps security could be the way to lift interface development to its proper status. So why not read up on &lt;a href=&#34;http://en.wikipedia.org/wiki/Cross-site_scripting&#34;&gt;Cross Site Scripting (XSS)&lt;/a&gt;, look at examples of vulnerabilities, and pick a couple of examples of &lt;a href=&#34;http://www.xssed.com/&#34;&gt;big sites that are vulnerable&lt;/a&gt;. While you&#39;re at it, why not read up on &lt;a href=&#34;http://en.wikipedia.org/wiki/Cross-site_request_forgery&#34;&gt;Cross-site request forgery (CSRF)&lt;/a&gt; too?&lt;/p&gt;
&lt;p&gt;These are real issues that &lt;strong&gt;someone&lt;/strong&gt; needs to take into account when building websites. My guess is that the fancy computer scientists will have a very long way to go before grasping this stuff. &amp;quot;Why does IE6 parse &#39;java   script:&#39; as if there where no space in the middle?&amp;quot;. You know who&#39;s not surprised? Every damn interface developer out there.&lt;/p&gt;
&lt;p&gt;So. Go out there, and teach them silly math people how it&#39;s done, and what your HTML, CSS and javscript-knowledge is worth. Show them that logic isn&#39;t the way we do things around here, that anything can happen when IE6 boots. And… whatever you do… think very hard before letting people embed HTML on your site.&lt;/p&gt;

            </content>
        </entry>
    
        <entry>
            <title type="html">Worth a look: DOMAssistant</title>
            <link href="http://friendlybit.com/js/worth-a-look-domassistant/" rel="alternate" type="text/html" title="Worth a look: DOMAssistant" />
            <published>2008-02-25T21:30:31+01:00</published>
            <updated>2008-02-25T21:30:31+01:00</updated>
            <id>http://friendlybit.com/js/worth-a-look-domassistant/</id>
            <author>
                <name>Emil Stenström</name>
            </author>
            <summary type="text">A couple of months ago Robert Nyman showed me a javascript library he had built, DOMAssistant, and proceeded to use it successfully in one of our projects....</summary>
            <content type="html" xml:base="http://friendlybit.com/js/worth-a-look-domassistant/">
                &lt;p&gt;A couple of months ago &lt;a href=&#34;http://www.robertnyman.com/&#34;&gt;Robert Nyman&lt;/a&gt; showed me a javascript library he had built, &lt;a href=&#34;http://domassistant.com/&#34;&gt;DOMAssistant&lt;/a&gt;, and proceeded to use it successfully in one of our projects. I wasn&#39;t amused. How could a tiny homebuilt little hack compete with my favorite, the almighty jQuery?&lt;/p&gt;
&lt;p&gt;I whined, and said I really liked the CSS-selector syntax that jQuery has. So &lt;a href=&#34;http://www.robertnyman.com/2007/12/17/domassistant-25-released-css-selector-support-new-ajax-methods-and-more-goodies-added/&#34;&gt;he added support for CSS1, CSS2, and CSS3&lt;/a&gt;. The bastard.&lt;/p&gt;
&lt;p&gt;After a while he started getting doubts about if he really could compete with the big names, being supported by lots of people. But instead of giving up he got himself &lt;a href=&#34;http://domassistant.com/about/&#34;&gt;a team of his own&lt;/a&gt;. The famous &lt;a href=&#34;http://www.456bereastreet.com/about/&#34;&gt;Roger Johansson&lt;/a&gt; being one of them. There went that argument, damnit!&lt;/p&gt;
&lt;p&gt;I pointed out the jQuery was very small, only 15 kb! He pointed out that DOMAssistant is half that size, 7 kb. That&#39;s smaller than most images. Aaaargghh!&lt;/p&gt;
&lt;p&gt;I said that jQuery is much faster than anything I&#39;ve seen. He showed me the &lt;a href=&#34;http://www.domassistant.com/slickspeed/&#34;&gt;slickspeed&lt;/a&gt; test, showing that his framework was indeed faster than all the others. How could he do that? Well, he explained, by using the browser optimized XPath and querySelectorAll support in browsers.&lt;/p&gt;
&lt;p&gt;I had one card left to play, a somewhat ugly one. &amp;quot;Animations?&amp;quot; I almost wispered. &amp;quot;No…&amp;quot; came the reply back. But as he saw me straighten my back, getting ready to proclaim victory, he contiuned &amp;quot;… but it&#39;s being worked on, and coming in the next release&amp;quot;. Damn you Robert, it seems I just have to give it a try…&lt;/p&gt;

            </content>
        </entry>
    
        <entry>
            <title type="html">Sharepoint 2007 from an interface developer’s view</title>
            <link href="http://friendlybit.com/css/sharepoint-2007-from-an-interface-developers-view/" rel="alternate" type="text/html" title="Sharepoint 2007 from an interface developer’s view" />
            <published>2008-01-20T12:10:42+01:00</published>
            <updated>2008-01-20T12:10:42+01:00</updated>
            <id>http://friendlybit.com/css/sharepoint-2007-from-an-interface-developers-view/</id>
            <author>
                <name>Emil Stenström</name>
            </author>
            <summary type="text">Like Cameron Moll (Skinning Sharepoint and Pointedly unskinnable), I&#39;ve been working with Sharepoint 2007 (aka MOSS) recently, and I hope you don&#39;t mind me...</summary>
            <content type="html" xml:base="http://friendlybit.com/css/sharepoint-2007-from-an-interface-developers-view/">
                &lt;p&gt;Like Cameron Moll (&lt;a href=&#34;http://cameronmoll.com/archives/2007/05/skinning_ms_sharepoint_with_st/&#34;&gt;Skinning Sharepoint&lt;/a&gt; and &lt;a href=&#34;http://cameronmoll.com/archives/2007/10/sharepoint_2007_pointedly_unskinnable/&#34;&gt;Pointedly unskinnable&lt;/a&gt;), I&#39;ve been working with Sharepoint 2007 (aka MOSS) recently, and I hope you don&#39;t mind me posting a few articles about my work here. I&#39;ve found far too few blog posts that really go to the depth in explaining how things really work. I&#39;ll try to do that here, but I hope you can respect my wish that this does not turn into a helpdesk.&lt;/p&gt;
&lt;h2 id=&#34;quotcustomizationquot&#34;&gt;&amp;quot;Customization&amp;quot;&lt;a href=&#34;#quotcustomizationquot&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let&#39;s start. &lt;strong&gt;Sharepoint 2007 very, very hard to customize&lt;/strong&gt;. If your job is to customize the interface in any major way, you have a lot of work ahead of you. You might think you&#39;re a much better interface developer than me, but you still have a lot of work ahead of you. You need to accept that.&lt;/p&gt;
&lt;p&gt;When you read about Sharepoint 2007 on other sites you will find that people are really ecstatic about it. Just check the comments on how to &lt;a href=&#34;http://planetwilson.blogspot.com/2007/09/sharepoint-2007-colour-color-calendar.html&#34;&gt;customize the calendar&lt;/a&gt;. Reading carefully you will find that he&#39;s comparing it with Sharepoint 2003, not with other products, or even a standard ASP.NET site. That&#39;s a big difference. Sharepoint 2003 was much worse, but that does not mean things are good now. This is a common pattern, people that like Sharepoint compare it to the previous version, not with better ways of doing things.&lt;/p&gt;
&lt;p&gt;As most CMS:es, Sharepoint gets sold to customers that don&#39;t know programming. They see a product that can handle all the features they want: blogs, wikis, forums, calendars, document libraries, workflows, and so on. All features you could ever want is included, from what is called &amp;quot;out of the box&amp;quot;. The problem is that the system is built so that all of those &amp;quot;out of the box&amp;quot; features are hard to customize. Things like changing how the wiki renders, is really hard. Often it&#39;s easier to rebuild that feature from scratch, than customizing what Sharepoint ships.&lt;/p&gt;
&lt;p&gt;This is the main reason, from my point of view, that you should pick another CMS.&lt;/p&gt;
&lt;h2 id=&#34;specifics&#34;&gt;Specifics&lt;a href=&#34;#specifics&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I don&#39;t believe you trust me on my words, so I thought I&#39;d be more specific now, and talk about the issues that make Sharepoint 2007 hard to work with (customize). Let me stress that these are not all the issues, just the major ones that an interface developer has to tackle.&lt;/p&gt;
&lt;h3 id=&#34;development&#34;&gt;Development&lt;a href=&#34;#development&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;From what I&#39;ve read from larger projects, the recommended development environment for a Sharepoint site is a virtual machine. For us, we needed a 36 Gb image, a size that required me to get a new external hard drive, just to store it. Also, running in a virtual machine means that you only can use about half of your RAM, which means everything gets slow. As if that wasn&#39;t enough, a new virtual machine means you have to reinstall all your programs, browsers, plugins again. Web development shouldn&#39;t have to be like that.&lt;/p&gt;
&lt;h3 id=&#34;accessibility&#34;&gt;Accessibility&lt;a href=&#34;#accessibility&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Sharepoint has gotten a lot of bashing for not being accessible, so they&#39;ve added some features to account for that. Some of those are really good individually, but looking at the general mess that is the HTML that Sharepoint spits out, the pretty page above fades in importance. One major problem is that you still need &lt;strong&gt;javascript enabled&lt;/strong&gt; for many of the accessibility features. Enabling &amp;quot;Accessibility mode&amp;quot;, among other things, makes dropdown menus appear as new windows (popups) instead of dynamically writing HTML to the page. And this is after they &amp;quot;fixed&amp;quot; it.&lt;/p&gt;
&lt;h3 id=&#34;page-size&#34;&gt;Page size&lt;a href=&#34;#page-size&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A standard Sharepoint site uses lots of default Javascript and CSS in two files called core.js and core.css. All in all they add up to over 250 kb. Yes, that&#39;s not a misspelling or extra zero, a default page in sharepoint takes at least 250 kb. This is not counting the HTML, a huge, table-ridden, inline-javascripted, mess of things.&lt;/p&gt;
&lt;p&gt;If you go through lots of trouble, you can strip those files out, but that means you can&#39;t use any default components. Since much of Sharepoint depend on those, you don&#39;t really want to go that way. It&#39;s a mess, and Microsoft themselves recommend you try to &lt;a href=&#34;http://msdn2.microsoft.com/en-us/library/bb727371.aspx#MOSS2007OptPerfWCM_PagePayloadSmallisGood&#34;&gt;remove some of it&lt;/a&gt; to boost performance. Preferably by using AJAX to load the js file later. Seriously.&lt;/p&gt;
&lt;h3 id=&#34;javascript-and-browser-dependencies&#34;&gt;Javascript and Browser dependencies&lt;a href=&#34;#javascript-and-browser-dependencies&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Except from core.js, the javascript is spread out all over the place. As usual in many CMS:es, javascript is not treated as a real programming language, so there&#39;s no structuring whatsoever. Sometimes it&#39;s script tags, sometimes inline, sometimes external mini files, and most often automatically generated code. It&#39;s a real mess, and is a big reason for the HTML size being so large. Many of the scripts do not work in browsers other than IE, which means you really need IE to properly use the admin interface.&lt;/p&gt;
&lt;p&gt;From the browser compatability info you can read that there are level 1 and level 2 browsers:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Level 2 web browsers support all of our basic functionality so that users can both read and write in our content sites, perform site administration, etc. Some functionality may not be available, some functionality may be available in a more limited form, and some visual rendering may not be as optimized as our Level 1 browsers. We also will not support Level 2 web browsers on the Central Administration site.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;These are the Level 2 browsers: Firefox, Netscape, Safari. Opera isn&#39;t even in the list. Is this the new, modern way, of handling cross browser compatibility?&lt;/p&gt;
&lt;h3 id=&#34;changing-the-css&#34;&gt;Changing the CSS&lt;a href=&#34;#changing-the-css&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I previously said that most CSS is included in a file called core.css. The file in itself if huge, with thousands of class names, and no structuring whatsoever. Heather Solomon has made an attempt to make things workable by &lt;a href=&#34;http://www.heathersolomon.com/content/sp07cssreference.htm&#34;&gt;making images of what each class specifies&lt;/a&gt;. It&#39;s not even nearly a complete reference, and helps some, but using &lt;a href=&#34;http://getfirebug.com/&#34;&gt;Firebug&lt;/a&gt; is a faster way. Another thing the CSS sheet above does, is show how completely unorganized the CSS is. Have a look at it.&lt;/p&gt;
&lt;p&gt;As with core.js you can&#39;t really remove core.css, since lots of built-in functionality depends on it. So what you need to do is start deciding which of those rules you need to overwrite and which not. Have fun!&lt;/p&gt;
&lt;p&gt;To add to the insult, if you just add your own CSS as an external file and try to link to that on your own pages, core.css is appended as the last stylesheet in the source code. This of course means that all your changes get overwritten, and you need to hack around things by using the &lt;link&gt; tag directly (instead of sharepoint&#39;s own csslink-control), or add your custom files via the admin interface. Since core.css is just a list of simple class names, you can also use &lt;a href=&#34;http://www.htmldog.com/guides/cssadvanced/specificity/&#34;&gt;CSS Specificity&lt;/a&gt; to make your rules count, but that isn&#39;t mentioned in any of the troubleshooting blog posts. None the less, it&#39;s tedious do work around.&lt;/p&gt;
&lt;h3 id=&#34;share-point-and-master-pages&#34;&gt;Share point and Master pages&lt;a href=&#34;#share-point-and-master-pages&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Most of Sharepoint is upgraded to use .NET 2.0, and its concept of Master pages and aspx pages. For those of you that don&#39;t develop in .NET the two can be explained as a templating mechanism, where each Master page has general placeholders where you can insert aspx pages. In each aspx page you specify one master page, and all of the placeholders you want to fill with content. It&#39;s a pretty good system.&lt;/p&gt;
&lt;p&gt;Sharepoint taps into this system by making up two strings &amp;quot;~masterurl/custom.master&amp;quot;, and &amp;quot;~masterurl/default.master&amp;quot;, that you use instead of specifying your own masterpages. Users then specify masterpages in the admin interface, potentially breaking the entire site. Also, Sharepoint assumes there&#39;s just one masterpage per site, so if you thought you could use one masterpage for twocolumn layouts, and another for threecolumn layouts, you&#39;re wrong. The solution here is to break out of the Sharepoint way and hardcode real urls instead of doing things the Sharepoint way.&lt;/p&gt;
&lt;p&gt;There&#39;s also things you can&#39;t change. The admin interface has a masterpage called application.master, which controls pretty much everything that has to do with built-in Sharepoint things. You don&#39;t ever change this file, since it&#39;s quite easy to seriously break things then. The problem is that this file also specify the look and feel of the admin interface, and if you&#39;re building a site where people are expected to add stuff, they will spend time in the admin interface. There isn&#39;t a good way around this, and you probably end up just changing some colors via CSS and let it be.&lt;/p&gt;
&lt;h3 id=&#34;default-net-controls&#34;&gt;Default .NET controls&lt;a href=&#34;#default-net-controls&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The default master pages that ship with Sharepoint is horrendous and I&#39;ll post more details about them in a later post. But even if you roll your own master pages from scratch you still have the standard .NET-problem with controls. Using controls in .NET is a way to package functionality that you can easily add to your pages. A developer just needs to copy a DLL file, and call the control, optionally sending in some parameters. Easy.&lt;/p&gt;
&lt;p&gt;The problem with this approach is that a control consists both of logic and HTML. So if you want some built-in logic that renders, say, the breadcrumb trail, you also get the HTML the author of the control deemed appropriate. In Sharepoint, a breadcrumb trail can be a doubly nested table, with display: none; controls to enable accessibility, and a doubly span nested link. It&#39;s just a terrible mess, but there&#39;s no other way to get to the breadcrumb logic, except from building a new control from scratch. Be prepared to work with terrible HTML.&lt;/p&gt;
&lt;h2 id=&#34;in-summary&#34;&gt;In summary&lt;a href=&#34;#in-summary&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you want to examine the points above by yourself, there&#39;s a MOSS example site up at &lt;a href=&#34;http://www.wssdemo.com/default.aspx&#34;&gt;wssdemo.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This article is a interface developer view at Sharepoint 2007. If you look at the system from other viewpoints, I&#39;m sure there are good things there. That&#39;s not my point. What I&#39;m trying to say is that &lt;strong&gt;Sharepoint 2007, is beyond repair when it comes to interface customization&lt;/strong&gt;, and you should do everything in your power to avoid working with it. If I can give one interface developer the arguments to convince a customer to pick another system, this article was worth it. Thanks for reading.&lt;/p&gt;

            </content>
        </entry>
    
        <entry>
            <title type="html">Manipulating innerHTML removes events</title>
            <link href="http://friendlybit.com/js/manipulating-innerhtml-removes-events/" rel="alternate" type="text/html" title="Manipulating innerHTML removes events" />
            <published>2007-09-26T23:24:04+02:00</published>
            <updated>2007-09-26T23:24:04+02:00</updated>
            <id>http://friendlybit.com/js/manipulating-innerhtml-removes-events/</id>
            <author>
                <name>Emil Stenström</name>
            </author>
            <summary type="text">Others have written about this before, but I thought I&#39;d mention it again, just so you don&#39;t miss it. Aleksandar Vaci? found it while playing with tables...</summary>
            <content type="html" xml:base="http://friendlybit.com/js/manipulating-innerhtml-removes-events/">
                &lt;p&gt;Others have written about this before, but I thought I&#39;d mention it again, just so you don&#39;t miss it. Aleksandar Vaci? found it while playing with tables and their cells. I found it when &lt;a href=&#34;http://www.robertnyman.com/&#34;&gt;Robert&lt;/a&gt; and I played with nested lists. It works the same across browers. Let me show a quick example:&lt;/p&gt;
&lt;p&gt;You have a paragraph tag that contains a span that you want to make clickable.&lt;/p&gt;
&lt;div class=&#34;highlight&#34; data-language=&#34;HTML&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;p&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;para&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
   &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;span&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;clickspan&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;This is clickable.&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;span&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
   But this is not.
&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To make it clickable you don&#39;t do any fancy stuff, you just add it with onclick:&lt;/p&gt;
&lt;div class=&#34;highlight&#34; data-language=&#34;JS&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;span&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getElementsById&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;clickspan&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;nx&#34;&gt;span&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;onclick&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;You clicked the span!&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;All fine. You click the span and it just works. But then you remember something. You want to add some text to the end of the paragraph, and you decide to do this with javascript. You add the following line to the end of the script:&lt;/p&gt;
&lt;div class=&#34;highlight&#34; data-language=&#34;JS&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getElementById&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;para&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;nx&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;innerHTML&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot; Some extra text&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You try clicking the span again, and it doesn work. You scratch your hair, you bite your nails, you scream of desperation and anger. It still doesn&#39;t work. It seems manipulating an element by using innerHTML removes all events from that element, and all children. Here&#39;s a &lt;a href=&#34;/files/innerHTMLevents/&#34; data-no-instant&gt;live example&lt;/a&gt;. I thought you should know.&lt;/p&gt;

            </content>
        </entry>
    
        <entry>
            <title type="html">I’m an interface developer</title>
            <link href="http://friendlybit.com/css/im-an-interface-developer/" rel="alternate" type="text/html" title="I’m an interface developer" />
            <published>2007-08-20T23:17:55+02:00</published>
            <updated>2007-08-20T23:17:55+02:00</updated>
            <id>http://friendlybit.com/css/im-an-interface-developer/</id>
            <author>
                <name>Emil Stenström</name>
            </author>
            <summary type="text">In his latest post Roger Johansson asks the question Are we designers or developers?. I have a simple answer for that. None of them. Let me explain: First...</summary>
            <content type="html" xml:base="http://friendlybit.com/css/im-an-interface-developer/">
                &lt;p&gt;In his latest post Roger Johansson asks the question &lt;a href=&#34;http://www.456bereastreet.com/archive/200708/are_we_designers_or_developers/&#34;&gt;Are we designers or developers?&lt;/a&gt;. I have a simple answer for that. &lt;strong&gt;None of them&lt;/strong&gt;. Let me explain:&lt;/p&gt;
&lt;p&gt;First we have these people calling themselves &lt;strong&gt;developers&lt;/strong&gt;. And boy do they know programming… and math… and… no that&#39;s all. Many have a masters degree in computer science, a degree that pretty much tells you that they once gave five years of their lives to programing, how cool is that!? It&#39;s not unusual to find people that &lt;a href=&#34;http://xkcd.com/55/&#34;&gt;think in those terms&lt;/a&gt; too. You can recognize them by their 10 year old, unmatched, clothes and you&#39;ll rarely talk more than 1 minute with them. Very efficient.&lt;/p&gt;
&lt;p&gt;Then we have the &lt;strong&gt;designers&lt;/strong&gt;. Either real females, or people very close to females, that just can&#39;t stop talking about this abstract thingie-thongie that just like, you know, exploded in a big burst of colors and like… &amp;quot;EHEM! Sorry!&amp;quot;, you hear them say, regaining consciousness and flying back to earth. Their clothes, at least you think they are clothes, often look like they where meant for something else. Perhaps for building steel pumps, or killing animals… or both. Well, at least these clothes are matched… or very purposefully not at all matched (not at aaaall like the developers). You can talk with these people for hours, probably even days, and still only touch upon the delicate topic of &amp;quot;a glass of water&amp;quot;. Oh, and they &amp;quot;create&amp;quot; things too. Very deep.&lt;/p&gt;
&lt;p&gt;So where the heck does the &lt;strong&gt;interface developer&lt;/strong&gt; come into all of this? Well, imagine you have a real project at hand. Real people that need some new website to do their work. Real deadlines, money that switches hands. Smiling business people that promises things and shake hands. Seems like something you know of?&lt;/p&gt;
&lt;p&gt;Now, imagine bringing a developer and a designer together in a room, for like a month, working together with this new website. Concentrate hard and try to see the images before your very eyes. Will they accomplish anything?&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Hell no!&lt;/strong&gt; In 5 minutes they will have started arguing about who should be the first one to open the door, and in what way. One talking about the most efficient way to turn the handle, and the other one defending herself by talking about cosmic beams from Saturn. After the first day the developer will have sore cheeks, after being constantly bitch slapped while hiding under his desk. The third day the designer will sit shaking in a corner after the electric shock induced by the steel helmet the developer built. None of them will survive the fourth day, let alone the project.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Very yes!&lt;/strong&gt; When you meet them after the month has passed you find two harmonic people that smiles to each other and really seem to have connected. They explain to you that the demonstration will be in two parts, first the designer and then the programmer. The designer shows you an app that really touches you, at least you think so, although you not fully understand it. The programmer shows you the other part of the app, one that instantly shows the number 369. They finish the presentation and look at you. You stand up, walk out, lock yourself into a nearby free conference room, and shout with all the power in your lungs: &amp;quot;HOW THE F*#CK AM I GOING TO DO MY TAXES WITH THIS SHIT?!#&amp;quot;. When you come back you find them congratulating each other for making the deadline.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You see? There&#39;s something missing there. Some kind of link between the two. Someone that can walk into a room with two screaming people and calmly say: &amp;quot;Hey, you both kinda run linux (SuSE vs. Mac OS X), and have a &amp;quot;cold&amp;quot; desktop background (default plain blue vs. modern interpretation of &lt;a href=&#34;http://en.wikipedia.org/wiki/Image:Vasnetsov_Snegurochka.jpg&#34;&gt;Vasnetsov Snegurochka&lt;/a&gt;), what a coincidence!?&amp;quot;. There needs to be someone that can walk into the same room the next day and explain that they are talking about two different kinds of &amp;quot;abstract methods&amp;quot;. There needs to be a link.&lt;/p&gt;
&lt;p&gt;But there&#39;s more: An interface developer is silly enough to learn languages that doesn&#39;t even have variables. Even though he know that his code will be sent as uncompressed plaintext and will be rendered by broken excuses for programs, he won&#39;t cry himself to bed every night.&lt;/p&gt;
&lt;p&gt;He will also gladly adapt a design to something it wasn&#39;t really intended for, and he even will make it look somewhat good. He will skip adding those fabulous shadows, to make the deadline on time, and still think of himself a good person.&lt;/p&gt;
&lt;p&gt;You see, even though &amp;quot;interface&amp;quot; reflect the visual graphic things, and &amp;quot;developer&amp;quot; relate to hard logic code, &lt;strong&gt;interface developers&lt;/strong&gt; are real people, not a combination of two halves. I am one.&lt;/p&gt;

            </content>
        </entry>
    
        <entry>
            <title type="html">What is Web 2.0? Really.</title>
            <link href="http://friendlybit.com/js/what-is-web-20-really/" rel="alternate" type="text/html" title="What is Web 2.0? Really." />
            <published>2007-03-10T00:59:52+01:00</published>
            <updated>2007-03-10T00:59:52+01:00</updated>
            <id>http://friendlybit.com/js/what-is-web-20-really/</id>
            <author>
                <name>Emil Stenström</name>
            </author>
            <summary type="text">Web 2.0 is really hot right now. One of Sweden&#39;s biggest newspapers recently wrote a long article on their debate section. They had started linking back to...</summary>
            <content type="html" xml:base="http://friendlybit.com/js/what-is-web-20-really/">
                &lt;p&gt;Web 2.0 is really hot right now. One of Sweden&#39;s biggest newspapers recently wrote a long article on their debate section. They had started linking back to blogs that linked to them, in a little box next to the article. The problem was that they had got into trouble with what blogs to link to. After all, you can&#39;t just link to anything, right?&lt;/p&gt;
&lt;p&gt;Aside from starting to think about the implications of blog links, I got another interesting question in my head. What is Web 2.0 really? Most people working with interface development would say that Web 2.0 is everything that uses AJAX. But the newspaper didn&#39;t use AJAX at all, and still they claim links to blogs is Web 2.0. Time for some research!&lt;/p&gt;
&lt;h2 id=&#34;the-hunt-for-a-definition&#34;&gt;The hunt for a definition&lt;a href=&#34;#the-hunt-for-a-definition&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The phrase &amp;quot;Web 2.0&amp;quot; was first put into widespread use at an O&#39;Reilly conference in 2004. The organizers wanted to talk about a change that has happened on the web, and just bumping the version of the web seemed like a good idea. Paul Graham found this &lt;a href=&#34;http://www.paulgraham.com/web20.html#f1n&#34;&gt;first try at defining Web 2.0&lt;/a&gt; at the conference:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;While the first wave of the Web was closely tied to the browser, the second wave extends applications across the web and enables a new generation of services and business opportunities.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Note that there&#39;s no mention of AJAX there. Hell, there&#39;s no mention of users either! They must have meant something else, and the definition might have changed over the years since then. Let&#39;s keep looking for a good definition.&lt;/p&gt;
&lt;p&gt;Tim O&#39;Reilly comments on the issue two years later, in a &lt;a href=&#34;http://radar.oreilly.com/archives/2006/12/web_20_compact.html&#34;&gt;clarification on his blog&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Web 2.0 is the business revolution in the computer industry caused by the move to the internet as platform, and an attempt to understand the rules for success on that new platform. Chief among those rules is this: Build applications that harness network effects to get better the more people use them.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Tim acknowledges the change in meaning and talks about &amp;quot;network effects&amp;quot; here, something that starts to look a little bit more like what my idea of Web 2.0 is. But isn&#39;t there still something missing? To me, that looks only like a small part of what I call Web 2.0. Let&#39;s keep looking…&lt;/p&gt;
&lt;p&gt;Gartner has tried to convince companies of the merits of Web 2.0 for a rather long time. In one of their many (business oriented) PowerPoint presentations they attempt to define &amp;quot;three anchor points around Web 2.0&amp;quot;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Technology and Architecture&lt;/strong&gt; — Consisting of Web-oriented architecture (WOA) and Web platforms.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Community&lt;/strong&gt; — Looks at the dynamics around social networks and other personal content public/shared models, wiki and other collaborative content models.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Business Model&lt;/strong&gt; — Web service-enabled business models, mashup/remix applications and so forth.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;I believe we&#39;re getting closer. Gartner is making business models a separate point which I don&#39;t agree with. Many of the biggest Web 2.0 sites didn&#39;t have a business model when they started (and many still don&#39;t). Digg has troubles covering their hosting cost with the tiny bit of money they acquire from their ads. Del.icio.us still doesn&#39;t make any direct money (although they got sold to Yahoo, and they surely use the data…). My point is, a business plan isn&#39;t one third of Web 2.0, it&#39;s something sites add afterwards if things work out.&lt;/p&gt;
&lt;p&gt;So let me state my own (slightly more general) definition of Web 2.0:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;A collection of ideas and techniques that can be used to make more interactive sites&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The thing is, just doing something in AJAX does not mean it gets the Web 2.0 stamp of approval. You need several of the ideas or techniques and you need to combine them in clever ways. So lets agree on the definition above and got look for ideas.&lt;/p&gt;
&lt;h2 id=&#34;ideas-that-are-part-of-web-20&#34;&gt;Ideas that are part of Web 2.0&lt;a href=&#34;#ideas-that-are-part-of-web-20&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I&#39;d like to gather a whole bunch of ideas under the Web 2.0 roof. My selection is of course not all there is. Googling could uncover more I&#39;m sure, but I think this is a good start.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#generated&#34;&gt;User generated content&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#trust&#34;&gt;Radical trust&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#syndication&#34;&gt;Syndication of content and services&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#tail&#34;&gt;Long tail&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#collective&#34;&gt;Collective intelligence&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;generated&#34;&gt;User generated Content&lt;a href=&#34;#generated&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Many companies still view the web as a one-way medium, an extension of a paper catalog, it&#39;s main advantage being that it can be distributed to more people. It&#39;s not like that any more! There are people that want to add content to your site, that want to contribute their ideas and thoughts. Why are you denying them to help you?&lt;/p&gt;
&lt;p&gt;User generated content is content that your users are willing to give you. It can be everything from a simple &amp;quot;like it&amp;quot; or &amp;quot;don&#39;t like it&amp;quot;, to fully featured articles written by users. The two most used ways of contributions are the simple ones: votes and comments. The author is still in full control of the content but users are given a chance to chip in with minor corrections. This is the least you can do. It&#39;s what I do on this blog; let you chip in by commenting.&lt;/p&gt;
&lt;p&gt;But if you have users that are passionate about your subject, users that are willing to use your site to get their ideas out, you should really endorse that! Allow them to post articles on your site, allow them to regroup and re-prioritize according to their own wishes. It is technically possible, even rather easy to do; you just have to do it.&lt;/p&gt;
&lt;p&gt;Six simple things your users can help you with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reviews of your products&lt;/li&gt;
&lt;li&gt;Comments on your articles&lt;/li&gt;
&lt;li&gt;Stories about how people use your product&lt;/li&gt;
&lt;li&gt;Multimedia using your product&lt;/li&gt;
&lt;li&gt;Questions about your products&lt;/li&gt;
&lt;li&gt;Articles in an area you choose&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;trust&#34;&gt;Radical trust&lt;a href=&#34;#trust&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img class=&#34;secondary&#34; src=&#34;/files/web20/wikipedia.png&#34; alt=&#34;Logotype of Wikipedia&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Another approach many sites have taken can be summarized as &amp;quot;radical trust&amp;quot;. It builds on the simple idea that users know what they want better than you do. So let them order, categorize, sort, select your data as they like!&lt;/p&gt;
&lt;p&gt;This is exactly what wikis do. They acknowledge that there are more users doing good than doing bad. If that&#39;s the case, why not let them in on your content directly, letting them edit and improve it like they want. They few people that do bad can be hunted away with a combination with versioning (saving old versions of content that&#39;s easy to restore), and some simple monitoring. Wikis trust users, do you?&lt;/p&gt;
&lt;h3 id=&#34;syndication&#34;&gt;Syndication of content and services&lt;a href=&#34;#syndication&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Web 2.0 is not only about &amp;quot;user to website&amp;quot; interactivity. It&#39;s also about letting other sites and tools interact with your site directly. This is often summarized as &amp;quot;syndication&amp;quot;.&lt;/p&gt;
&lt;p&gt;It&#39;s a very fancy word for a simple concept. Let me try to explain.&lt;/p&gt;
&lt;p&gt;Somewhere you have some kind of database with your content, be it products in your e-store or posts on your blog. Usually you take that content, add some structure (HTML) to it, and send it to the user.&lt;/p&gt;
&lt;p&gt;Another website that wants to access the same information could parse the HTML and try to understand what it means, something called &amp;quot;screen scraping&amp;quot; (or microformats ;). The problem with that method is that it&#39;s very dependent on that the webmaster doesn&#39;t decide to change the HTML. The other problem is that computers and humans often want different types of information. A computer that is going to parse a list of your products doesn&#39;t need navigation like humans do. What you do is send your data directly to computers instead, without messing it up with HTML. Formats include: RDF, RSS, or perhaps custom XML through a Web Service.&lt;/p&gt;
&lt;p&gt;Thing is, when you start syndicating your data you make it easier for others build services based on it. Now people get several entrances into your content instead of the one you produced. Again, your users are helping you reach more people.&lt;/p&gt;
&lt;p&gt;Allowing full RSS feeds is another way of syndicating, I&#39;m switching right now. Do you syndicate?&lt;/p&gt;
&lt;h3 id=&#34;tail&#34;&gt;Long tail&lt;a href=&#34;#tail&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img class=&#34;secondary&#34; src=&#34;/files/web20/tail.png&#34; alt=&#34;Graph of a sold units per item&#34; /&gt;&lt;/p&gt;
&lt;p&gt;The theory of the long tail is one of the ideas that are usually associated with Web 2.0. It&#39;s a business model that many companies that are successful on the web use. As with most business models they are invented after the fact, and as such I&#39;m not sure it really belongs on this list, but people always bring it up, so let’s go. I&#39;ll let you choose yourself.&lt;/p&gt;
&lt;p&gt;Wikipedia describes the long tail like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Products that are in low demand […] can collectively make up a market share that rivals or exceeds the relatively few current bestsellers and blockbusters, if the store or distribution channel is large enough&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Most physical stores need to aim for the bestsellers to sell anything. There&#39;s simply too few interested in odd products, to make it worth hiring store space and personnel to sell it.&lt;/p&gt;
&lt;p&gt;Web based stores are in a different position. Selling another product usually means just adding another page to your site, no extra store space or personnel needed. In addition people are prepared to wait a couple of days before receiving their products. That time span means you can skip warehouses and not start producing your products until you have an order ready.&lt;/p&gt;
&lt;p&gt;No more is there a need to estimate what people will be interested in and pre-order them. For the right kind of product the internet is a huge benefit. Amazon did it with books, iTunes did it with music, do you do it?&lt;/p&gt;
&lt;h3 id=&#34;collective&#34;&gt;Collective intelligence&lt;a href=&#34;#collective&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;You have let each user customize their experience and add content of their own. Now it&#39;s time to organize that content to better help the everyone benefit from it. There&#39;s hundreds of ways of doing it, but here&#39;s a couple of things that you can present to your users:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The most popular Swedish article right now…&lt;/strong&gt; - Crawl all Swedish blogs and keep track of what they link to.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Others that bought this book also bought…&lt;/strong&gt; - Query your shipment table. Pick a product, select the number of times each other product appeared together with said product, and recommend that product to your customers. Amazon does this and it&#39;s said that it has increased their profits considerably.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;You probably think this movie is a four out of five&lt;/strong&gt; - A Swedish movie site give its users personalized ratings of movies. They find users that have similar taste as you have (based on your previous grades) and then checks what those people have rated the movie as.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;This is probably spam&lt;/strong&gt; - Write a word filter that learns what is considered spam when users mark them. Share that filter with fellow users and let their markings stop your spam. A form of collective sieve filtering, Akismet does this.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;None of them are technologically hard to do, you just Google and copy other people&#39;s samples. Why not?&lt;/p&gt;
&lt;h2 id=&#34;techniques-involved-in-web-20&#34;&gt;Techniques involved in Web 2.0&lt;a href=&#34;#techniques-involved-in-web-20&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;But there are techniques involved too. Let&#39;s go through a few of the important ones.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#ajax&#34;&gt;AJAX (and other javascript)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#feeds&#34;&gt;Feeds (RSS, Atom)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#tags&#34;&gt;Tags&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;ajax&#34;&gt;AJAX (and other javascript)&lt;a href=&#34;#ajax&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Everyone talks about AJAX together with Web 2.0, but I think it&#39;s important they are kept separate.&lt;/p&gt;
&lt;p&gt;AJAX is just a technology that helps prevent (full) page reloads. Instead you connect to the server silently in the background and receive your data that way. What&#39;s the revolutionary about this technique? Nothing. It has been in use for at least 5 years. They new thing about it is that people started using it to build better interfaces.&lt;/p&gt;
&lt;p&gt;Javascript is language that enables AJAX, and playing with reloads is not all it can do. Through some nifty use you can change attributes on any HTML element on the page. Move things around, react to mouse movement, fade and animate, it&#39;s your choice. This means a lot of new controls become possible, ranging from simple sliders to interactive maps.&lt;/p&gt;
&lt;p&gt;Why do most accessibility people hate it? Because most developers don&#39;t know enough about accessibility. And when those start to use AJAX they disregard accessibility completely. Javascript and AJAX have different goals and I think a good compromise is making sure the basic functions of the site (buy a product and pay for it) works without javascript, but enabling it adds additional features.&lt;/p&gt;
&lt;p&gt;When was the last time you used javascript to enhance your site? What was the last control you invented?&lt;/p&gt;
&lt;h3 id=&#34;feeds&#34;&gt;Feeds (RSS, Atom)&lt;a href=&#34;#feeds&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img class=&#34;secondary&#34; src=&#34;/files/web20/feeds.png&#34; alt=&#34;The official feed icon&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Feeds are great for syndication of content. There are many different feed formats to choose from but they all have one purpose: to communicate pure data, skipping all design.&lt;/p&gt;
&lt;p&gt;A feed is simply a list of feed items, each with an unique identifier. A user adds the address to their &amp;quot;feed reader&amp;quot; and it starts polling you, asking for updates. I have my reader set to just a couple of minutes, making sure I quickly notice changes in people&#39;s feeds.&lt;/p&gt;
&lt;p&gt;The good thing about feeds is that they make it easy to follow several at once. There&#39;s no annoying different designs in the way if you don&#39;t want to (you can always just visit the site if you want design). Feeds are getting more and more of a commodity; you should already be allowing your users the possibility to subscribe your content. Do you?&lt;/p&gt;
&lt;h3 id=&#34;tags&#34;&gt;Tags&lt;a href=&#34;#tags&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Tags is another hip concept. It deals with the collective intelligence idea and how to categorize content efficiently. A tag consists of a phrase of some kind that describes a piece of content. This blog post could have the tag &amp;quot;javascript&amp;quot;.&lt;/p&gt;
&lt;p&gt;There&#39;s several ways you can use them. One is the just fix what tags are allowed and use them as regularly groups you can assign content to. But allowing more than one tag enable you to do more than just split things into groups, you can instead pick all contents bits that have the same tag. You can go further, allowing custom tags that the users can pick themselves. That gives you a wide array of descriptive words for your content, free to play around with. For example, if many users pick the same word, that one is probably a better descriptor.&lt;/p&gt;
&lt;p&gt;Picking many bits of content and analyzing all tags tied to them can be easily done with a tag cloud. In that you simply print all tags used after each other, and make those used often bigger. Doing this on a whole site is an effective way of giving users a snapshot of what you write about, something I know I like.&lt;/p&gt;
&lt;p&gt;Can tags help you solve a categorization problem you have?&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;a href=&#34;#summary&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now. To build a Web 2.0 site, pick from both of the lists above. You Google for more ideas and you work hard to interact with your users as much as possible. Web 2.0 is the combination that happens when your ideas and technology finally just works.&lt;/p&gt;
&lt;p&gt;Your users want to help you, do you let them in?&lt;/p&gt;

            </content>
        </entry>
    
        <entry>
            <title type="html">Improving interactivity with Javascript</title>
            <link href="http://friendlybit.com/js/improving-interactivity-with-javascript/" rel="alternate" type="text/html" title="Improving interactivity with Javascript" />
            <published>2007-02-21T22:13:21+01:00</published>
            <updated>2007-02-21T22:13:21+01:00</updated>
            <id>http://friendlybit.com/js/improving-interactivity-with-javascript/</id>
            <author>
                <name>Emil Stenström</name>
            </author>
            <summary type="text">Push buttons, radio buttons, check boxes, select boxes, and text inputs. That&#39;s the controls HTML allows us to use to interact with our users. A small...</summary>
            <content type="html" xml:base="http://friendlybit.com/js/improving-interactivity-with-javascript/">
                &lt;p&gt;Push buttons, radio buttons, check boxes, select boxes, and text inputs. That&#39;s the controls HTML allows us to use to interact with our users.&lt;/p&gt;
&lt;p&gt;A small dedicated group of people at the office (I work at &lt;a href=&#34;http://www.valtech.se&#34;&gt;Valtech&lt;/a&gt;) sat down and listed all controls we could think of. The list below is basically that list, completed with examples where possible. Let me stress that the below controls are meant as &lt;strong&gt;inspiration&lt;/strong&gt;. They are not all free, or even available for download. If you decide to use one of the ideas, google for them first and pick the best one. While selecting one, make sure it supports some kind of fallback for users without javascript enabled.&lt;/p&gt;
&lt;h2 id=&#34;slider&#34;&gt;Slider&lt;a href=&#34;#slider&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Slider control meant to let users select values from a range of options.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://webfx.eae.net/dhtml/slider/slider.html&#34;&gt;&lt;img src=&#34;/files/ajaxexamples/slider.png&#34; alt=&#34;Slider control&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;date-picker&#34;&gt;Date picker&lt;a href=&#34;#date-picker&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;What format should this date be? What weekday is the 15:th of august? A good date picker helps the user answer those questions and makes filling in dates much more delighful.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.basicdatepicker.com/&#34;&gt;&lt;img src=&#34;/files/ajaxexamples/datepicker.png&#34; alt=&#34;Date picker&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;smart-text-boxes&#34;&gt;Smart text boxes&lt;a href=&#34;#smart-text-boxes&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;It&#39;s easy to make some text boxes only allow certain kinds of characters. Why allow letters in the age field?&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.cambiaresearch.com/c4/029c978b-aac5-472e-97a8-95b256f5febd/How-Can-I-Use-Javascript-to-Allow-Only-Numbers-to-Be-Entered-in-a-TextBox.aspx&#34;&gt;&lt;img src=&#34;/files/ajaxexamples/smarttextbox.png&#34; alt=&#34;Text box that only allows numbers&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;mixing-text-inputs-with-select-boxes&#34;&gt;Mixing text inputs with select boxes&lt;a href=&#34;#mixing-text-inputs-with-select-boxes&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Allow users to both input text and pick common options.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.google.com/webhp?complete=1&amp;amp;hl=en&#34;&gt;&lt;img src=&#34;/files/ajaxexamples/gsuggest.png&#34; alt=&#34;Google Suggest&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/files/ajaxexamples/extratasty.png&#34; alt=&#34;Ingredience picker with AJAX&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;drag-and-drop&#34;&gt;Drag and Drop&lt;a href=&#34;#drag-and-drop&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Users are used to dragging and dropping things from their operating systems. Letting them do the same on the web makes for a great affect! Don&#39;t forget about a fallback though, not everyone uses a mouse (A buy-button is enough).&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/files/ajaxexamples/dragdrop.png&#34; alt=&#34;Example shop with drag and drop&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.panic.com/goods/&#34;&gt;&lt;img src=&#34;/files/ajaxexamples/panic.png&#34; alt=&#34;Real shop with drag and drop&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;collapse-and-expand-control&#34;&gt;Collapse and expand control&lt;a href=&#34;#collapse-and-expand-control&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Makes it possible to quickly show less important information on demand. Just make sure everything is open by default (with no javascript).&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/files/ajaxexamples/expand.png&#34; alt=&#34;Toggling a block is easy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;advanced-tooltips&#34;&gt;Advanced tooltips&lt;a href=&#34;#advanced-tooltips&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When the title attribute is not enough. Use images, fine-tune the delay, make them sticky if you click them, it&#39;s all up to you!&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/files/ajaxexamples/tooltip.png&#34; alt=&#34;Tool tips with a little spice&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;autosaving-form-fields&#34;&gt;Autosaving form fields&lt;a href=&#34;#autosaving-form-fields&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you write an email with &lt;a href=&#34;http://www.gmail.com&#34;&gt;Gmail&lt;/a&gt; and the browser crashes, you&#39;ll appreciate that Gmail automatically saves your text regularly. It&#39;s done with a simple piece of javascript that periodically sends all your text off to the server, and saves it away. Simple and &lt;strong&gt;very&lt;/strong&gt; useful.&lt;/p&gt;
&lt;h2 id=&#34;auto-validation&#34;&gt;Auto validation&lt;a href=&#34;#auto-validation&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;While filling in some forms you&#39;ll notice a little green check on the side. I can&#39;t begin to praise how much faster this makes filling out forms. Directly after you&#39;ve written enough letters in the password field you&#39;ll find that it&#39;s ok. No more trial and error against a slow server (unless you have javascript off, of course).&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.zapatec.com/website/ajax/zpform/doc/demo.html#ajax.html&#34;&gt;&lt;img src=&#34;/files/ajaxexamples/autovalid.png&#34; alt=&#34;Early notification that the password is correct&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;controls-affecting-each-other&#34;&gt;Controls affecting each other&lt;a href=&#34;#controls-affecting-each-other&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In complex forms it&#39;s not unusual to want the user to fill in either one set of fields or another. The showing and hiding of what fields are available is a another perfect case of where javascript really helps.&lt;/p&gt;
&lt;h2 id=&#34;image-handling&#34;&gt;Image handling&lt;a href=&#34;#image-handling&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;It&#39;s time to get easy handling of images in browsers. Javascript can help there too, by combining drag and drop with resizing and so on. Photoshop, here we come!&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.walterzorn.com/dragdrop/dragdrop_e.htm&#34;&gt;&lt;img src=&#34;/files/ajaxexamples/images.png&#34; alt=&#34;Images you can move and resize in the browser&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;search-based-or-structured-navigation&#34;&gt;Search-based or structured navigation&lt;a href=&#34;#search-based-or-structured-navigation&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Sometimes new navigation schemes can be useful. Using search instead of navigation is an interesting idea. Another is letting the user pick categories and using them in search.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.vitvarumaklarna.se/&#34;&gt;&lt;img src=&#34;/files/ajaxexamples/searchstructure.png&#34; alt=&#34;Menu that allows expanding and searching&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;better-stronglookingstrong-form-fields&#34;&gt;Better &lt;strong&gt;looking&lt;/strong&gt; form fields&lt;a href=&#34;#better-stronglookingstrong-form-fields&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Javascript also allows you to enhance existing form fields with prettier equivalents.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/files/ajaxexamples/checkboxes.png&#34; alt=&#34;Pretty form controls&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;sortable-items&#34;&gt;Sortable items&lt;a href=&#34;#sortable-items&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Sometimes you want drag and drop in a more controllable manner. Why not use it to make it easier to sort your lists?&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/files/ajaxexamples/sortable.png&#34; alt=&#34;Sortable list items&#34; /&gt;&lt;/p&gt;
&lt;p&gt;That&#39;s all! Hope I&#39;ve given you some ideas of widgets/controls you can use to enhance user experience. Good luck!&lt;/p&gt;

            </content>
        </entry>
    
        <entry>
            <title type="html">Flash-only vs. AJAX sites</title>
            <link href="http://friendlybit.com/js/flash-only-vs-ajax-sites/" rel="alternate" type="text/html" title="Flash-only vs. AJAX sites" />
            <published>2007-01-16T00:02:35+01:00</published>
            <updated>2007-01-16T00:02:35+01:00</updated>
            <id>http://friendlybit.com/js/flash-only-vs-ajax-sites/</id>
            <author>
                <name>Emil Stenström</name>
            </author>
            <summary type="text">Even though web developers like me have discouraged from building Flash-only sites for as long as I remember, they are popping up all over the place. For no...</summary>
            <content type="html" xml:base="http://friendlybit.com/js/flash-only-vs-ajax-sites/">
                &lt;p&gt;Even though web developers like me have discouraged from building Flash-only sites for as long as I remember, they are popping up all over the place. For no reason! We are ready to make the leap to standards. And our weapon with be AJAX.&lt;/p&gt;
&lt;h2 id=&#34;what-kind-of-sites-are-built-with-only-flash&#34;&gt;What kind of sites are built with only Flash?&lt;a href=&#34;#what-kind-of-sites-are-built-with-only-flash&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let&#39;s start by having a look at a few big Flash sites. Because they exist, and keep popping up all over the place. Here&#39;s a couple of movie sites using it: &lt;a href=&#34;http://thedeparted.warnerbros.com/&#34;&gt;Departed&lt;/a&gt;, &lt;a href=&#34;http://www.sonypictures.com/homevideo/underworldevolution/index.html&#34;&gt;Underworld Evolution&lt;/a&gt;, &lt;a href=&#34;http://whatisthematrix.warnerbros.com/&#34;&gt;Matrix&lt;/a&gt;; Here&#39;s a couple of big brands: &lt;a href=&#34;http://www.coca-cola.se&#34;&gt;Coca-cola&lt;/a&gt;, Nike, &lt;a href=&#34;http://electrolux.com/&#34;&gt;Electrolux&lt;/a&gt;. These sites are more than just animated images, they have their own content and often need to get updated continuously.&lt;/p&gt;
&lt;h2 id=&#34;whats-the-purpose-of-them&#34;&gt;What&#39;s the purpose of them?&lt;a href=&#34;#whats-the-purpose-of-them&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before deciding on anything we need to examine what purpose these sites have. It&#39;s not OK to change the purpose of the site just because we dislike the technology behind it. I can&#39;t possibly know the reasons behind all of the campaigns going on today but I believe there&#39;s a core that most sites are after.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Promote something new&lt;/strong&gt; - Someone wants to to push some of their products/deals/ideas to the spotlight.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Specific target audience&lt;/strong&gt; - Companies are well aware that what kind of people they reach initially will define if the product is successful or not. Many want the hip people.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;updating-flash-files-is-hard&#34;&gt;Updating flash files is hard&lt;a href=&#34;#updating-flash-files-is-hard&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Many years ago it was ok just to throw up static information on a site and have a good site. Don&#39;t get me wrong, content is still king, what has changed is that content alone isn&#39;t enough. We demand much more from a good website. Coca Cola can&#39;t just publish a press release telling us that there is a new taste out. It&#39;s the Web 2.0 age and we want to be able to send our own tasting stories in, we want to be able to see live counters of the number of bottles sold, and we want forums to talk amongst ourselves about our experiences. We want tags! You get the point.&lt;/p&gt;
&lt;p&gt;How does this affect the choice of flash or not? We need dynamics, ways for both editors and users to add content to the site, and &lt;strong&gt;Flash files are hard to update&lt;/strong&gt;! Just the fact that I need a special program to edit them speaks for itself.&lt;/p&gt;
&lt;p&gt;Another fact: As you probably know, it&#39;s rare (in the real world) to have the same person both writing code and publishing content. The coders need to cater for that, and make sure it&#39;s easy for editors to add new content. Now. Even if you&#39;ve bought licenses and are able to edit flash files, you can&#39;t expect editors to understand all about how flash works. So you need to build a content management system (CMS) of some kind. If you buy one, you still need to integrate it with your current code.&lt;/p&gt;
&lt;p&gt;&amp;quot;But&amp;quot;, I hear you say, &amp;quot;…you have that same problem with non-Flash sites!&amp;quot;. Yes, but the difference is that CMS tools that publish HTML have existed a lot longer. This affects both the quality, usability and ease of integration with current systems. A HTML-based site will therefore be easier to update, making for both more and fresher content that reaches more people. If it&#39;s easy enough to update the site, you can even let users do it, Web 2.0 style.&lt;/p&gt;
&lt;h2 id=&#34;flash-is-not-hip-any-longer&#34;&gt;Flash is not hip any longer&lt;a href=&#34;#flash-is-not-hip-any-longer&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Publishing a site with Flash today is hardly going to get mentioned at all. AJAX has completely taken over the scene and anyone even whispering AJAX gets to the front page of digg.&lt;/p&gt;
&lt;p&gt;Aside from the technology buzz we have had some real changes rather recently: Javascript can now deliver what was once only available with Flash. It can fade, move, round corners, drag-drop, auto-save, validate, the list could go on forever… There&#39;s several effect libraries available that makes using all those effects easity. All the good ones are even free.&lt;/p&gt;
&lt;h2 id=&#34;flash-only-vs-ajax-the-showdown&#34;&gt;Flash-only vs. AJAX - The showdown&lt;a href=&#34;#flash-only-vs-ajax-the-showdown&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I&#39;ve made a small list of things that matters when you build a website today, and evaluated each one of them for both Flash-only and AJAX.&lt;/p&gt;
&lt;table&gt;
  &lt;tr&gt;
    &lt;td&gt;
    &lt;/td&gt;
    &lt;th scope=&#34;col&#34;&gt;
      Flash
    &lt;/th&gt;
    &lt;th scope=&#34;col&#34;&gt;
      AJAX
    &lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&#34;row&#34;&gt;
      Accessibility
    &lt;/th&gt;
    &lt;td class=&#34;incorrect&#34;&gt;
      &lt;strong&gt;Poor&lt;/strong&gt;. There&#39;s problems with everything from how a flash app gets its initial focus from the browser window, to unusual interaction controls, to lack of text resize. In summary, zero points.
    &lt;/td&gt;
    &lt;td class=&#34;almost&#34;&gt;
      &lt;strong&gt;Moderate&lt;/strong&gt;. AJAX has problems with requiring js for accessing data, but smart developers have started thinking in terms of accessibility and fixed many of AJAX initial flaws. &lt;a href=&#34;http://www.robertnyman.com/2006/02/08/ask-ajax-source-kit&#34;&gt;Nyman&#39;s ASK&lt;/a&gt; is one way.
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&#34;row&#34;&gt;
      Search Engine Optimization (SEO)
    &lt;/th&gt;
    &lt;td class=&#34;incorrect&#34;&gt;
      &lt;strong&gt;Poor&lt;/strong&gt;. Search engines don&#39;t read flash files (even though they probably could). Some people claim that you should &lt;a href=&#34;http://blog.deconcept.com/2006/03/13/modern-approach-flash-seo/&#34;&gt;duplicate all your content&lt;/a&gt;. I say that will be a mess to update.
    &lt;/td&gt;
    &lt;td class=&#34;almost&#34;&gt;
      &lt;strong&gt;Moderate&lt;/strong&gt;. If you just use the javascript effects you are fine, if you fetch data with javascript you need to write a little script that reloads the content and gets it that way instead. It is possible, but not easy enough. Bonus: if you fix accessibility you often get this too.
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&#34;row&#34;&gt;
      Ease of content change
    &lt;/th&gt;
    &lt;td class=&#34;incorrect&#34;&gt;
      &lt;strong&gt;Poor&lt;/strong&gt;. You need an expensive program to edit the files. ? Only available on PCs running Windows. Few CMS:es available (any?) that makes it easy for editors to update content.
    &lt;/td&gt;
    &lt;td class=&#34;correct&#34;&gt;
      &lt;strong&gt;Strong&lt;/strong&gt;. All the big CMS:es can be used together with an AJAX app, it&#39;s just a matter of changing the templates on the front. Systems like Ruby on Rails (while not being a CMS) have built in support for AJAX stuff, but including a framework in older systems is no big deal.
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&#34;row&#34;&gt;
      Hipness
    &lt;/th&gt;
    &lt;td class=&#34;incorrect&#34;&gt;
      &lt;strong&gt;Poor&lt;/strong&gt;. There used to be a big community of flash developers that got incredible respect in the webdev community with their flash-only sites. Many of these communities have been replaced by CSS Galleries of different kinds.
    &lt;/td&gt;
    &lt;td class=&#34;correct&#34;&gt;
      &lt;strong&gt;Strong&lt;/strong&gt;. While Flash-only developers focused mainly on visuals the AJAX community have focused more on user experience, building applications that &lt;em&gt;feels&lt;/em&gt; better to use. Together with the technology buzz behind it AJAX solutions have gotten (and still get) a great response from the start. The potential for marketing campaigns based on user experience in huge.
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&#34;row&#34;&gt;
      Graphic effects
    &lt;/th&gt;
    &lt;td class=&#34;correct&#34;&gt;
      &lt;strong&gt;Strong&lt;/strong&gt;. This wouldn&#39;t be a fair comparison if we didn&#39;t acknowledge that Flash is far ahead of AJAX when it comes to graphic effects. Most of this is based in the fact that you are working in an application instead of a website, and things like anti-aliasing, drop shadows, transitions, and filters have existed for long.
    &lt;/td&gt;
    &lt;td class=&#34;almost&#34;&gt;
      &lt;strong&gt;Moderate&lt;/strong&gt;. Websites was long lacking pretty interfaces but in the recent years we&#39;ve seen an explosion of graphic effects even in the standards world, probably starting with the famous &lt;a href=&#34;http://www.csszengarden.com/&#34;&gt;CSS Zengarden&lt;/a&gt;.
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th scope=&#34;row&#34;&gt;
      Integration with existing sites
    &lt;/th&gt;
    &lt;td class=&#34;almost&#34;&gt;
      &lt;strong&gt;Moderate&lt;/strong&gt;. Few code libraries are written to work well together with flash, so often you have to do the integration yourself. In it&#39;s latest version Flash has gotten more integration points with the possibility to communicate with javascript, import HTML and so on. Better, but not perfect.
    &lt;/td&gt;
    &lt;td class=&#34;correct&#34;&gt;
      &lt;strong&gt;Strong&lt;/strong&gt;. Most effect libraries are built to be as easy to include as possible. The usual way to make use of one is two lines long: link a javascript file and call the right function. The more advanced libraries that enable asynchronous loading require some more work, but unless you want advanced error handling it&#39;s no big deal.
    &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;Next time a customer ask for a Flash-only site, tell them about AJAX and it&#39;s advantages.&lt;/p&gt;

            </content>
        </entry>
    
        <entry>
            <title type="html">Web development blogs you should read</title>
            <link href="http://friendlybit.com/css/web-development-blogs-you-should-read/" rel="alternate" type="text/html" title="Web development blogs you should read" />
            <published>2006-11-19T04:40:48+01:00</published>
            <updated>2006-11-19T04:40:48+01:00</updated>
            <id>http://friendlybit.com/css/web-development-blogs-you-should-read/</id>
            <author>
                <name>Emil Stenström</name>
            </author>
            <summary type="text">The web is filled with blogs about web development. I&#39;m always looking for good blogs to add to my feed reader and I thought some of you might do that too....</summary>
            <content type="html" xml:base="http://friendlybit.com/css/web-development-blogs-you-should-read/">
                &lt;p&gt;The web is filled with blogs about web development. I&#39;m always looking for good blogs to add to my feed reader and I thought some of you might do that too. So let me list the webdev blogs I subscribe to right now (in alphabetic order):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&#34;http://www.456bereastreet.com/&#34;&gt;456 Berea St&lt;/a&gt;&lt;/strong&gt; - Roger Johansson is one of the most well known web developers out there, and it&#39;s for a reason. He posts almost daily about things happening in the webdev field. Everything from short comments with links to things to full blown articles.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&#34;http://headrush.typepad.com/creating_passionate_users/&#34;&gt;Creating passionate users&lt;/a&gt;&lt;/strong&gt; - Simply one of the best blogs there is, all categories. Deals with usability and making users happy. The posts are everything from hilarious to spectacular and I often get the motivation to write from here. Read an article or just look at one of the wonderful graphs. You&#39;ll love it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&#34;http://www.thefutureoftheweb.com/&#34;&gt;Future of the web&lt;/a&gt;&lt;/strong&gt; - Jesse Skinner writes for all skill levels. Articles vary from basic markup to advanced javascript tutorials. Often with a twist of humour added in the middle of an article. Nice read.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&#34;http://mondaybynoon.com&#34;&gt;Monday By Noon&lt;/a&gt;&lt;/strong&gt; - Jon posts articles weekly (as reflected in the name) about all things related to web development. His friendly tone and ability to explain things makes this site ideal for people starting out. The good thing is that the same style works for more experienced people too. Try one of the articles, I&#39;m sure you&#39;ll like it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&#34;http://f6design.com/journal/&#34;&gt;Pixel Acres&lt;/a&gt;&lt;/strong&gt; - Jonathan Nicol combines webdev articles with thoughts on how to deal with clients and co-workers. Well written and qualitative, what else do you need?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&#34;http://www.robertnyman.com/&#34;&gt;Robert&#39;s talk&lt;/a&gt;&lt;/strong&gt; - Robert Nyman&#39;s blog, mixing personal posts with those that have to do with all kinds of interfaces. Entertaining read that feels balanced and well thought-out.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&#34;http://rundkvadrat.com/&#34;&gt;Rund kvadrat&lt;/a&gt;&lt;/strong&gt; - Blog in Swedish about making money on the web. While this isn&#39;t the primary concern for many interface developers we should certainly keep it in mind. Does moving a certain link upwards increase the client&#39;s sales?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Well, and then there&#39;s all the big ones, but they tend to post too much about the conferences they attended and the books they wrote. Also, all their good articles end up on the big webdev news sites, which I also subscribe to.&lt;/p&gt;
&lt;p&gt;Do you have any other sites that should be on that list?&lt;/p&gt;

            </content>
        </entry>
    
        <entry>
            <title type="html">How web standards feels</title>
            <link href="http://friendlybit.com/css/how-web-standards-feels/" rel="alternate" type="text/html" title="How web standards feels" />
            <published>2006-10-11T21:34:42+02:00</published>
            <updated>2006-10-11T21:34:42+02:00</updated>
            <id>http://friendlybit.com/css/how-web-standards-feels/</id>
            <author>
                <name>Emil Stenström</name>
            </author>
            <summary type="text">When talking about web standards many of us have started using marketing terms. Every day we hear about the bandwidth savings, the increased user base that...</summary>
            <content type="html" xml:base="http://friendlybit.com/css/how-web-standards-feels/">
                &lt;p&gt;When talking about web standards many of us have started using marketing terms. Every day we hear about the bandwidth savings, the increased user base that are able to access your site, how well it affects SEO and so on. But none of that was what got me into all this. Let me tell you about the thing that convinced me: the feeling.&lt;/p&gt;
&lt;p&gt;For me the web standards revolution started with a feeling that something was wrong. &amp;quot;There has got to be a better way&amp;quot;, was a thought that buzzed in my ears when nesting my tables to create some padding.&lt;/p&gt;
&lt;p&gt;I first saw CSS in other people&#39;s code, often embedded in style attributes with text-decoration: none; to remove underlines. I started experimenting, but the deeper aspects of how it could change the way websites were built didn&#39;t occur to me. It was just another tool to place things where I wanted them, and make things look like I wanted.&lt;/p&gt;
&lt;p&gt;At that time I didn&#39;t know any server-side language so all my sites where frame based static HTML, often with a fancy javascript enabled select box for navigation. I did use some CSS just to remove the underlinings on my links, but that was it. Something still felt wrong, was this really the best way?&lt;/p&gt;
&lt;p&gt;The &amp;quot;AHA!&amp;quot; feeling came much later; I&#39;d love to say a certain moment when I understood but it wasn&#39;t a certain text or piece of advice, it grew on me. Suddenly everything felt like it had its place. It wasn&#39;t always obvious where that place was, but you could reason your way there. When the strength of CSS occurred to me, it was like finally understanding a tough mathematical formula. Yes!&lt;/p&gt;
&lt;p&gt;So go ahead, show me your pretty charts of workday savings, &lt;a href=&#34;http://csszengarden.com/&#34;&gt;CSS Zen garden&lt;/a&gt; remakes, or new techniques you can use. I like them, I really do, but I&#39;m pretty convinced it&#39;s the &amp;quot;AHA!&amp;quot; feeling that finally wins people over to the web standards side.&lt;/p&gt;
&lt;p&gt;What won you over? Can you convince someone else using that method?&lt;/p&gt;
&lt;p&gt;(Inspiration from &lt;a href=&#34;http://headrush.typepad.com/creating_passionate_users/2006/09/motivating_othe.html&#34;&gt;Motivating others&lt;/a&gt;)&lt;/p&gt;

            </content>
        </entry>
    
        <entry>
            <title type="html">Concept: Four layers of web development</title>
            <link href="http://friendlybit.com/css/concept-four-tier-web-development/" rel="alternate" type="text/html" title="Concept: Four layers of web development" />
            <published>2006-06-03T18:45:07+02:00</published>
            <updated>2006-06-03T18:45:07+02:00</updated>
            <id>http://friendlybit.com/css/concept-four-tier-web-development/</id>
            <author>
                <name>Emil Stenström</name>
            </author>
            <summary type="text">When thinking about web development on the client side, I tend to think of four different layers. Any (well built) framework will cater for all of these...</summary>
            <content type="html" xml:base="http://friendlybit.com/css/concept-four-tier-web-development/">
                &lt;p&gt;When thinking about web development on the client side, I tend to think of four different layers. Any (well built) framework will cater for all of these layers and all good developers will be aware of them. The layers I&#39;m thinking about are: Data, Structure, Design, and Behavior. This article discusses all four of those and explains how they relate.&lt;/p&gt;
&lt;h2 id=&#34;data-layer&#34;&gt;Data layer&lt;a href=&#34;#data-layer&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The data layer is the most important one and strangely the one most people get confused about. HTML is &lt;em&gt;not&lt;/em&gt; the data layer, the &lt;strong&gt;content&lt;/strong&gt; is. The data layer is the raw data that you are presenting, the text, the images, the sound, the video, whatever content you want to serve. For bigger sites the data is often stored in a database or perhaps XML files somewhere and then processed server side every time someone wants to access it.&lt;/p&gt;
&lt;p&gt;This layer is also where all websites should start. What content do you have? If the content is bad no pretty design or fancy Web 2.0 technique is going to cater for that. In fact, content together with bad uses of the other layers, &lt;a href=&#34;http://www.andyrutledge.com/bad-design.php&#34;&gt;might still work&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;One last point to make about data is that you should make sure to use the best possible media for representing your content. If it can be text, use text! Don&#39;t use images for text, narrate your podcasts (or at least provide a text-summary), put your videos online with descriptions to them. Having that text there helps you convey your point, search engines will find you, your users will be able to skim read while it loads and disabled users will get access to at least some of your content.&lt;/p&gt;
&lt;h2 id=&#34;structural-layer&#34;&gt;Structural layer&lt;a href=&#34;#structural-layer&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The structural layer is where the much misunderstood HTML comes to play. HTML&#39;s job is to take the data it has received from the data layer and &lt;a href=&#34;/html/datatypes-of-html/&#34; title=&#34;Some examples of data structures you have available in HTML&#34;&gt;add some structure to it&lt;/a&gt;. Mark up what parts are headers, make sure lists get the HTML that best describes them, split the page up in the important parts and so on.&lt;/p&gt;
&lt;p&gt;HTML also adds some semantics to the data but since it&#39;s quite a limited dictionary we have to work with I believe this is secondary. If you happened to have the kind of data that HTML happens to catch with its elements be sure to use them, if not make sure you at least capture the structure of it.&lt;/p&gt;
&lt;p&gt;You know you have done this level right if your site works with nothing but data and structure.&lt;/p&gt;
&lt;h2 id=&#34;design-layer&#34;&gt;Design layer&lt;a href=&#34;#design-layer&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The design layer is where you define the looks of your data. Design requires a good basic structure to be useful. On the web you should use CSS for this layer, a language that has been built upon the idea of a solid structure and is remarkably powerful. As you know CSS targets certain elements and then defines their look. Without a solid structure this is not possible.&lt;/p&gt;
&lt;p&gt;Good designers often point out that only working with the looks of a site will not accomplish good design. They also work on the structural layer by making sure structurally important content gets the most exposure in the design. This is also strengthens the idea that structure is a layer upon which design works.&lt;/p&gt;
&lt;h2 id=&#34;behavioral-layer&#34;&gt;Behavioral layer&lt;a href=&#34;#behavioral-layer&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Behavior is the last layer I&#39;m going to talk about. It&#39;s the one that&#39;s least important; data, structure and design are all more effective in conveying your message. None the less, added behavioral functionality &lt;em&gt;can&lt;/em&gt; be powerful if executed properly on top of the other layers.&lt;/p&gt;
&lt;p&gt;Javascript is the most used language for adding new behavior to websites. With the whole &lt;a href=&#34;http://en.wikipedia.org/wiki/Web_2.0&#34;&gt;Web 2.0&lt;/a&gt; and &lt;a href=&#34;http://en.wikipedia.org/wiki/Ajax_%28programming%29&#34;&gt;AJAX&lt;/a&gt; wave we are experiencing many new sites that adds a behavioral layer without even thinking about it. We should be careful; becoming dependent on the new behavior (the site not working without it) means you will lose many potential visitors, the most important single one being search engines. Behavior should always be added separately and only enhance the experience for those that has it enabled. This is what&#39;s called unobtrusive javascript.&lt;/p&gt;
&lt;h2 id=&#34;putting-it-all-together-four-tier-web-development&#34;&gt;Putting it all together: four tier web development&lt;a href=&#34;#putting-it-all-together-four-tier-web-development&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Putting all these four parts together we get the following:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/files/four-tier-webdev.png&#34; alt=&#34;Adding layers step by step to a paragraph of text&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Is this the same mental model you use? Let me know through comments.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Threehouse has an image up showing the four layers in the context of javascript connection the layers together.&lt;/p&gt;

            </content>
        </entry>
    
        <entry>
            <title type="html">Challenge: What’s the worst you can do?</title>
            <link href="http://friendlybit.com/css/challange-whats-the-worst-you-can-do/" rel="alternate" type="text/html" title="Challenge: What’s the worst you can do?" />
            <published>2006-03-11T16:09:26+01:00</published>
            <updated>2006-03-11T16:09:26+01:00</updated>
            <id>http://friendlybit.com/css/challange-whats-the-worst-you-can-do/</id>
            <author>
                <name>Emil Stenström</name>
            </author>
            <summary type="text">After reading through the comments on my levels of CSS article I find that I few people seem to think that the article is a way to ridicule beginners. It&#39;s...</summary>
            <content type="html" xml:base="http://friendlybit.com/css/challange-whats-the-worst-you-can-do/">
                &lt;p&gt;After reading through the comments on my &lt;a href=&#34;/css/levels-of-css-knowledge/&#34;&gt;levels of CSS&lt;/a&gt; article I find that I few people seem to think that the article is a way to ridicule beginners. It&#39;s not. It&#39;s a way to document the steps that I think I have climbed. Some people also thought that this set of levels is a good indicator of how good sites you will make. That&#39;s also false. Being Level 5 or 6 in the list means that you are a good &lt;em&gt;coder&lt;/em&gt;, nothing else. It does not mean that a site you make is any good, I&#39;ve seen many sites that have great code but that still makes me want to kill someone. Don&#39;t confuse good web developers with good coders. &amp;quot;Don&#39;t be a &lt;a href=&#34;http://www.molly.com/2006/02/23/how-to-sniff-out-a-rotten-standardista/&#34;&gt;rotten standardista&lt;/a&gt;&amp;quot; as Molly Holzschlag would put it.&lt;/p&gt;
&lt;h2 id=&#34;the-challenge&#34;&gt;The challenge&lt;a href=&#34;#the-challenge&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To give you a perspective of how bad it really could be I&#39;m challenging all the readers of Friendly Bit. It&#39;s kind of a competition (with no prize) about who can make the worst site. The rules are simple; you are to construct a page, using HTML and CSS (and Javascript if you think you need it) that has a design that is as hideous as possible. I want pages that make my eyes bleed, that make small children cry and makes &lt;a href=&#34;http://maddox.xmission.com/&#34;&gt;Maddox&lt;/a&gt; write hate articles about you. Think of all the good things you&#39;ve learnt and do the opposite.&lt;/p&gt;
&lt;h2 id=&#34;inspiration-for-a-truly-hideous-design&#34;&gt;Inspiration for a truly hideous design&lt;a href=&#34;#inspiration-for-a-truly-hideous-design&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I won&#39;t be giving out any prize but what I can do is help you with some ideas of bad code.&lt;/p&gt;
&lt;p&gt;Make use of the &lt;code&gt;&amp;lt;marquee&amp;gt;&lt;/code&gt; tag. It makes any content inside it scroll in the speed and direction you choose. Did you know that you can wrap &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; in a marquee tag? That&#39;s right, your entire page will move automatically. You can also nest several marquee tags inside each other. Ohh yeah!&lt;/p&gt;
&lt;p&gt;Another good tag you can use is the &lt;code&gt;&amp;lt;blink&amp;gt;&lt;/code&gt; tag. Can it be applied to, say, a table? I hear you ask. But of course. You can have a full screen blinking table on your company homepage.&lt;/p&gt;
&lt;p&gt;Continuing with the good ideas we have the oldschool &lt;em&gt;frames&lt;/em&gt; we all have come to like. Did you know that there are no set upper limit on the number of frames you can load? You can have thousands of them! You can even mark up a whole tabular grid with frames alone.&lt;/p&gt;
&lt;p&gt;This challange is about &lt;em&gt;terrible code&lt;/em&gt; as much as it&#39;s about terrible design. So don&#39;t go with well-formed or the basic foundations of HTML. Did you even try putting tags inside other tags? &lt;code&gt;&amp;lt;font &amp;lt;font size=&amp;quot;2&amp;quot;&amp;gt; size=&amp;quot;3&amp;quot;&amp;gt;&lt;/code&gt; is quite fantastic don&#39;t you think? Make your page upside down by adding the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; below the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt;, but only after you have added your own &lt;code&gt;&amp;lt;neck&amp;gt;&lt;/code&gt; tag to the mix. Surprise me!&lt;/p&gt;
&lt;h2 id=&#34;how-to-accept-the-challenge&#34;&gt;How to accept the challenge&lt;a href=&#34;#how-to-accept-the-challenge&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To join all of this you just have to make the page, put it up on your server and link to it here. Post a link as a comment or simply trackback (link to this post) from your own blog and it will show up here.&lt;/p&gt;
&lt;p&gt;Finally: Don&#39;t forget the lesson behind all this. When you see a site with bad code, know that there&#39;s a lot of much worse sites out there.&lt;/p&gt;

            </content>
        </entry>
    
        <entry>
            <title type="html">Extra fluid layouts with javascript</title>
            <link href="http://friendlybit.com/css/extra-fluid-layouts-with-javascript/" rel="alternate" type="text/html" title="Extra fluid layouts with javascript" />
            <published>2006-02-13T01:00:31+01:00</published>
            <updated>2006-02-13T01:00:31+01:00</updated>
            <id>http://friendlybit.com/css/extra-fluid-layouts-with-javascript/</id>
            <author>
                <name>Emil Stenström</name>
            </author>
            <summary type="text">I&#39;m a big fan of vector graphics. Because of that I love Macromedia Fireworks and the way it handles all elements like vectors. The good thing about that is...</summary>
            <content type="html" xml:base="http://friendlybit.com/css/extra-fluid-layouts-with-javascript/">
                &lt;p&gt;I&#39;m a big fan of vector graphics. Because of that I love Macromedia Fireworks and the way it handles all elements like vectors. The good thing about that is that they can be resized and zoomed without them losing their sharpness.&lt;/p&gt;
&lt;p&gt;This got me thinking about how to add some vectorization to CSS layouts. My idea was that you should let the width of the screen decide the font-size of, for example, your headers. This could make for nice fluid layouts and might even add to usability in some cases. There are probably other uses for this but I leave that to you, please use the comments if you come up with something.&lt;/p&gt;
&lt;p&gt;Start by having a look at the &lt;a href=&#34;/files/window_fontsize/&#34; data-no-instant&gt;dynamic font-size example&lt;/a&gt; just so we&#39;re talking about the same thing. Try resizing the window and reloading and see that the headers really do adapt to the width of the browser window.&lt;/p&gt;
&lt;h2 id=&#34;how-its-done&#34;&gt;How it&#39;s done&lt;a href=&#34;#how-its-done&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;First we need a way to meassure the width of the text in the default font. For this I use my own little getTextWidth() that were constructed in my &lt;a href=&#34;/css/line-breaking-with-javascript/&#34;&gt;line-break script&lt;/a&gt;. It simply takes a piece of text, attaches it to the page, meassures it&#39;s width and removes it again.&lt;/p&gt;
&lt;div class=&#34;highlight&#34; data-language=&#34;JS&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getTextWidth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ea&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;createElement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;span&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ea&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;innerHTML&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;body&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;appendChild&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ea&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ea&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;offsetWidth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;body&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;removeChild&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ea&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ok, now we know the width of some text in it&#39;s non formated state. Next up is to scale it as much as needed.&lt;/p&gt;
&lt;div class=&#34;highlight&#34; data-language=&#34;JS&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;scaleUp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;elem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;targetWidth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;blockWidth&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getTextWidth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;elem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;innerHTML&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;defaultSize&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;parseInt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;elem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;style&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fontSize&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;100%&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;newSize&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;Math&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;floor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.9&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;targetWidth&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;blockWidth&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;defaultSize&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;elem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;style&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fontSize&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;newSize&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;%&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you see scaleUp() determines a percentage by looking at three things: it&#39;s unformated width, it&#39;s current width and the target width. Font-size and text width does not seem to follow eachother perfectly so an additional multiplication by 0.9 is needed.&lt;/p&gt;
&lt;p&gt;This handy little function is then called with the element you want to scale and the width in pixels of how wide you want it. The calls look something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34; data-language=&#34;JS&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;element&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getElementsByTagName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;h1&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)[&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;body&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;offsetWidth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;nx&#34;&gt;scaleUp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;element&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That&#39;s it, hope you find some fun use for it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; After doing some research I see that Eric Meyer is already using something like this in his &lt;a href=&#34;http://www.meyerweb.com/eric/tools/s5/&#34;&gt;slideshow system S5&lt;/a&gt;. Well well, it was a funny exercise none the less.&lt;/p&gt;

            </content>
        </entry>
    
        <entry>
            <title type="html">Line Breaking With Javascript</title>
            <link href="http://friendlybit.com/js/line-breaking-with-javascript/" rel="alternate" type="text/html" title="Line Breaking With Javascript" />
            <published>2006-01-22T00:00:00+01:00</published>
            <updated>2006-01-22T00:00:00+01:00</updated>
            <id>http://friendlybit.com/js/line-breaking-with-javascript/</id>
            <author>
                <name>Emil Stenström</name>
            </author>
            <summary type="text">Over the years there have been numerous suggestions of different ways of doing line breaks on the web. Browser incompatibilities, lack of support for...</summary>
            <content type="html" xml:base="http://friendlybit.com/js/line-breaking-with-javascript/">
                &lt;p&gt;Over the years there have been numerous suggestions of different ways of doing line breaks on the web. Browser incompatibilities, lack of support for standardized features, and the creation of browser specific features all helps in making it incredibly difficult. Searching and reading for a while quickly brought me to think the best current solution is &lt;a href=&#34;http://www.quirksmode.org/blog/archives/2005/06/quirks_mode_and_1.html&#34;&gt;quirksmode&#39;s wbr&lt;/a&gt;. It seems quite well supported but has two major flaws:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;wbr&amp;gt;&lt;/code&gt; is not valid HTML&lt;/li&gt;
&lt;li&gt;The suggested solution does not work in Safari&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So off I went to find a better one. I started trying some different combinations of spaces marked up with &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; tags and I tried some nifty CSS tricks before it hit me - this should be done with javascript. Javascript has wide browser support and after some research (and help from the people in EFNet #javascript) I actually got a &lt;a href=&#34;/files/js-linebreak/&#34; data-no-instant&gt;working example&lt;/a&gt; up. I have been able to test it in FF 1.5/Win, IE 5.5/Win, IE 6/Win, Opera 8.51/Win+Mac, and Safari 2.0.3/Mac and everything seems to work fine in all of them.&lt;/p&gt;
&lt;h2 id=&#34;how-it-works&#34;&gt;How it works&lt;a href=&#34;#how-it-works&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The idea here is to add ordinary &lt;code&gt;&amp;lt;br&amp;gt;&lt;/code&gt;s and using javascript to measure the length of the text. The user gives a piece of text and a width in pixels and the script returns the text with breaks inserted.&lt;/p&gt;
&lt;p&gt;The hard part is to find at which letter we should break. My first idea was to just loop over the text and keep track of the width in pixels. When we get over the given width, back one step and add a break at that position. But this will be slow for small font-sizes and wide columns so let&#39;s do something faster. Instead of looping through all letters we can use &lt;a href=&#34;http://en.wikipedia.org/wiki/Binary_search&#34;&gt;Binary Search&lt;/a&gt; (check the link if you&#39;re not familiar with it, it&#39;s good to know). This makes for a lot less calls.&lt;/p&gt;
&lt;p&gt;We need a small change to the algorithm since we won&#39;t be able to find the exact width we&#39;re looking for (a letter is wider than 1px). Instead we break when we&#39;re down to knowing that it&#39;s between two letters. We then return the first letter&#39;s position. Here is code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34; data-language=&#34;JS&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;binSearch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;searchLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;left&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;right&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;length&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;breakPos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;left&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;lastBreakPos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;right&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;Math&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;abs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;lastBreakPos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;breakPos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;lastBreakPos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;breakPos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;breakPos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;Math&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;floor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;left&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;right&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;searchLen&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getTextWidth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;substring&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;breakPos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;right&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;breakPos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;left&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;breakPos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;Math&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;min&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;breakPos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;lastBreakPos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The code above uses &lt;code&gt;getTextWidth()&lt;/code&gt; to get the width of a piece of text. &lt;code&gt;getTextWidth()&lt;/code&gt; makes use of the &lt;code&gt;offsetWidth&lt;/code&gt; property to get the width of a piece of text. Problem is that only elements that are rendered have the property set. This means we need to add it to the page, measure it, and then remove it. This code does just that:&lt;/p&gt;
&lt;div class=&#34;highlight&#34; data-language=&#34;JS&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getTextWidth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ea&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;createElement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;span&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ea&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;innerHTML&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;body&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;appendChild&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ea&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ea&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;offsetWidth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;body&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;removeChild&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ea&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Good. We now have two nice helper functions to handle all the hard work. Now we only need some code to actually split the text and add the breaks. We do this by using &lt;code&gt;binSearch()&lt;/code&gt; to fetch where the next break should be. &lt;code&gt;binSearch()&lt;/code&gt; returns an index and we split the line and add the first part (including a break) to a buffer. We then repeat the same procedure on the last part of the string. We keep splitting until &lt;code&gt;getTextWidth()&lt;/code&gt; tells us we&#39;re done.&lt;/p&gt;
&lt;div class=&#34;highlight&#34; data-language=&#34;JS&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;linebreak&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;maxLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;breakPos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;part1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;part2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getTextWidth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;part1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;maxLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getTextWidth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;part1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;maxLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;breakPos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;binSearch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;part1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;maxLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;part2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;part1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;substring&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;breakPos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;part1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;length&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;part1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;part1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;substring&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;breakPos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;part1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;part1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;part2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;part2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It&#39;s now time to use the function we have. The first line selects what elements we want to wrap. You can replace this with a loop if you want if you need to go over all the paragraphs in your document. The second line just fetches everything inside the paragraph and sends it to &lt;code&gt;linebreak()&lt;/code&gt; for wrapping. The two lines are then made to trigger when the document is ready loading.&lt;/p&gt;
&lt;div class=&#34;highlight&#34; data-language=&#34;JS&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;window&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;onload&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getElementsByTagName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;p&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)[&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;innerHTML&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;linebreak&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;innerHTML&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;200&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A &lt;a href=&#34;/files/js-linebreak/&#34; data-no-instant&gt;working example&lt;/a&gt; is available that shows what it can do. So, what do you think? Could this be the best solution so far to handling line breaks?&lt;/p&gt;

            </content>
        </entry>
    
        <entry>
            <title type="html">Make a tooltip out of some columns in a table</title>
            <link href="http://friendlybit.com/css/make-a-tooltip-out-of-some-columns-in-a-table/" rel="alternate" type="text/html" title="Make a tooltip out of some columns in a table" />
            <published>2006-01-06T01:16:59+01:00</published>
            <updated>2006-01-06T01:16:59+01:00</updated>
            <id>http://friendlybit.com/css/make-a-tooltip-out-of-some-columns-in-a-table/</id>
            <author>
                <name>Emil Stenström</name>
            </author>
            <summary type="text">A worried user joins the #CSS channel on EFNet. He has a big problem with the site he&#39;s currently working on and wonders if there might be a problem with...</summary>
            <content type="html" xml:base="http://friendlybit.com/css/make-a-tooltip-out-of-some-columns-in-a-table/">
                &lt;p&gt;A worried user joins the #CSS channel on EFNet. He has a big problem with the site he&#39;s currently working on and wonders if there might be a problem with his markup. Let&#39;s see what he wants.&lt;/p&gt;
&lt;p&gt;The site sells some kind of houses and each house has a few &amp;quot;options&amp;quot; (let&#39;s pretend a bigger door is one option) that the user should be able to select among. Each of these options has a name and costs a certain amount of money. When you move your mouse over one of the options, he wants more info to pop up in a small box. In the box there should be an image, a store name and strange number. What HTML should he use to mark that up?&lt;/p&gt;
&lt;p&gt;We talked for a while and thought about definition lists containing a div with the extra info in, perhaps a two-column table with a div in the second column? After looking again it became pretty clear, if we just look at his data and not think about the design, all that was left was one big table. Everything that he wants in the tooltip are things that could as well be shown in a big table. So why not use exactly that markup and then use javascript to make some cells only pop up when the row was hovered?&lt;/p&gt;
&lt;p&gt;This is the markup I propose:&lt;/p&gt;
&lt;div class=&#34;highlight&#34; data-language=&#34;HTML&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;table&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Options for your house&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;thead&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;th&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;Option&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;th&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;th&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;Price&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;th&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;th&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;tooltip&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;Image&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;th&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;th&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;tooltip&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;Store&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;th&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;th&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;tooltip&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;SKU#&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;th&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;thead&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tbody&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;td&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;Bush&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;td&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;td&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;$3&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;td&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;td&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;tooltip a1&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;img&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;/files/post-media/bush.jpg&amp;quot;&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;alt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;An alabama bush&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;td&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;td&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;tooltip a2&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;Alabama&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;td&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;td&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;tooltip a3&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;#23535151&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;td&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;td&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;Bush&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;td&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;td&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;$3&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;td&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;td&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;tooltip a1&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;img&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;/files/post-media/bush.jpg&amp;quot;&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;alt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;An alabama bush&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;td&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;td&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;tooltip a2&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;Alabama&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;td&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;td&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;tooltip a3&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;#23535151&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;td&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tbody&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;table&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What you see there is a plain five column table with some classes spread out to make it easier to fetch what we want with the javascript later on. The whole table is given the id &amp;quot;info&amp;quot;, this makes us able to separate it from other tables on the same page. Each cell that are going to be in the tooltip get the class &amp;quot;tooltip&amp;quot; and an aditional a1-a3 class that simply is used to position the specific cell later on.&lt;/p&gt;
&lt;p&gt;Next we need to do two of things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Loop over the table and hide everything with the class &amp;quot;tooltip&amp;quot;&lt;/li&gt;
&lt;li&gt;Loop over all table rows and add a mouseover function to each of them that makes them show all hidden cells in that particular row&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To fetch all elements that has a certain className we will use Jonathan Snook&#39;s fabulous getElementsByClassName. It takes two arguments, the element whose children it should loop through and the className it should look for. The function looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34; data-language=&#34;JS&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getElementsByClassName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;classname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[];&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;re&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;ow&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;RegExp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;\\b&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;classname&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;\\b&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;els&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getElementsByTagName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;*&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;j&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;els&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;length&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ij&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;re&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;test&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;els&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;className&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;push&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;els&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next we need to write the code that fulfils the list we wrote previously:&lt;/p&gt;
&lt;div class=&#34;highlight&#34; data-language=&#34;JS&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Hide all classes with the className &amp;quot;tooltip&amp;quot;&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;tooltips&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getElementsByClassName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getElementsByTagName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;body&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)[&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;tooltip&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;tooltips&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;length&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;tooltips&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;className&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot; hide&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;tbodies&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getElementsByTagName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;tbody&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;tbodies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;length&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;trows&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;tbodies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getElementsByTagName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;tr&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Add a function to each tr that makes it show it&amp;#39;s cells on mouseover&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;j&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;j&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;trows&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;length&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;j&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;trows&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;j&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;onmouseover&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;childtooltips&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getElementsByClassName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;tooltip&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;k&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;k&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;childtooltips&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;length&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;k&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;childtooltips&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;k&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;className&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot; hooover&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// And hides all child cells on mouseout&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;trows&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;j&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;onmouseout&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;childtooltips&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getElementsByClassName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;tooltip&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;k&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;k&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;childtooltips&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;length&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;k&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;childtooltips&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;k&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;className&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;               &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;childtooltips&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;k&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;className&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;replace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ow&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;RegExp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot; hooover\\b&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A note here is that we don&#39;t loop over the first table row. That one contains the table headers and shouldn&#39;t react to us hovering it.&lt;/p&gt;
&lt;p&gt;Last but not least we need a few lines of CSS to make the page behave like we want it to. Without either Javascript or CSS enabled a plain table should be shown with all cells visible. If you have both enabled you don&#39;t want the cells that contain the tooltip to take up space in the table. Here&#39;s the code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34; data-language=&#34;CSS&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;hide&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;left&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;-10000&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;px&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;absolute&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;hooover&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;left&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;80&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;px&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;tr&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;relative&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;a1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;border&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;px&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;solid&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Black&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;300&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;px&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;a2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;padding&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;px&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;120&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;px&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;a3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;padding&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;px&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;px&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &amp;quot;hide&amp;quot; class is added to any element with the class &amp;quot;tooltip&amp;quot;. Why not make the tooltip class hide the cells right away you ask? The answer is that then a non js user would not see those cells at all. This way we get the best of both worlds. To remove the hidden cells from taking up space we remove them from the flow with &lt;code&gt;position: absolute;&lt;/code&gt; and to hide them we use &lt;code&gt;left: -10000px&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &amp;quot;hooover&amp;quot; class get enabled when we mouseover one of the table rows. It just sets the left value to a far more visible 100px. Lastly we set some styles on the a1-a3 classes that makes the tooltip look a little better. We use a1 as a background and place the other two classes on top of it to make it look like they are in the same box.&lt;/p&gt;
&lt;p&gt;And that&#39;s it, a &lt;a href=&#34;/files/table-tooltip/&#34; data-no-instant&gt;table turned into a tooltip&lt;/a&gt;, another user is a little bit happier and all would be fine... Unless of course the user had left the channel before I could show him my solution. Damn.&lt;/p&gt;

            </content>
        </entry>
    
</feed>