<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[No Rest For The Weekend]]></title>
  <link href="http://blog.norestfortheweekend.com/atom.xml" rel="self"/>
  <link href="http://blog.norestfortheweekend.com/"/>
  <updated>2013-08-18T17:34:36+01:00</updated>
  <id>http://blog.norestfortheweekend.com/</id>
  <author>
    <name><![CDATA[Mark Stickley]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Using git to deploy your site]]></title>
    <link href="http://blog.norestfortheweekend.com/blog/2013/08/18/using-git-to-deploy-your-site/"/>
    <updated>2013-08-18T15:30:00+01:00</updated>
    <id>http://blog.norestfortheweekend.com/blog/2013/08/18/using-git-to-deploy-your-site</id>
    <content type="html"><![CDATA[<p>If you’re using git for your source control but still using FTP to publish updates to your website, you’re <em>doing it wrong</em>!</p>

<h2 id="tl-dr">TL; DR</h2>

<p>You can set up git so that you can use a single command to deploy your code to live. This post takes you through the typical steps to set this up.</p>

<h2 id="about-git">About git</h2>

<p>Git is a distributed version control system. It’s the “distributed” part that makes it useful in this situation. Git allows you to specify multiple remote repositories at addressable locations that it can sync with. To be able to use git to deploy your site, one of those remote repositories must be on the live server.</p>

<h2 id="some-assumptions">Some assumptions</h2>

<p>In order for this to work, you will need:</p>

<ul>
  <li>Code for a website under version control in git</li>
  <li>An addressable web server to which you want to deploy the website</li>
  <li>SSH access to the web server</li>
  <li>Git available on the web server</li>
</ul>

<p>I’ll go through some other steps that require you to be working on a *nix computer, but they are not essential and are really for convenience. You should be able to do this from a Windows machine without a problem.</p>

<h2 id="making-life-easier">Making life easier</h2>

<p><em>This section is optional, but it reduces hassle and increases security so why not?</em></p>

<p><strong><a href="https://kb.mediatemple.net/questions/1625/Using+an+SSH+Config+File">Use an SSH config file</a>.</strong> You can set up aliases, default parameters and security options in <code>~/.ssh/config</code>. It’s a real time saver - it basically means you don’t have to provide all the options and switches every time you sign in via SSH to your server. My host provides a jailed shell on port 2222 and for security I like to use a public key for authentication so my config file looks a little like this:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
</pre></td><td class="code"><pre><code class=""><span class="line">Host mydomain.com
</span><span class="line">  Port 2222
</span><span class="line">  PreferredAuthentications publickey</span></code></pre></td></tr></table></div></figure></notextile></div>

<p><strong>Set up public key authentication.</strong> This increases security on your server by not allowing password access and by installing a certificate on your local computer means you never have to manually authenticate either (unless you choose to password protect your certificate). I won’t go through it here but if you’re interested you can <a href="http://stackoverflow.com/a/9095">learn how to do it</a>.</p>

<h2 id="server-side">Server-side</h2>

<p>Sign in via SSH to your server. You’ll start in your home directory.</p>

<p>Create a folder and initialise a new git repo inside it. You can call it what you like; I gave mine the same name as the domain. </p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
</pre></td><td class="code"><pre><code class="bash"><span class="line"><span class="nv">$ </span>mkdir mydomain.com
</span><span class="line"><span class="nv">$ </span><span class="nb">cd </span>mydomain.com/
</span><span class="line"><span class="nv">$ </span>git init
</span><span class="line">Initialized empty Git repository in /home/username/mydomain.com/
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>A git repository and the filesystem containing the checked-out files from that repository are two different things in different locations on disk. When you push from your computer to a remote repository you will only alter what’s in the remote repository; the checked out files on the server remain unchanged. This is a problem since you need the checked-out files to be updated as well so they can be read by the web server software and served to people visiting your site. This is where <strong>git hooks</strong> come in handy.</p>

<p>Git hooks are scripts that are automatically run when certain events occur in git. In this case we want a script that checks out the latest version to run after the repo receives an update. The hook’s name is <code>post-receive</code>.</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
</pre></td><td class="code"><pre><code class="bash"><span class="line"><span class="nv">$ </span><span class="nb">cd</span> .git/hooks/
</span><span class="line"><span class="nv">$ </span>vim post-receive
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p><code>post-receive</code> does not exist by default and so vim should open with a blank file. For the benefit of those not fluent in vim-ese I’ll give blow by blow instructions.</p>

<ul>
  <li>Type ‘i’ to enter Insert Mode</li>
  <li>Paste in the following code:</li>
</ul>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
</pre></td><td class="code"><pre><code class="bash"><span class="line"><span class="c">#!/bin/sh</span>
</span><span class="line"><span class="nv">GIT_WORK_TREE</span><span class="o">=</span>../ git checkout -f
</span></code></pre></td></tr></table></div></figure></notextile></div>

<ul>
  <li>Press Escape to exit Insert Mode</li>
  <li>Type ‘:’ followed by ‘w’, ‘q’, and Enter, which should (w)rite the file and (q)uit.</li>
</ul>

<p>The script we just created simply performs a <em>forced checkout</em> which makes sure the state of the checked-out files match the latest version of the repository (i.e. The version just received).</p>

<p>Now it needs to be made executable:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
</pre></td><td class="code"><pre><code class="bash"><span class="line"><span class="nv">$ </span>chmod a+x post-receive
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>Finally, we need to configure the repository to accept incoming updates without complaining. By default it’s set up to grumble because without the git hook we just set up, the working tree (checked-out files) and the repository would be out of sync. With the git hook in place this becomes a non-issue.</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
</pre></td><td class="code"><pre><code class="bash"><span class="line"><span class="nv">$ </span>git config receive.denyCurrentBranch ignore
</span></code></pre></td></tr></table></div></figure></notextile></div>

<h2 id="connecting-the-dots">Connecting the dots</h2>

<p>Now the server is ready to receive updates we need to tell the local repository about it.</p>

<p>On your local computer:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
</pre></td><td class="code"><pre><code class="bash"><span class="line"><span class="nv">$ </span>git remote add live username@mydomain.com:mydomain.com
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>This sets up the repository you just set up on your server as a ‘remote’. You can now refer to that repository as <code>live</code>.</p>

<h2 id="doing-it-live">Doing it live</h2>

<p>All that remains now is to push your site live. From your local computer:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
</pre></td><td class="code"><pre><code class="bash"><span class="line"><span class="nv">$ </span>git push live master
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>That’s it. Whenever you want to publish, from now on that’s all you need to type.</p>

<h2 id="one-more-thing">One more thing</h2>

<p>You may notice that your site isn’t showing up just yet. Log back on to your server. You can see, if you check, in the <code>mydomain.com</code> folder your latest changes are there, but we need to alter the folder that currently contains your website to point to the <code>mydomain.com</code> folder instead.</p>

<p>There will be a folder in your home directory called <code>htdocs</code>, <code>www</code> or <code>public_html</code> containing all the files that currently form your website. I’ll assume it’s called <code>public_html</code>. Make sure there’s nothing in that folder that you haven’t got backed up or that you want to keep - it’s about to be deleted!</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
</pre></td><td class="code"><pre><code class="bash"><span class="line"><span class="nv">$ </span>rm -rf public_html/
</span><span class="line"><span class="nv">$ </span>ln -s mydomain.com public_html
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>This creates a symbolic link from <code>public_html</code> to your repository. Reload the page in your browser and you should see the version you just pushed from git.</p>

<p>Make a small change and try <code>git push live master</code> again. As soon as it has finished you should see the change on your site. Deployments, no matter how large or small, will never be a hassle again.</p>

<h2 id="a-note-on-security">A note on security</h2>

<p>If you navigate to http://mydomain.com/.git you may notice that the contents of your git repository are available for the world to see. Some reasons why you might not want this:</p>

<ul>
  <li>Your email address is probably associated with all your commits</li>
  <li>Anyone could download your repository and all of its history</li>
  <li>Your code will be public and it would be easier to find security holes in it</li>
</ul>

<p>I get around this by having all the code to be served in a subfolder of the repository, <code>htdocs</code>, and link to that instead of the main repository folder. Alternatively you could use <code>.htaccess</code> (if you’re running Apache) to block access. Just copy these lines into your <code>.htaccess</code> file:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
</pre></td><td class="code"><pre><code class="apache"><span class="line"><span class="nb">RewriteEngine</span> <span class="k">On</span>
</span><span class="line"><span class="nb">RewriteRule</span> ^(.*/)?\.git+ - [F,L]
</span></code></pre></td></tr></table></div></figure></notextile></div>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[In Defence Of The BBC And Its Clock]]></title>
    <link href="http://blog.norestfortheweekend.com/blog/2013/06/06/in-defence-of-the-bbc-and-its-clock/"/>
    <updated>2013-06-06T23:00:00+01:00</updated>
    <id>http://blog.norestfortheweekend.com/blog/2013/06/06/in-defence-of-the-bbc-and-its-clock</id>
    <content type="html"><![CDATA[<p>The <abbr title="British Broadcasting Corporation">BBC</abbr> has said that due to a single person complaining, <a href="http://www.bbc.co.uk/news/entertainment-arts-22768861">they will be removing the clock from the home page</a>. The news has been reported fairly widely, particularly through technology channels, and people have been very vocal about their feelings on one particular point:</p>

<ul>
  <li>How could it possibly take 100 days to fix the problem?</li>
</ul>

<p>Having worked for the <abbr title="British Broadcasting Corporation">BBC</abbr> for 4 years I would agree on that estimate, and I’ll explain why. First, I need to explain a little about the <abbr title="British Broadcasting Corporation">BBC</abbr> some of the history surrounding the clock.</p>

<h2 id="history">History</h2>

<p><img class="center" src="http://blog.norestfortheweekend.com/images/posts/2013/06/06/in-defence-of-the-bbc-and-its-clock/clocks.jpg" width="790" height="592" title="'The BBC clock through the ages'" /></p>

<p>The <a href="https://www.google.co.uk/search?q=bbc+clock&amp;tbm=isch"><abbr title="British Broadcasting Corporation">BBC</abbr> clock</a> has been around for a long time. It has had many incarnations and is an integral part of the <abbr title="British Broadcasting Corporation">BBC</abbr>’s history. It first appeared on BBC1 as an actual clock with a camera pointing at it, and then digital representations in the same style appeared. During a major redesign of the <abbr title="British Broadcasting Corporation">BBC</abbr> home page it was lovingly recreated in Flash as an homage to this iconic timepiece.</p>

<p>A subsequent redesign removed the clock from the home page but due to an outcry from regular visitors to the site it was reinstated, and rewritten to use the modern <code>canvas</code> <abbr title="Hypertext Markup Language">HTML</abbr> element with Flash as a fallback to give the best available experience.</p>

<h2 id="the-trust">The Trust</h2>

<p>The <a href="http://www.bbc.co.uk/bbctrust/"><abbr title="British Broadcasting Corporation">BBC</abbr> Trust</a> is an independent body who governs the <abbr title="British Broadcasting Corporation">BBC</abbr> and is intended to act in the best interests of the licence fee payers (for the benefit of international readers, everyone in the UK who owns a TV must pay a yearly fee which mainly funds the output of the <abbr title="British Broadcasting Corporation">BBC</abbr> which is broadcast ad-free). This basically means that the Trust have final say in matters such as this. A single complaint such as this can out-weigh the opinions of many if the Trust feel that the <abbr title="British Broadcasting Corporation">BBC</abbr> is not upholding its core values.</p>

<p>One of the core values of the <abbr title="British Broadcasting Corporation">BBC</abbr> is to never knowingly broadcast inaccurate information. As the clock is on the <abbr title="British Broadcasting Corporation">BBC</abbr> home page, it looks like that information comes from the <abbr title="British Broadcasting Corporation">BBC</abbr>, and therefore should be accurate. As the time displayed actually comes from the user’s computer it has the potential to be inaccurate and therefore make the <abbr title="British Broadcasting Corporation">BBC</abbr> home page inaccurate, and that is unacceptable.</p>

<h2 id="breaking-down-the-problem">Breaking down the problem</h2>

<p>As the clock has been criticised for its accuracy, a fix that makes it anything less than perfect for every single user would be unacceptable. Here are the facts:</p>

<ol>
  <li>As already established, you can’t trust the user’s clock.</li>
  <li>The site is not restricted to people within a single time zone, the clock will have to display the correct time according to the time zone the user is in.</li>
  <li>As we can’t trust any time information on the user’s computer(1), we can’t rely on their computer to provide a time zone automatically.</li>
  <li>Getting a user’s location by IP address is never 100% accurate, particularly when using mobile broadband so we can’t use that.</li>
  <li>This leaves us with only one option (since we can’t rely on every device having GPS built in) - the user must manually provide their time zone, which can be stored in a cookie or a similar client-side storage mechanism.</li>
  <li>To make the clock accurate if they move time zones, or if they have not yet provided a time zone, the time zone must be displayed along side the clock.</li>
</ol>

<p>Now that the facts are clearer the problem can be broken down.</p>

<p><strong>User Experience &amp; Design</strong>:</p>

<ul>
  <li>How should the time zone be displayed next to the clock?</li>
  <li>How does the user know they can change it?</li>
  <li>How does the interaction to change the time zone work / look?</li>
  <li>Does this all fit within the <abbr title="British Broadcasting Corporation">BBC</abbr>’s <abbr title="User Experience">UX</abbr> guidelines?</li>
</ul>

<p>These are all decisions that will need consideration and questions that will need answering before at least some of the development starts. Design documents will be created in order to accurately pass on the outcome of these decisions to the developers.</p>

<p><abbr title="User Experience &amp; Design">UX&D</abbr> will also perform some user testing to make sure the solution is easy to use and understandable. There may also be accessibility testing to ensure disabled users can still get the most out of the site possible including use of the clock.</p>

<p><strong>Development</strong>:</p>

<ul>
  <li>How do we build this so that the home page retains its current high level of cachability which is necessary for the load the <abbr title="British Broadcasting Corporation">BBC</abbr> experiences?</li>
  <li>How do we deliver the time accurately to the end-user?</li>
  <li>How do we minimise load and rendering times on the home page?</li>
</ul>

<p>When you have a site with as much traffic as the <abbr title="British Broadcasting Corporation">BBC</abbr> there is a strong need for a good caching strategy to avoid overloading the servers and mitigating downtime. When it comes to delivering the time, one option would be to embed it in the body of the page, but this would mean that the cache would have to be regenerated every second which is an inefficient solution. There is the possibility of using post-cache/edge includes to insert the time with placeholders but this would be on every request and even more inefficient.</p>

<p>Logically then, you would need a separate <abbr title="Asynchronous Javascript And XML">AJAX</abbr> call to get the current time. This could result in a short period of time when the clock displayed no time at all before the time had loaded which would look bad. This would have to be referred back to <abbr title="User Experience &amp; Design">UX&D</abbr> for approval.</p>

<p>To serve the accurate time the <abbr title="British Broadcasting Corporation">BBC</abbr> would need to set up one or more time servers capable of handling the constant load of every single person who visited the home page. Not only would the servers need to maintain perfectly accurate time but they would need to deliver it to the user in a fraction of a second wherever they were in the world.</p>

<p>Because any request that took longer than 1 second would make the clock inaccurate there would have to be a series of servers at various locations around the world capable between them of delivering a latency lower than 1 second to any country. This would take some setting up, particularly if you want to defend against <abbr title="Distributed Denial of Service">DDoS</abbr> attacks.</p>

<h2 id="days">100 days?</h2>

<p>Given the complexity of the task, the number of different teams &amp; discipines involved, the infrastucture and the attention to detail required, perhaps 100 days doesn’t seem that mad after all. I don’t think so.</p>

<p><strong>Update 07/06/2013</strong>:</p>

<p>I’ve been made aware of <a href="http://www.ntp.org"><abbr title="Network Time Protocol">NTP</abbr></a>, which provides a mechanism of transmitting an accurate time across a network. However, (according to the FAQ it can take up to 5 minutes to determine the time accurately)[http://www.ntp.org/ntpfaq/<abbr title="Network Time Protocol">NTP</abbr>-s-algo.htm]. This is because it has to make multiple requests to sanity-check the result and ensure latency isn’t affecting the time.</p>

<p>I doubt many people will remain on the home page for 5 minutes and since the page would not have access to set the time of the user’s computer clock the process would have to start from scratch each time the page loaded.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Javascript Named Arguments]]></title>
    <link href="http://blog.norestfortheweekend.com/blog/2013/05/22/javascript-named-arguments/"/>
    <updated>2013-05-22T08:47:00+01:00</updated>
    <id>http://blog.norestfortheweekend.com/blog/2013/05/22/javascript-named-arguments</id>
    <content type="html"><![CDATA[<h2 id="whats-in-a-name">What’s In A Name?</h2>

<p>Javascript is an extremely versatile language, however it is missing various useful features that other languages aren’t. In many cases these features can be added with a shim or a polyfill, if required. However, there is a set of missing features that are low-level enough that a shim isn’t possible. They are all surrounding function arguments:</p>

<ul>
  <li>Named arguments</li>
  <li>Default argument values</li>
  <li>Argument type enforcement</li>
</ul>

<p>Default argument values is actually <a href="https://wiki.mozilla.org/ES6_plans#New_syntax_.28stuff_that_affects_the_front_end_and.2For_bytecode.29">a feature proposed in ES6</a> but as we aren’t quite there yet with ES6 I decided to patch the functionality myself in the best way I could. I’ve made a little library and it’s called <a href="http://namesjs.markstickley.co.uk">Names.js</a>. Please <a href="https://github.com/markstickley/names.js">fork it</a> and help me improve it!</p>

<h2 id="namesjs">Names.js</h2>

<p>As it is impossible to alter the fundamental way that functions work without making changes to the Javascript engine, it’s written as an augmentation to the <code>Function</code> object adding a couple of instance methods to the prototype and a static method to the main object. The static method is this:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>Javascript</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
</pre></td><td class="code"><pre><code class="javascript"><span class="line"><span class="kd">var</span> <span class="nx">myFunction</span> <span class="o">=</span> <span class="nb">Function</span><span class="p">.</span><span class="nx">createNamed</span><span class="p">({</span>
</span><span class="line">    <span class="nx">args</span><span class="o">:</span> <span class="p">[</span>
</span><span class="line">        <span class="p">[</span><span class="s1">&#39;arg1&#39;</span><span class="p">,</span> <span class="s1">&#39;string&#39;</span><span class="p">,</span> <span class="s1">&#39;defaultValue&#39;</span><span class="p">],</span>
</span><span class="line">        <span class="p">[</span><span class="s1">&#39;arg2&#39;</span><span class="p">,</span> <span class="nx">MyClass</span><span class="p">,</span> <span class="nx">someVar</span><span class="p">]</span>
</span><span class="line">    <span class="p">],</span>
</span><span class="line">    <span class="nx">method</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">arg1</span><span class="p">,</span> <span class="nx">arg2</span><span class="p">)</span> <span class="p">{</span>
</span><span class="line">        <span class="c1">// ...</span>
</span><span class="line">    <span class="p">}</span>
</span><span class="line"><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>It’s a bit more verbose than simply</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>Javascript</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
</pre></td><td class="code"><pre><code class="javascript"><span class="line"><span class="kd">var</span> <span class="nx">myFunction</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">arg1</span><span class="p">,</span> <span class="nx">arg2</span><span class="p">)</span> <span class="p">{</span>
</span><span class="line">    <span class="c1">// ...</span>
</span><span class="line"><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>however it offers the following benefits:</p>

<ul>
  <li>You don’t need to provide an argument each time if you’re happy with the default value:</li>
</ul>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>Javascript</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
</pre></td><td class="code"><pre><code class="javascript"><span class="line"><span class="nx">myFunction</span><span class="p">.</span><span class="nx">applyNamed</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="p">{</span> <span class="nx">arg1</span><span class="o">:</span> <span class="s1">&#39;Hello world&#39;</span> <span class="p">});</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<ul>
  <li>You know what each argument <em>means</em> (this advantage is a lot clearer when the arguments are named well and the values you are assigning them are all booleans and integers).</li>
  <li>You can provide the arguments in whichever order you like:</li>
</ul>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>Javascript</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
</pre></td><td class="code"><pre><code class="javascript"><span class="line"><span class="nx">myFunction</span><span class="p">.</span><span class="nx">applyNamed</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="p">{</span>
</span><span class="line">    <span class="nx">arg2</span><span class="o">:</span> <span class="nx">fooBar</span><span class="p">,</span>
</span><span class="line">    <span class="nx">arg1</span><span class="o">:</span> <span class="s1">&#39;Hello world&#39;</span>
</span><span class="line"><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<ul>
  <li>The function will throw an error if you pass it an incorrectly typed value:</li>
</ul>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>Javascript</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
</pre></td><td class="code"><pre><code class="javascript"><span class="line"><span class="nx">myFunction</span><span class="p">.</span><span class="nx">applyNamed</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="p">{</span> <span class="nx">arg1</span><span class="o">:</span> <span class="mi">1234</span> <span class="p">});</span> <span class="c1">// throws, as 1234 is not a &#39;string&#39;</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p><code>applyNamed</code> works just like Javascript’s native <code>apply</code> method, taking the scope as the first argument and the arguments to apply as the second.</p>

<h2 id="adding-validation">Adding validation</h2>

<p>In many languages, type checking is mandatory but at the end of the day it’s just a form of validation. In an effort to reduce the usual argument-checking clutter at the beginning of a function I thought it was worth extending the validation functionality to allow for custom validations.</p>

<p>You can either use a regex or a function:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>Javascript</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
</pre></td><td class="code"><pre><code class="javascript"><span class="line"><span class="nx">myFunction</span><span class="p">.</span><span class="nx">addValidaton</span><span class="p">({</span>
</span><span class="line">    <span class="nx">arg1</span><span class="o">:</span> <span class="p">{</span>
</span><span class="line">        <span class="nx">test</span><span class="o">:</span> <span class="sr">/-a-diddly$/</span><span class="p">,</span> <span class="c1">// Check for Flanders</span>
</span><span class="line">    <span class="p">},</span>
</span><span class="line">    <span class="nx">arg2</span><span class="o">:</span> <span class="p">{</span>
</span><span class="line">        <span class="nx">test</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">myClass</span><span class="p">)</span> <span class="p">{</span>
</span><span class="line">            <span class="k">return</span> <span class="nx">myClass</span><span class="p">.</span><span class="nx">isInitialised</span><span class="p">;</span>
</span><span class="line">        <span class="p">},</span>
</span><span class="line">        <span class="nx">required</span><span class="o">:</span> <span class="kc">true</span>
</span><span class="line">    <span class="p">}</span>
</span><span class="line"><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>The <code>required</code> option on <code>arg2</code>’s validation object means that <code>arg2</code> is required. Ordinarily if the argument is omitted when calling <code>applyNamed</code> then that validation will not be run. If the argument is omitted but the validation for that argument states that it is <code>required</code> then it will fail instantly.</p>

<h2 id="dogs-dinner">Dog’s dinner</h2>

<p>Names.js <a href="http://en.wikipedia.org/wiki/Eating_your_own_dog_food">eats its own dogfood</a> wherever possible and practical. There are only 3 public functions:</p>

<ul>
  <li><code>applyNamed</code> wouldn’t make sense to be able to <code>applyNamed</code> to.</li>
  <li><code>createNamed</code> would be an even more verbose way of creating a function if you used it with <code>applyNamed</code>. However it does use an <code>applyNamed</code>-style syntax and goes on to use <code>applyNamed</code> internally to create the new function.</li>
  <li><code>addValidation</code> is not only created with <code>createNamed</code> but also its own validation rules are added using <code>addValidation</code>. Talk about meta!</li>
</ul>

<h2 id="and">And…</h2>

<p>…that’s pretty much it really. I also wrote a <a href="https://github.com/markstickley/names.js/blob/master/release">release script</a> for the library that I’m pretty pleased with but maybe that’s for another blog post :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Interviewing for CSS]]></title>
    <link href="http://blog.norestfortheweekend.com/blog/2013/01/31/interviewing-for-css/"/>
    <updated>2013-01-31T23:43:00+00:00</updated>
    <id>http://blog.norestfortheweekend.com/blog/2013/01/31/interviewing-for-css</id>
    <content type="html"><![CDATA[<p>One day in my previous job I was kind of dropped in it when my boss asked me at about 5pm to interview a potential new recruit at 11am the next day. I’d never been on that side of the table in an interview before. Considering how long I had got to prepare I was understandably a little nervous - and for good reason. When you’re interviewing, not only do you have to display an excellent knowledge of the topics you are discussing but you also have to assess whether the person you are talking to possesses that same knowledge. If you do not do this well you are either rejecting a good candidate (which is bad) or hiring a bad one (which is worse).</p>

<p>I was told that the role was for a short contract and the successful candidate would be showing a little love to our badly neglected CSS, both tidying it up while also making sure the styles were rendering accurately according to the designs (plus a few extra tweaks here and there). So basically they had to be fluent in CSS-ese.</p>

<h2 id="twitter-saves-the-day-again">Twitter saves the day again</h2>

<p>When faced with a daunting task such as this, I did what any other self-respecting geek would do and turned to the all-knowing masses on Twitter.</p>

<p>Some brilliant people came to my rescue almost immediately and here are their responses:</p>

<!-- "spell 'specificity' (and then explain it...)" -@rich13 -->
<div class="embed tweet"><blockquote class="twitter-tweet"><p>@<a href="https://twitter.com/markstickley">markstickley</a> &#8220;spell &#8216;specificity&#8217; (and then explain it&#8230;)&#8221;</p>&mdash; Richard Northover (@rich13) <a href="https://twitter.com/rich13/status/200628477991464961">May 10, 2012</a></blockquote>
<script async="" src="http://blog.norestfortheweekend.com//platform.twitter.com/widgets.js" charset="utf-8"></script></div>

<p>I like this one because it’s really getting back to basics. Not only do you have to know that specificity exists but you have to understand what it does and how it does it. The spelling part is a bit of fun - hopefully the candidate will understand that that’s not the important part! Here’s <a href="http://css-tricks.com/specifics-on-css-specificity/">an article on CSS specificity</a> if you need a refresher.</p>

<!-- I got asked the difference between display:none; and visibility:hidden -@mfujica -->
<div class="embed tweet"><blockquote class="twitter-tweet"><p>@<a href="https://twitter.com/markstickley">markstickley</a> I got asked the difference between display:none; and visibility:hidden - but that&#8217;s years ago&#8230;</p>&mdash; Morena Fiore (@mfujica) <a href="https://twitter.com/mfujica/status/200629821737406465">May 10, 2012</a></blockquote>
<script async="" src="http://blog.norestfortheweekend.com//platform.twitter.com/widgets.js" charset="utf-8"></script></div>

<p>This is a nice one as well. It checks that they have some understanding about how the document flow works. You could follow this question up by asking if they know any other ways of hiding content and why they might want to do it that way instead.</p>

<p>The answer, of course, is that <code>display: none</code> removes the element from the document flow while <code>visibility: hidden</code> does not. Another way of hiding content (which is good for accessibility as it doesn’t hide it from screen readers) is by using a negative margin. There are various drawbacks and other ways of achieveing this which might also be a good thing to discuss.</p>

<!-- What is the default position of an element? -@mfujica -->
<div class="embed tweet"><blockquote class="twitter-tweet"><p>@<a href="https://twitter.com/markstickley">markstickley</a> What is the default position of an element?</p>&mdash; Morena Fiore (@mfujica) <a href="https://twitter.com/mfujica/status/200630440720220160">May 10, 2012</a></blockquote>
<script async="" src="http://blog.norestfortheweekend.com//platform.twitter.com/widgets.js" charset="utf-8"></script></div>

<p>It is <code>static</code>. But it’s not the most well-known property as normally we are changing the position <em>from</em> <code>static</code> <em>to</em> something else, like <code>relative</code> or <code>fixed</code>.</p>

<!-- Explaning what inline-block is also should be a good -@mfujica -->
<div class="embed tweet"><blockquote class="twitter-tweet"><p>@<a href="https://twitter.com/markstickley">markstickley</a> Explaning what inline-block is also should be a good question&#8230;</p>&mdash; Morena Fiore (@mfujica) <a href="https://twitter.com/mfujica/status/200631684956299266">May 10, 2012</a></blockquote>
<script async="" src="http://blog.norestfortheweekend.com//platform.twitter.com/widgets.js" charset="utf-8"></script></div>

<p><code>inline-block</code> has only really been useful since IE started supporting it properly (around v8) and so while it’s very handy, not everyone has used it.</p>

<p>An element with <code>display: inline-block</code> flows in the document like an inline element but allows you to apply styles to it that normally only apply to block-level elements such as <code>margin</code>, <code>width</code> and <code>height</code>.</p>

<!-- what is CSS3? Draw an arrow head using borders. -@ralfas -->
<div class="embed tweet"><blockquote class="twitter-tweet"><p>@<a href="https://twitter.com/markstickley">markstickley</a> what is CSS3? Draw an arrow head using borders.</p>&mdash; Ralfas Jegorovas (@ralfas) <a href="https://twitter.com/ralfas/status/200843040892518400">May 11, 2012</a></blockquote>
<script async="" src="http://blog.norestfortheweekend.com//platform.twitter.com/widgets.js" charset="utf-8"></script></div>

<p>I expect most candidates would ask for clarification or look confused at the first part of that question. That’s fine, seeing their reaction allows you to gauge the way they might react to a poorly defined spec, for example. It’s kind of open ended so they might simply say “It’s the latest version of CSS”. Others may list a few new features. If they’re really smart they’ll tell you that CSS3 hasn’t been formally specified because it’s still in development.</p>

<p>Drawing an arrowhead with borders requires the knowledge that when fat borders meet on adjacent edges they form a diagonal. Check out <a href="http://www.yuiblog.com/blog/2010/11/22/css-quick-tip-css-arrows-and-shapes-without-markup/">this article</a> for more details. Alternatively you can ask them to <a href="http://blog.norestfortheweekend.com/blog/2012/07/11/zero-image-close-buttons/">create a close button with pure CSS</a> if you’re feeling mean!</p>

<!-- @markstickley @mfujica just make sure you know the answers yourself... -@timblair -->
<div class="embed tweet"><blockquote class="twitter-tweet"><p>@<a href="https://twitter.com/markstickley">markstickley</a> @<a href="https://twitter.com/mfujica">mfujica</a> just make sure you know the answers yourself&#8230;</p>&mdash; Tim Blair (@timblair) <a href="https://twitter.com/timblair/status/200633510950748161">May 10, 2012</a></blockquote>
<script async="" src="http://blog.norestfortheweekend.com//platform.twitter.com/widgets.js" charset="utf-8"></script></div>

<p>Yep :)</p>

<h2 id="other-ideas">Other ideas</h2>

<h3 id="vendor-prefixes">Vendor prefixes</h3>

<p>I quite like an open ended question, particularly if it calls for some opinion. A lot of this industry is based on facts and rigid concepts that are either right or wrong so hearing someone’s opinion and their ability to express it well could be the difference between a hire and a no-hire.</p>

<p>Simply ask them to explain vendor prefixes, what they’re for and importantly whether they think they are a good idea, making sure to push them for both positive and negative points).</p>

<h3 id="box-model">Box model</h3>

<p>Get them to explain <a href="https://developer.mozilla.org/en-US/docs/CSS/box_model">the box model</a> to you. You’re looking for a good understanding of the different parts that come into play, particularly how it can affect how wide an element will be (and how it won’t always be the same width as its <code>width</code> value). This conversation can then lead onto <a href="https://developer.mozilla.org/en-US/docs/CSS/box-sizing">the <code>box-sizing</code> property</a> introduced in CSS3. See if they know the default value for all element (<code>content-box</code>) and for bonus points see if they know which mode IE uses in Quirks Mode (<code>border-box</code>).</p>

<h3 id="scss">SCSS</h3>

<p>Of course these days CSS isn’t quite as static as it used to be with code generators like <a href="http://sass-lang.com/">Sass</a> and <a href="http://lesscss.org/">less</a> becoming more and more popular. You can ask if they know about these technologies (and what they think of them). If you’re using one in your business, you should probably have a few specific questions about it as well ;)</p>

<p>In favour of CSS generation, it is nice to be able to use a <abbr title="Don't Repeat Yourself">DRY</abbr> methodology through mixins and inheritance, and it’s even better to be able to define things once and use them many times throughout the document (like colours). Against it, the code generated can be quite verbose and it’s typically hard to debug as looking at the compiled code gives you no indication where a rule exists (or was generated from) in the source.</p>

<h3 id="implement-something-with-no-classes-or-ids">Implement {something} with no classes or ids</h3>

<p>Finally, get them to code up some HTML and CSS for a small interface element (Eg. a tweet (including all the meta data around it)) but do it <strong>without using classes or ids</strong>. Ask them to use HTML5 and to use semantically relevant tags.</p>

<p>This task can take a while but it shows a lot about their thinking process.</p>

<ul>
  <li>It shows they have a knowledge of HTML5 tags and semantic markup</li>
  <li>It forces them to improvise with the use of CSS selectors</li>
</ul>

<p>There are many under-used selectors out there which would be perfect for this sort of task. Just <a href="http://www.w3.org/TR/selectors/#selectors">look at them</a>! Do you know all of them? I know I don’t, certainly not without looking. If you really wanted to test just their CSS skills then you could write the HTML for them in a way that would force them to use specific selectors. The sky really is the limit here… get creative!</p>

<h2 id="any-more">Any more?</h2>

<p>If you’ve got any favourites (and I’m sure you have, whether they’re questions you use or have had used on you), please stick them in the comments. I’d be really interested to hear them!</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Zero image close buttons]]></title>
    <link href="http://blog.norestfortheweekend.com/blog/2012/07/11/zero-image-close-buttons/"/>
    <updated>2012-07-11T15:06:00+01:00</updated>
    <id>http://blog.norestfortheweekend.com/blog/2012/07/11/zero-image-close-buttons</id>
    <content type="html"><![CDATA[<p>While I was <a href="http://en.wiktionary.org/wiki/yak_shaving#Noun">shaving yaks</a> recently, I came across and interface element in our product: a tiny button that removed an item from a list. The button was just a simple circle with an X through it.</p>

<p>Originally it had been created by hiding the text of a link, using the <code>:before</code> selector and the <code>content</code> property to add an X and then styling it. It wasn’t ideal because it never really lined up properly, especially when the font size changed and <em>especially</em> if the font family was changed. I wanted to find a better way.</p>

<h2 id="using-a-gradient-as-a-gradient-is-so-overrated">Using a gradient as a gradient is so overrated</h2>

<p>You can create a much better X with a few gradients! In fact, gradient backgrounds, multiple background images and rounded corners give you pretty much all the tools you need to create the <strong>best X button ever</strong>. You just have to realise that just because it’s called a gradient it doesn’t have to look like one.</p>

<p>There are two ways of doing this, but I’ll start with the simplest. Let’s deconstruct our button:</p>

<p><img class="center" src="http://blog.norestfortheweekend.com/images/posts/2012/07/11/zero-image-close-buttons/simple-breakdown.png" width="514" height="195" title="'The X is just two lines'" /></p>

<p>As a single linear gradient can only make lines parallel to each other, we need to make two lines by using two gradients.</p>

<p>By placing two colour stops of differing colours right next to each other we create a solid transition between colours instead of a gradient.</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>CSS</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
</pre></td><td class="code"><pre><code class="css"><span class="line"><span class="nt">a</span><span class="nc">.close</span><span class="p">{</span>
</span><span class="line">    <span class="k">background-image</span><span class="o">:</span> <span class="n">linear</span><span class="o">-</span><span class="n">gradient</span><span class="p">(</span><span class="m">135</span><span class="n">deg</span><span class="o">,</span> <span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">0</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">41</span><span class="o">.</span><span class="m">5</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">1</span><span class="p">)</span> <span class="m">41</span><span class="o">.</span><span class="m">5</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">1</span><span class="p">)</span> <span class="m">58</span><span class="o">.</span><span class="m">5</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">58</span><span class="o">.</span><span class="m">5</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">100</span><span class="o">%</span><span class="p">)</span><span class="o">,</span>
</span><span class="line">                      <span class="n">linear</span><span class="o">-</span><span class="n">gradient</span><span class="p">(</span><span class="m">45</span><span class="n">deg</span><span class="o">,</span> <span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">0</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">41</span><span class="o">.</span><span class="m">5</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">1</span><span class="p">)</span> <span class="m">41</span><span class="o">.</span><span class="m">5</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">1</span><span class="p">)</span> <span class="m">58</span><span class="o">.</span><span class="m">5</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">58</span><span class="o">.</span><span class="m">5</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">100</span><span class="o">%</span><span class="p">);</span>
</span><span class="line"><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>
<p>You can <a href="http://blog.norestfortheweekend.com/demos/zero-image-close-buttons/simple.html">see it in action</a> and also check the source for the full gamut of vendor extensions.</p>

<h2 id="adding-pzazz">Adding pzazz</h2>

<p>We can make our close button look a lot like the <a href="https://www.google.co.uk/search?q=x+men+logo&amp;tbm=isch">X-Men logo</a> by adding a couple of lines of extra CSS. I added a hover state as well just for kicks:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>CSS</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
</pre></td><td class="code"><pre><code class="css"><span class="line"><span class="nt">a</span><span class="nc">.close</span><span class="p">{</span>
</span><span class="line">    <span class="k">background-image</span><span class="o">:</span> <span class="n">linear</span><span class="o">-</span><span class="n">gradient</span><span class="p">(</span><span class="m">135</span><span class="n">deg</span><span class="o">,</span> <span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">0</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">41</span><span class="o">.</span><span class="m">5</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">1</span><span class="p">)</span> <span class="m">41</span><span class="o">.</span><span class="m">5</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">1</span><span class="p">)</span> <span class="m">58</span><span class="o">.</span><span class="m">5</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">58</span><span class="o">.</span><span class="m">5</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">100</span><span class="o">%</span><span class="p">)</span><span class="o">,</span>
</span><span class="line">                      <span class="n">linear</span><span class="o">-</span><span class="n">gradient</span><span class="p">(</span><span class="m">45</span><span class="n">deg</span><span class="o">,</span> <span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">0</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">41</span><span class="o">.</span><span class="m">5</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">1</span><span class="p">)</span> <span class="m">41</span><span class="o">.</span><span class="m">5</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">1</span><span class="p">)</span> <span class="m">58</span><span class="o">.</span><span class="m">5</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">58</span><span class="o">.</span><span class="m">5</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">100</span><span class="o">%</span><span class="p">);</span>
</span><span class="line">
</span><span class="line">    <span class="k">border</span><span class="o">:</span> <span class="m">3px</span> <span class="k">solid</span> <span class="nb">black</span><span class="p">;</span>
</span><span class="line">    <span class="k">border</span><span class="o">-</span><span class="n">radius</span><span class="o">:</span> <span class="m">5px</span><span class="p">;</span>
</span><span class="line"><span class="p">}</span>
</span><span class="line"><span class="nt">a</span><span class="nc">.close</span><span class="nd">:hover</span><span class="p">{</span>
</span><span class="line">    <span class="k">background-color</span><span class="o">:</span> <span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">.</span><span class="m">1</span><span class="p">);</span>
</span><span class="line"><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>
<p><a href="http://blog.norestfortheweekend.com/demos/zero-image-close-buttons/simple-with-border.html">See it in action here</a>.</p>

<h2 id="the-next-level">The next level</h2>

<p>The above approach is a bit limited. A couple of problems:</p>

<ul>
  <li>It’s easy to change the background or to leave it transparent, BUT what if we want the background to have a solid colour and have the X transparent, letting the colour or image behind show through? It doesn’t work.</li>
  <li>With one line of the X overlaid on the other it would be impossible to give the lines of the X a gradient with any kind of rotational symmetry.</li>
</ul>

<p>Both these problems can be solved by deconstructing the X a little further:</p>

<p><img class="center" src="http://blog.norestfortheweekend.com/images/posts/2012/07/11/zero-image-close-buttons/advanced-breakdown.png" width="200" height="200" title="'The X is four lines joining at the centre'" /></p>

<p>This means as well as creating four gradients we must also give them each different positions within the element they apply to.</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>CSS</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
</pre></td><td class="code"><pre><code class="css"><span class="line"><span class="nt">a</span><span class="nc">.close</span><span class="p">{</span>
</span><span class="line">    <span class="k">background-image</span><span class="o">:</span> <span class="n">linear</span><span class="o">-</span><span class="n">gradient</span><span class="p">(</span><span class="m">135</span><span class="n">deg</span><span class="o">,</span> <span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">0</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">33</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">1</span><span class="p">)</span> <span class="m">33</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">1</span><span class="p">)</span> <span class="m">67</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">67</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">100</span><span class="o">%</span><span class="p">)</span><span class="o">,</span>
</span><span class="line">                      <span class="n">linear</span><span class="o">-</span><span class="n">gradient</span><span class="p">(</span><span class="m">45</span><span class="n">deg</span><span class="o">,</span> <span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">0</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">33</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">1</span><span class="p">)</span> <span class="m">33</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">1</span><span class="p">)</span> <span class="m">67</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">67</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">100</span><span class="o">%</span><span class="p">)</span><span class="o">,</span>
</span><span class="line">                      <span class="n">linear</span><span class="o">-</span><span class="n">gradient</span><span class="p">(</span><span class="m">135</span><span class="n">deg</span><span class="o">,</span> <span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">0</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">33</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">1</span><span class="p">)</span> <span class="m">33</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">1</span><span class="p">)</span> <span class="m">67</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">67</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">100</span><span class="o">%</span><span class="p">)</span><span class="o">,</span>
</span><span class="line">                      <span class="n">linear</span><span class="o">-</span><span class="n">gradient</span><span class="p">(</span><span class="m">45</span><span class="n">deg</span><span class="o">,</span> <span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">0</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">33</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">1</span><span class="p">)</span> <span class="m">33</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">1</span><span class="p">)</span> <span class="m">67</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">67</span><span class="o">%,</span><span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">100</span><span class="o">%</span><span class="p">);</span>
</span><span class="line">
</span><span class="line">    <span class="k">background</span><span class="o">-</span><span class="k">size</span><span class="o">:</span> <span class="m">50</span><span class="o">%</span><span class="p">;</span>
</span><span class="line">    <span class="k">background-repeat</span><span class="o">:</span> <span class="k">no-repeat</span><span class="p">;</span>
</span><span class="line">    <span class="k">background-position</span><span class="o">:</span> <span class="k">right</span> <span class="k">top</span><span class="o">,</span> <span class="k">left</span> <span class="k">top</span><span class="o">,</span> <span class="k">left</span> <span class="k">bottom</span><span class="o">,</span> <span class="k">right</span> <span class="k">bottom</span><span class="p">;</span>
</span><span class="line"><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p><a href="http://blog.norestfortheweekend.com/demos/zero-image-close-buttons/advanced.html">See it</a>! (Yes, it looks the same as the first one).</p>

<h2 id="thats-a-bit-fancy">That’s a bit fancy</h2>

<p>Now that each ‘spoke’ of the X is created by a separate gradient, we can get super-fancy and create effects like <a href="http://blog.norestfortheweekend.com/demos/zero-image-close-buttons/fancy1.html">this</a>, <a href="http://blog.norestfortheweekend.com/demos/zero-image-close-buttons/fancy2.html">this</a> and <a href="http://blog.norestfortheweekend.com/demos/zero-image-close-buttons/fancy3.html">this</a>.</p>

<h2 id="getting-sassy">Getting SASSy</h2>

<p>It only seems right that all this goodness should be rolled into a simple-to-use SCSS mixin. Copy and paste this code and create close buttons as easily as typing <code>@include XBackground($foreground: white, $background: gray, $width: 34%)</code> (adding your own <code>border</code> and <code>border-radius</code> as required).</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>SCSS</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
<span class="line-number">13</span>
<span class="line-number">14</span>
<span class="line-number">15</span>
</pre></td><td class="code"><pre><code class="scss"><span class="line"><span class="k">@mixin</span><span class="nf"> XBackground</span><span class="p">(</span><span class="nv">$foreground</span><span class="o">,</span> <span class="nv">$background</span><span class="o">,</span> <span class="nv">$width</span><span class="p">)</span> <span class="p">{</span>
</span><span class="line">    <span class="nv">$stop1</span><span class="o">:</span> <span class="mi">50</span><span class="kt">%</span> <span class="o">-</span> <span class="p">(</span><span class="nv">$width</span> <span class="o">/</span> <span class="mi">2</span><span class="p">);</span>
</span><span class="line">    <span class="nv">$stop2</span><span class="o">:</span> <span class="mi">50</span><span class="kt">%</span> <span class="o">+</span> <span class="p">(</span><span class="nv">$width</span> <span class="o">/</span> <span class="mi">2</span><span class="p">);</span>
</span><span class="line">
</span><span class="line">    <span class="na">background-image</span><span class="o">:</span> <span class="nf">-moz-linear-gradient</span><span class="p">(</span><span class="mi">-45</span><span class="kt">deg</span><span class="o">,</span> <span class="nv">$background</span> <span class="mi">0</span><span class="kt">%</span><span class="o">,</span> <span class="nv">$background</span> <span class="nv">$stop1</span><span class="o">,</span> <span class="nv">$foreground</span> <span class="nv">$stop1</span><span class="o">,</span> <span class="nv">$foreground</span> <span class="nv">$stop2</span><span class="o">,</span> <span class="nv">$background</span> <span class="nv">$stop2</span><span class="o">,</span> <span class="nv">$background</span> <span class="mi">100</span><span class="kt">%</span><span class="p">)</span><span class="o">,</span> <span class="nf">-moz-linear-gradient</span><span class="p">(</span><span class="mi">45</span><span class="kt">deg</span><span class="o">,</span> <span class="nv">$background</span> <span class="mi">0</span><span class="kt">%</span><span class="o">,</span> <span class="nv">$background</span> <span class="nv">$stop1</span><span class="o">,</span> <span class="nv">$foreground</span> <span class="nv">$stop1</span><span class="o">,</span> <span class="nv">$foreground</span> <span class="nv">$stop2</span><span class="o">,</span> <span class="nv">$background</span> <span class="nv">$stop2</span><span class="o">,</span> <span class="nv">$background</span> <span class="mi">100</span><span class="kt">%</span><span class="p">)</span><span class="o">,-</span><span class="nf">moz-linear-gradient</span><span class="p">(</span><span class="mi">-45</span><span class="kt">deg</span><span class="o">,</span> <span class="nv">$background</span> <span class="mi">0</span><span class="kt">%</span><span class="o">,</span> <span class="nv">$background</span> <span class="nv">$stop1</span><span class="o">,</span> <span class="nv">$foreground</span> <span class="nv">$stop1</span><span class="o">,</span> <span class="nv">$foreground</span> <span class="nv">$stop2</span><span class="o">,</span> <span class="nv">$background</span> <span class="nv">$stop2</span><span class="o">,</span> <span class="nv">$background</span> <span class="mi">100</span><span class="kt">%</span><span class="p">)</span><span class="o">,</span> <span class="nf">-moz-linear-gradient</span><span class="p">(</span><span class="mi">45</span><span class="kt">deg</span><span class="o">,</span> <span class="nv">$background</span> <span class="mi">0</span><span class="kt">%</span><span class="o">,</span> <span class="nv">$background</span> <span class="nv">$stop1</span><span class="o">,</span> <span class="nv">$foreground</span> <span class="nv">$stop1</span><span class="o">,</span> <span class="nv">$foreground</span> <span class="nv">$stop2</span><span class="o">,</span> <span class="nv">$background</span> <span class="nv">$stop2</span><span class="o">,</span> <span class="nv">$background</span> <span class="mi">100</span><span class="kt">%</span><span class="p">);</span>
</span><span class="line">	<span class="na">background-image</span><span class="o">:</span> <span class="nf">-webkit-gradient</span><span class="p">(</span><span class="n">linear</span><span class="o">,</span> <span class="no">left</span> <span class="no">top</span><span class="o">,</span> <span class="no">right</span> <span class="no">bottom</span><span class="o">,</span> <span class="nf">color-stop</span><span class="p">(</span><span class="mi">0</span><span class="kt">%</span><span class="o">,</span><span class="nv">$background</span><span class="p">)</span><span class="o">,</span> <span class="nf">color-stop</span><span class="p">(</span><span class="nv">$stop1</span><span class="o">,</span><span class="nv">$background</span><span class="p">)</span><span class="o">,</span> <span class="nf">color-stop</span><span class="p">(</span><span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span><span class="p">)</span><span class="o">,</span> <span class="nf">color-stop</span><span class="p">(</span><span class="nv">$stop2</span><span class="o">,</span><span class="nv">$foreground</span><span class="p">)</span><span class="o">,</span> <span class="nf">color-stop</span><span class="p">(</span><span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span><span class="p">)</span><span class="o">,</span> <span class="nf">color-stop</span><span class="p">(</span><span class="mi">100</span><span class="kt">%</span><span class="o">,</span><span class="nv">$background</span><span class="p">))</span><span class="o">,</span> <span class="nf">-webkit-gradient</span><span class="p">(</span><span class="n">linear</span><span class="o">,</span> <span class="no">right</span> <span class="no">top</span><span class="o">,</span> <span class="no">left</span> <span class="no">bottom</span><span class="o">,</span> <span class="nf">color-stop</span><span class="p">(</span><span class="mi">0</span><span class="kt">%</span><span class="o">,</span><span class="nv">$background</span><span class="p">)</span><span class="o">,</span> <span class="nf">color-stop</span><span class="p">(</span><span class="nv">$stop1</span><span class="o">,</span><span class="nv">$background</span><span class="p">)</span><span class="o">,</span> <span class="nf">color-stop</span><span class="p">(</span><span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span><span class="p">)</span><span class="o">,</span> <span class="nf">color-stop</span><span class="p">(</span><span class="nv">$stop2</span><span class="o">,</span><span class="nv">$foreground</span><span class="p">)</span><span class="o">,</span> <span class="nf">color-stop</span><span class="p">(</span><span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span><span class="p">)</span><span class="o">,</span> <span class="nf">color-stop</span><span class="p">(</span><span class="mi">100</span><span class="kt">%</span><span class="o">,</span><span class="nv">$background</span><span class="p">))</span><span class="o">,-</span><span class="nf">webkit-gradient</span><span class="p">(</span><span class="n">linear</span><span class="o">,</span> <span class="no">left</span> <span class="no">top</span><span class="o">,</span> <span class="no">right</span> <span class="no">bottom</span><span class="o">,</span> <span class="nf">color-stop</span><span class="p">(</span><span class="mi">0</span><span class="kt">%</span><span class="o">,</span><span class="nv">$background</span><span class="p">)</span><span class="o">,</span> <span class="nf">color-stop</span><span class="p">(</span><span class="nv">$stop1</span><span class="o">,</span><span class="nv">$background</span><span class="p">)</span><span class="o">,</span> <span class="nf">color-stop</span><span class="p">(</span><span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span><span class="p">)</span><span class="o">,</span> <span class="nf">color-stop</span><span class="p">(</span><span class="nv">$stop2</span><span class="o">,</span><span class="nv">$foreground</span><span class="p">)</span><span class="o">,</span> <span class="nf">color-stop</span><span class="p">(</span><span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span><span class="p">)</span><span class="o">,</span> <span class="nf">color-stop</span><span class="p">(</span><span class="mi">100</span><span class="kt">%</span><span class="o">,</span><span class="nv">$background</span><span class="p">))</span><span class="o">,</span> <span class="nf">-webkit-gradient</span><span class="p">(</span><span class="n">linear</span><span class="o">,</span> <span class="no">right</span> <span class="no">top</span><span class="o">,</span> <span class="no">left</span> <span class="no">bottom</span><span class="o">,</span> <span class="nf">color-stop</span><span class="p">(</span><span class="mi">0</span><span class="kt">%</span><span class="o">,</span><span class="nv">$background</span><span class="p">)</span><span class="o">,</span> <span class="nf">color-stop</span><span class="p">(</span><span class="nv">$stop1</span><span class="o">,</span><span class="nv">$background</span><span class="p">)</span><span class="o">,</span> <span class="nf">color-stop</span><span class="p">(</span><span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span><span class="p">)</span><span class="o">,</span> <span class="nf">color-stop</span><span class="p">(</span><span class="nv">$stop2</span><span class="o">,</span><span class="nv">$foreground</span><span class="p">)</span><span class="o">,</span> <span class="nf">color-stop</span><span class="p">(</span><span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span><span class="p">)</span><span class="o">,</span> <span class="nf">color-stop</span><span class="p">(</span><span class="mi">100</span><span class="kt">%</span><span class="o">,</span><span class="nv">$background</span><span class="p">));</span>
</span><span class="line">	<span class="na">background-image</span><span class="o">:</span> <span class="nf">-webkit-linear-gradient</span><span class="p">(</span><span class="mi">-45</span><span class="kt">deg</span><span class="o">,</span> <span class="nv">$background</span> <span class="mi">0</span><span class="kt">%</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="mi">100</span><span class="kt">%</span><span class="p">)</span><span class="o">,</span> <span class="nf">-webkit-linear-gradient</span><span class="p">(</span><span class="mi">45</span><span class="kt">deg</span><span class="o">,</span> <span class="nv">$background</span> <span class="mi">0</span><span class="kt">%</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="mi">100</span><span class="kt">%</span><span class="p">)</span><span class="o">,-</span><span class="nf">webkit-linear-gradient</span><span class="p">(</span><span class="mi">-45</span><span class="kt">deg</span><span class="o">,</span> <span class="nv">$background</span> <span class="mi">0</span><span class="kt">%</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="mi">100</span><span class="kt">%</span><span class="p">)</span><span class="o">,</span> <span class="nf">-webkit-linear-gradient</span><span class="p">(</span><span class="mi">45</span><span class="kt">deg</span><span class="o">,</span> <span class="nv">$background</span> <span class="mi">0</span><span class="kt">%</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="mi">100</span><span class="kt">%</span><span class="p">);</span>
</span><span class="line">	<span class="na">background-image</span><span class="o">:</span> <span class="nf">-o-linear-gradient</span><span class="p">(</span><span class="mi">-45</span><span class="kt">deg</span><span class="o">,</span> <span class="nv">$background</span> <span class="mi">0</span><span class="kt">%</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="mi">100</span><span class="kt">%</span><span class="p">)</span><span class="o">,</span> <span class="nf">-o-linear-gradient</span><span class="p">(</span><span class="mi">45</span><span class="kt">deg</span><span class="o">,</span> <span class="nv">$background</span> <span class="mi">0</span><span class="kt">%</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="mi">100</span><span class="kt">%</span><span class="p">)</span><span class="o">,-</span><span class="nf">o-linear-gradient</span><span class="p">(</span><span class="mi">-45</span><span class="kt">deg</span><span class="o">,</span> <span class="nv">$background</span> <span class="mi">0</span><span class="kt">%</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="mi">100</span><span class="kt">%</span><span class="p">)</span><span class="o">,</span> <span class="nf">-o-linear-gradient</span><span class="p">(</span><span class="mi">45</span><span class="kt">deg</span><span class="o">,</span> <span class="nv">$background</span> <span class="mi">0</span><span class="kt">%</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="mi">100</span><span class="kt">%</span><span class="p">);</span>
</span><span class="line">	<span class="na">background-image</span><span class="o">:</span> <span class="nf">-ms-linear-gradient</span><span class="p">(</span><span class="mi">-45</span><span class="kt">deg</span><span class="o">,</span> <span class="nv">$background</span> <span class="mi">0</span><span class="kt">%</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="mi">100</span><span class="kt">%</span><span class="p">)</span><span class="o">,</span> <span class="nf">-ms-linear-gradient</span><span class="p">(</span><span class="mi">45</span><span class="kt">deg</span><span class="o">,</span> <span class="nv">$background</span> <span class="mi">0</span><span class="kt">%</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="mi">100</span><span class="kt">%</span><span class="p">)</span><span class="o">,-</span><span class="nf">ms-linear-gradient</span><span class="p">(</span><span class="mi">-45</span><span class="kt">deg</span><span class="o">,</span> <span class="nv">$background</span> <span class="mi">0</span><span class="kt">%</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="mi">100</span><span class="kt">%</span><span class="p">)</span><span class="o">,</span> <span class="nf">-ms-linear-gradient</span><span class="p">(</span><span class="mi">45</span><span class="kt">deg</span><span class="o">,</span> <span class="nv">$background</span> <span class="mi">0</span><span class="kt">%</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="mi">100</span><span class="kt">%</span><span class="p">);</span>
</span><span class="line">	<span class="na">background-image</span><span class="o">:</span> <span class="nf">linear-gradient</span><span class="p">(</span><span class="mi">135</span><span class="kt">deg</span><span class="o">,</span> <span class="nv">$background</span> <span class="mi">0</span><span class="kt">%</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="mi">100</span><span class="kt">%</span><span class="p">)</span><span class="o">,</span> <span class="nf">linear-gradient</span><span class="p">(</span><span class="mi">45</span><span class="kt">deg</span><span class="o">,</span> <span class="nv">$background</span> <span class="mi">0</span><span class="kt">%</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="mi">100</span><span class="kt">%</span><span class="p">)</span><span class="o">,</span><span class="nf">linear-gradient</span><span class="p">(</span><span class="mi">135</span><span class="kt">deg</span><span class="o">,</span> <span class="nv">$background</span> <span class="mi">0</span><span class="kt">%</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="mi">100</span><span class="kt">%</span><span class="p">)</span><span class="o">,</span> <span class="nf">linear-gradient</span><span class="p">(</span><span class="mi">45</span><span class="kt">deg</span><span class="o">,</span> <span class="nv">$background</span> <span class="mi">0</span><span class="kt">%</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop1</span><span class="o">,</span><span class="nv">$foreground</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="nv">$stop2</span><span class="o">,</span><span class="nv">$background</span> <span class="mi">100</span><span class="kt">%</span><span class="p">);</span>
</span><span class="line">
</span><span class="line">	<span class="na">background-size</span><span class="o">:</span> <span class="mi">50</span><span class="kt">%</span><span class="p">;</span>
</span><span class="line">	<span class="na">background-repeat</span><span class="o">:</span> <span class="no">no-repeat</span><span class="p">;</span>
</span><span class="line">	<span class="na">background-position</span><span class="o">:</span> <span class="no">right</span> <span class="no">top</span><span class="o">,</span> <span class="no">left</span> <span class="no">top</span><span class="o">,</span> <span class="no">left</span> <span class="no">bottom</span><span class="o">,</span> <span class="no">right</span> <span class="no">bottom</span><span class="p">;</span>
</span><span class="line"><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<h2 id="vendor-schmendor">Vendor schmendor</h2>

<p>Looking again at <a href="http://blog.norestfortheweekend.com/demos/zero-image-close-buttons/advanced.html">the CSS of the more advanced solution</a>, it turns out that there’s quite a lot of it. This is thanks to all the variations and vendor prefixes we have to use (THANKS FOR THAT VENDORS).</p>

<p>Of course another way we could do this is just to use an image. <em>Old school</em>. We can base64 encode and include it directly in the CSS. While doing that makes it a little larger than a separate file it cuts out the overhead of an extra request so it should be quicker overall.</p>

<p><a href="http://blog.norestfortheweekend.com/demos/zero-image-close-buttons/base64.html">Here</a>’s the base64 version in action. View source and you’ll see that it’s a lot smaller (about half the size) of the gradient-based solution. The gradient version will scale to any size but if you use it at a fixed size is it worth the extra bandwidth?</p>

<p>Fortunately you don’t need to make that choice! Here’s a handy little chart explaining why:</p>

<table class="display">
	<thead>
		<tr>
			<td class="unused"></td>
			<th>Chars</th>
			<th>Uncompressed</th>
			<th>Gzipped</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<th>Gradients</th>
			<td>3969</td>
			<td>3.84KB</td>
			<td>313 bytes</td>
		</tr>
		<tr>
			<th>Base64 image</th>
			<td>1961</td>
			<td>1.91KB</td>
			<td>1.33KB</td>
		</tr>
	</tbody>
</table>

<p>And you <em>are</em> gzipping all your stuff as you serve it, right? I thought so.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Moving from Wordpress to Octopress]]></title>
    <link href="http://blog.norestfortheweekend.com/blog/2012/05/12/moving-from-wordpress-to-octopress/"/>
    <updated>2012-05-12T15:34:00+01:00</updated>
    <id>http://blog.norestfortheweekend.com/blog/2012/05/12/moving-from-wordpress-to-octopress</id>
    <content type="html"><![CDATA[<p>My Wordpress install kept disabling all the plugins. No idea why. Because I don’t browse my own blog too regularly (especially with the regularity of posts I’ve been writing recently) the only indication I had was when I started getting lots of spam comments thanks to the lack of <a href="http://akismet.com/">Askimet</a>.</p>

<p>When <a href="http://www.twitter.com/elduderino78">a colleague</a> mentioned Wordpress recently, in particular how he would never use it in a million years, I asked what he would use instead thinking perhaps something like <a href="http://www.tumblr.com">Tumblr</a>, <a href="http://www.blogger.com">Blogger</a>, <a href="http://www.posterous.com">Posterous</a> or something similar. Instead, he suggested something decidedly more… <em>fishy</em>.</p>

<h2 id="octopress">Octopress</h2>

<p><a href="http://octopress.org/">Octopress</a> is a very neat little blogging environment. You write your posts in <a href="http://daringfireball.net/projects/markdown/">markdown</a> and then run a little rake script to generate your blog. The files generated are static HTML files which is great for performance and caching.</p>

<p>The blog’s structure is generated from templates and the CSS is generated using <a href="http://sass-lang.com/">SASS</a> so you get all the benefits of a dynamically generated site but none of the overheads. As if that wasn’t awesome enough, it’s virtually seamlessly integrated with GitHub and <a href="http://pages.github.com/">GitHub Pages</a>, so you write locally, generate and then deploy with another rake script.</p>

<h2 id="migrating-from-wordpress">Migrating from Wordpress</h2>

<p>To get all my stuff out of Wordpress I used Wordpress’ own export function to generate an XML document of all the posts and metadata. Then I used <a href="https://github.com/thomasf/exitwp">exitwp</a> to convert the XML to markdown, which worked OK. That converted everything except comments. Generating static files means that comments are not really possible natively but Octopress has built in support for <a href="http://disqus.com/">Disqus</a> which works seamlessly. This does mean that the old comments are lost but you know what they say: you can’t make a seafood paella without chopping up a few octopi.</p>

<p>It wasn’t all plain sailing though.</p>

<h2 id="this-almost-seems-like-work">This almost seems like work</h2>

<p>I noticed as I clicked through some of the generated markdown files that some scamp had been at my articles and inserted spam links directly into the articles! Honestly, I was getting more and more glad to be moving from Wordpress by the minute. This did mean I had to read each of them through to make sure there wasn’t anything in there I didn’t want. </p>

<p>Reading through your old blog posts is hard. There’s stuff that doesn’t matter any more, there’s stuff that’s just plain inaccurate, there’s stuff which sounds really goofy reading back 3 years later. I tried my hardest not to change the content in them and for the most part I managed for historical reasons to preserve it.</p>

<p>As I was going through each article I adjusted the formatting of the markdown making sure the heading level was correct, the line spacing was correct, the code correctly marked down etc. All the usual OCD stuff that needs doing once you know it’s there.</p>

<p>I had been using a plugin to handle media on Wordpress so images were kind of messed up and I had to copy all the images and reformat all the image tags by hand. I was so glad I hadn’t written all that many articles! Keeping it really simple in markdown seems so sensible I can’t believe we didn’t always blog like this.</p>

<p>The last thing that needed doing was to give it more of the look and feel of the old site. The default theme, <em>classic</em>, is very nice but I’m rather fond of that little pixel dude in the header. Plus I got to try out a friend’s clever <a href="http://glan.github.com/CSS-Patterns-Workbench/">CSS Patterns Workbench</a> to create the background in pure CSS instead of images.</p>

<h2 id="cname-cname-run">CNAME. CNAME RUN.</h2>

<p>One last awesome thing: GitHub Pages support domains. By setting your CNAME to point at the page (or the A tag if it’s the whole domain, not just a subdomain) you can point your site to GitHub Pages and have the whole thing hosted for free, no bandwidth charges or anything. I love you GitHub.</p>

<h2 id="verdict">Verdict</h2>

<p>I’m so glad I’m not using WordPress anymore. Wordpress blogs are such a target for hackers and spammers and I was hit several times over. I tended to keep fairly on top of the updates as well, so you can image how bad it might be for people who don’t bother. If anyone wants to hack this blog now they have to hack my GitHub account. Of course having <a href="https://github.com/markstickley/norestfortheweekend">the whole blog on GitHub</a> has its advantages too… if you like you can correct any mistakes or typos by submitting a pull request!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[3DS browser revisited]]></title>
    <link href="http://blog.norestfortheweekend.com/blog/2011/06/14/3ds-browser-revisited/"/>
    <updated>2011-06-14T01:19:14+01:00</updated>
    <id>http://blog.norestfortheweekend.com/blog/2011/06/14/3ds-browser-revisited</id>
    <content type="html"><![CDATA[<p>It’s been a few months since I made <a href="http://blog.norestfortheweekend.com/blog/2011/02/14/the-web-in-3d-the-nintendo-3ds-web-browser/">the post speculating about the 3DS’ browser capabilities</a>. Since the browser is now available and that post is easily the post that has drawn the most attention to my humble blog I thought it would be worth writing a quick follow-up.</p>

<p><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2011/06/photo.jpg" width="628" height="569" title="'Brand new Nintendo 3DS'" /></p>

<h3 id="not-letting-you-down-easily">Not letting you down easily</h3>

<p>There’s no way of saying this easily: the browser kind of sucks.</p>

<p>I’ve never found browsing on a console a particularly satisfying experience and I didn’t expect this to be any better. What excited me was the potential for extending the web into a new dimension. The browser doesn’t even do that. It’s nowhere near as awesome as I’d hoped. No 3D, no custom CSS extensions. It ‘does’ 3D… sort of. You can link to .mpo 3D image files; it’ll display them in 3D and allow you to save them to the SD card. It does not display the images in 3D inline in the page, though, and the 3D capabilities doesn’t extend beyond image files to other page elements.</p>

<p>Viewing 3D photos on the web is pretty cool though, I’ll admit. If you want to try out viewing 3D pictures on the web for yourself, head over to <a href="http://www.3dporch.com">3D Porch</a> where they have stacks of them waiting to be seen.</p>

<p>Interestingly, because .mpo and .jpg are both encoded using the standard jpeg format it seems that you can use them both in the same way. If you visit <a href="http://blog.norestfortheweekend.com/demos/3ds-browser-revisited/3ds-mpo.html">this little demo page I put together</a> you can see that most browsers are happy displaying .mpo files natively as well as .mpo files renamed as .jpgs. The 3DS browser will display both images on the page without a problem. Sadly they are in 2D, although if you click on them (they are linked to their original files) then the image is shown in 3D. This works for both the .mpo file and the .mpo renamed as a .jpg.</p>

<p>The browser doesn’t have Flash. This is no great loss, however, and with the 3DS’ weak battery life you can’t blame them for not wanting to include something that would drain it even more quickly than in most situations.</p>

<h3 id="getting-technical">Getting technical</h3>

<p>For some fairly technical details about the browser, <a href="http://www.3dsbuzz.com/nintendo-3ds-to-use-netfront-browser-supports-flash-and-html5/">3DS Buzz wrote it up at the bottom of this article</a>. I’ll attempt to filter some useful information out of that…</p>

<p>It is claimed that the browser supports HTML5 and CSS3 (partially in both cases). As such it isn’t much of a surprise that it doesn’t pass the <a href="http://acid3.acidtests.org/">Acid 3 test</a>. It is more of a surprise, however, that the 3DS does not even pass the <a href="http://acid2.acidtests.org/">Acid 2 test</a>. Don’t expect your pages to render perfectly (I’ve already had reports of pages not looking as they should).</p>

<p>The JavaScript engine is said to be “high speed” but it takes it’s sweet time to finish failing the Acid 3 test.</p>

<iframe width="628" height="628" src="http://www.youtube.com/embed/Ijv5TSGy1wY" frameborder="0" allowfullscreen=""></iframe>

<p>Here is the 3DS’ User Agent string:</p>

<pre><code>Mozilla/5.0 (Nintendo 3DS; U; ; en) Version/1.7412.EU
</code></pre>

<p>This is interesting for several reasons. </p>

<ol>
  <li>It doesn’t list the rendering engine or make any mention of NetFront	</li>
  <li>It DOES list the device name (not really that interesting, it’s just cool to see it)</li>
  <li>It’s fairly concise (it doesn’t come loaded with all the cruft you normally find in a UA string)</li>
  <li>It has the version number, but only for what appears to be the browser and not the system software</li>
</ol>

<p>Compare that UA string with the one of the version of Chrome I’m using right now:</p>

<pre><code>Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_7) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.91 Safari/534.30
</code></pre>

<p>Chrome’s is much longer and more verbose. You can see it not only contains the hardware but the system software version. It has the rendering engine and it’s version, the browser and it’s version and for the life of me I can’t think why but it also has a reference to Safari.</p>

<p>What’s odd to me about the 3DS’ UA string is the inclusion of the <code>.EU</code> on the end of the version number, right at the end. Does this mean that there’s an EU version of the browser that’s different from the browser they get in Japan and America? Why would they want to have to maintain multiple versions of the software? Will they use that user agent information to serve different content on Nintendo sites based on region? Probably not (but they could…).</p>

<h3 id="utilitarian">Utilitarian</h3>

<p>While I’m sure it’ll be fine for jumping onto GameFAQs to figure out how to beat that boss you’re stuck on, the 3DS browser is not going to set the world on fire like I hoped it might. I hope that not too many people got their hopes up about it, but if you did (like me) and are now feeling a little disappointed I feel your pain. At least it’s never going to gain a significant enough market share that we’ll ever have to worry about fixing broken sites in it… (famous last words).</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Webkit doesn't fire the load event on images]]></title>
    <link href="http://blog.norestfortheweekend.com/blog/2011/04/30/webkit-doesnt-fire-the-load-event-on-images/"/>
    <updated>2011-04-30T18:47:19+01:00</updated>
    <id>http://blog.norestfortheweekend.com/blog/2011/04/30/webkit-doesnt-fire-the-load-event-on-images</id>
    <content type="html"><![CDATA[<p>Well that’s not strictly true. The full headline reads something like this:</p>

<p><strong>Webkit doesn’t fire the <code>load</code> event on images when you change the <code>src</code> attribute and the new <code>src</code> is the same as the old</strong></p>

<h3 id="that-seems-reasonable">That seems reasonable</h3>

<p>That seems like reasonable behaviour. I mean, the image is already loaded. Changing the <code>src</code> attribute to it’s <em>current value</em> isn’t really changing it at all. It’s staying the same. If the <code>src</code> is the same and the image is already loaded, why fire the <code>load</code> event? You would only want to do that if the image was reloaded but doing that would be pointless as it’s already loaded. Loading it again would be a waste of bandwidth and make the experience feel slower; not what browser manufacturers are aiming for.</p>

<p>So what’s the big deal?</p>

<h3 id="inherently-lazy">Inherently lazy</h3>

<p>Developers like myself are inherently lazy. I don’t mean we’re workshy, but rather we always look for the easiest, cleanest solution to problems. This behaviour in WebKit fails twice on this count.</p>

<ol>
  <li>It’s inconsistent with other browsers. I have to work around it, potentially adding browser-specific code. That’s not good.</li>
  <li>It forces me to add extra code to cope with it’s specific requirements. Let me explain:</li>
</ol>

<p>If I was writing for a JS-guaranteed environment this wouldn’t be such a problem but I’m a conscientious sort of guy and realise that not everyone will have the benefits of a modern browser with all the options set to ‘awesome’. I want to cater for the JS-disadvantaged as well.</p>

<p>Let’s assume I’m writing a carousel for a photo slideshow that shows 4 pictures at a time. I want to show the first 4 pictures by default so that at least some content appears even for the non-JS users. Then, using non-intrusive JS I augment the slideshow to add next / previous buttons and the ability to click the image to enlarge it in a lightbox.</p>

<p>To avoid repeating a lot of code in a setup function that would also be present in the next/previous function I can write a single function to set the page of the carousel, setting up the images and their click events.</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>Carousel setup</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
<span class="line-number">13</span>
<span class="line-number">14</span>
<span class="line-number">15</span>
<span class="line-number">16</span>
<span class="line-number">17</span>
<span class="line-number">18</span>
<span class="line-number">19</span>
<span class="line-number">20</span>
<span class="line-number">21</span>
<span class="line-number">22</span>
<span class="line-number">23</span>
<span class="line-number">24</span>
<span class="line-number">25</span>
<span class="line-number">26</span>
<span class="line-number">27</span>
<span class="line-number">28</span>
<span class="line-number">29</span>
<span class="line-number">30</span>
</pre></td><td class="code"><pre><code class="javascript"><span class="line"><span class="kd">var</span> <span class="nx">picturesPerPage</span> <span class="o">=</span> <span class="mi">4</span><span class="p">,</span>
</span><span class="line">    <span class="nx">pictures</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#pictures img&#39;</span><span class="p">);</span>
</span><span class="line">
</span><span class="line"><span class="kd">var</span> <span class="nx">loadGalleryCarouselPage</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">pagenumber</span><span class="p">){</span>
</span><span class="line">    <span class="kd">var</span> <span class="nx">imageStart</span> <span class="o">=</span> <span class="nx">pagenumber</span><span class="o">*</span><span class="nx">picturesPerPage</span><span class="p">;</span>
</span><span class="line">    <span class="nx">pictures</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">i</span><span class="p">){</span>
</span><span class="line">        <span class="kd">var</span> <span class="nx">picture</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="nx">pictures</span><span class="p">[</span><span class="nx">i</span><span class="p">]),</span>
</span><span class="line">            <span class="nx">pictureContainer</span> <span class="o">=</span> <span class="nx">picture</span><span class="p">.</span><span class="nx">parent</span><span class="p">();</span>
</span><span class="line">        <span class="nx">picture</span><span class="p">.</span><span class="nx">hide</span><span class="p">();</span>
</span><span class="line">        <span class="k">if</span><span class="p">(</span><span class="nx">carouseldata</span><span class="p">.</span><span class="nx">images</span><span class="p">[</span><span class="nx">imageStart</span><span class="o">+</span><span class="nx">i</span><span class="p">]){</span>
</span><span class="line">            <span class="nx">picture</span><span class="p">.</span><span class="nx">show</span><span class="p">();</span>
</span><span class="line">            <span class="nx">picture</span><span class="p">.</span><span class="nx">bind</span><span class="p">(</span><span class="s1">&#39;load&#39;</span><span class="p">,</span><span class="kd">function</span><span class="p">(){</span>
</span><span class="line">                <span class="nx">pictureContainer</span><span class="p">.</span><span class="nx">removeClass</span><span class="p">(</span><span class="s1">&#39;loading&#39;</span><span class="p">);</span>
</span><span class="line">                <span class="nx">picture</span><span class="p">.</span><span class="nx">unbind</span><span class="p">(</span><span class="s1">&#39;load&#39;</span><span class="p">);</span>
</span><span class="line">            <span class="p">});</span>
</span><span class="line">            <span class="nx">pictureContainer</span><span class="p">.</span><span class="nx">addClass</span><span class="p">(</span><span class="s1">&#39;loading&#39;</span><span class="p">);</span>
</span><span class="line">            <span class="nx">picture</span><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s1">&#39;src&#39;</span><span class="p">,</span><span class="nx">carouseldata</span><span class="p">.</span><span class="nx">images</span><span class="p">[</span><span class="nx">imageStart</span><span class="o">+</span><span class="nx">i</span><span class="p">].</span><span class="nx">thumbnailurl</span><span class="p">);</span>
</span><span class="line">
</span><span class="line">            <span class="nx">picture</span><span class="p">.</span><span class="nx">unbind</span><span class="p">(</span><span class="s1">&#39;click&#39;</span><span class="p">);</span>
</span><span class="line">            <span class="nx">picture</span><span class="p">.</span><span class="nx">bind</span><span class="p">(</span><span class="s1">&#39;click&#39;</span><span class="p">,</span><span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">){</span>
</span><span class="line">                <span class="nx">e</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">();</span>
</span><span class="line">                <span class="nx">pictureLink</span><span class="p">.</span><span class="nx">fancybox</span><span class="p">({</span>
</span><span class="line">                    <span class="s2">&quot;href&quot;</span><span class="o">:</span> <span class="nx">carouseldata</span><span class="p">.</span><span class="nx">images</span><span class="p">[</span><span class="nx">imageStart</span><span class="o">+</span><span class="nx">i</span><span class="p">].</span><span class="nx">imageurl</span>
</span><span class="line">                <span class="p">});</span>
</span><span class="line">            <span class="p">});</span>
</span><span class="line">        <span class="p">}</span>
</span><span class="line">    <span class="p">});</span>
</span><span class="line"><span class="p">};</span>
</span><span class="line">
</span><span class="line"><span class="nx">loadGalleryCarouselPage</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>I’m using <a href="http://jquery.com/">JQuery</a> and <a href="http://fancybox.net/">Fancybox</a> for this example.</p>

<p>So what we have there is a function that loops over the four <code>img</code> tags, pulls information out of an array (<code>carouseldata</code>) based on the page offset passed as an argument, sets up click and load listeners and changes the image’s <code>src</code> attribute. This will work for any page at any time. In theory we could add a ‘jump to page’ option where the user could choose the page number to skip to. But we won’t.</p>

<p>This is especially handy as we can simply call <code>loadGalleryCarouselPage(0);</code> to set up the event listeners when the page first loads without having to duplicate most of the lines elsewhere. We even get a natty little loading spinner if we take advantage of the <code>loading</code> class that is set.</p>

<h3 id="making-things-difficult">Making things difficult</h3>

<p>When the page loads it’s a bit of a race. The results of this function varies between refreshes for me. If the image has not yet loaded when the JS runs then it works fine. If the image has already loaded, however, here’s what happens:</p>

<ol>
  <li>A <code>load</code> event listener is set	</li>
  <li>The <code>loading</code> class is applied which shows a spinner and hides the image</li>
  <li>The <code>src</code> of the <code>img</code> is set</li>
  <li>The <code>load</code> event DOES NOT FIRE in WebKit because the image is already loaded</li>
  <li>The picture remains hidden and the spinner keeps spinning even though the image is loaded</li>
</ol>

<p>And that is frustrating.</p>

<p>It’s an intermittent problem though, only when loading race conditions fail. Here’s another situation where it happens every time.</p>

<h3 id="the-dead-cert">The dead cert.</h3>

<p>The total number of images in the carousel doesn’t divide perfectly by four, so on the final page there are only two images showing. The final two of the four <code>img</code> elements are hidden from view. They are hidden rather than removed because:</p>

<ol>
  <li>They act as spacers so that other elements flow around them correctly</li>
  <li>The <code>img</code> tag needs to stay so that we can easily change the <code>src</code> attribute if the user navigates back to a page with 4 images on it.</li>
</ol>

<p>So say we’re on page 9 of 10 and click ‘Next’. Images 1 &amp; 2 are updated to show the final two pictures and images 3 &amp; 4 are hidden. Importantly: the <code>src</code> attributes of images 3 &amp; 4 don’t change. When we click ‘Previous’, images 1 &amp; 2 are changed back but 3 &amp; 4 are stuck with the loading spinner. That’s because, like before, the <code>src</code> was already set and it was equal to the new value.</p>

<h3 id="working-around-it">Working around it</h3>

<p>We could set the hidden images to a transparent .gif or .png instead of hiding them which would solve the second problem but because we want the images showing for non-JS users when the page loads we can’t use that technique to fix this. Also, downloading that extra image means extra bandwidth and latency times that we’d rather not have to deal with.</p>

<p>It turns out that setting the <code>src</code> to <code>''</code> (empty string) immediately before setting the image url will fix the problem. But! It causes the images (and consequently their container) to collapse to zero width and height in Firefox while the new images are loading which looks really bad if you’re trying to navigate a slideshow.</p>

<p>Here’s my solution:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>Carousel setup improved</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
<span class="line-number">13</span>
<span class="line-number">14</span>
<span class="line-number">15</span>
<span class="line-number">16</span>
<span class="line-number">17</span>
<span class="line-number">18</span>
<span class="line-number">19</span>
<span class="line-number">20</span>
<span class="line-number">21</span>
<span class="line-number">22</span>
<span class="line-number">23</span>
<span class="line-number">24</span>
<span class="line-number">25</span>
<span class="line-number">26</span>
<span class="line-number">27</span>
<span class="line-number">28</span>
<span class="line-number">29</span>
<span class="line-number">30</span>
<span class="line-number">31</span>
<span class="line-number">32</span>
<span class="line-number">33</span>
<span class="line-number">34</span>
<span class="line-number">35</span>
<span class="line-number">36</span>
<span class="line-number">37</span>
<span class="line-number">38</span>
</pre></td><td class="code"><pre><code class="javascript"><span class="line"><span class="kd">var</span> <span class="nx">picturesPerPage</span> <span class="o">=</span> <span class="mi">4</span><span class="p">,</span>
</span><span class="line">    <span class="nx">pictures</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#pictures img&#39;</span><span class="p">);</span>
</span><span class="line">
</span><span class="line"><span class="kd">var</span> <span class="nx">loadGalleryCarouselPage</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">pagenumber</span><span class="p">){</span>
</span><span class="line">    <span class="kd">var</span> <span class="nx">imageStart</span> <span class="o">=</span> <span class="nx">pagenumber</span><span class="o">*</span><span class="nx">picturesPerPage</span><span class="p">;</span>
</span><span class="line">    <span class="nx">pictures</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">i</span><span class="p">){</span>
</span><span class="line">        <span class="kd">var</span> <span class="nx">picture</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="nx">pictures</span><span class="p">[</span><span class="nx">i</span><span class="p">]),</span>
</span><span class="line">            <span class="nx">pictureContainer</span> <span class="o">=</span> <span class="nx">picture</span><span class="p">.</span><span class="nx">parent</span><span class="p">();</span>
</span><span class="line">        <span class="nx">picture</span><span class="p">.</span><span class="nx">hide</span><span class="p">();</span>
</span><span class="line">        <span class="k">if</span><span class="p">(</span><span class="nx">carouseldata</span><span class="p">.</span><span class="nx">images</span><span class="p">[</span><span class="nx">imageStart</span><span class="o">+</span><span class="nx">i</span><span class="p">]){</span>
</span><span class="line">            <span class="nx">picture</span><span class="p">.</span><span class="nx">show</span><span class="p">();</span>
</span><span class="line">            <span class="nx">picture</span><span class="p">.</span><span class="nx">bind</span><span class="p">(</span><span class="s1">&#39;load&#39;</span><span class="p">,</span><span class="kd">function</span><span class="p">(){</span>
</span><span class="line">                <span class="nx">pictureContainer</span><span class="p">.</span><span class="nx">removeClass</span><span class="p">(</span><span class="s1">&#39;loading&#39;</span><span class="p">);</span>
</span><span class="line">                <span class="nx">picture</span><span class="p">.</span><span class="nx">unbind</span><span class="p">(</span><span class="s1">&#39;load&#39;</span><span class="p">);</span>
</span><span class="line">            <span class="p">});</span>
</span><span class="line">            <span class="nx">pictureContainer</span><span class="p">.</span><span class="nx">addClass</span><span class="p">(</span><span class="s1">&#39;loading&#39;</span><span class="p">);</span>
</span><span class="line">            <span class="nx">picture</span><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s1">&#39;src&#39;</span><span class="p">,</span><span class="nx">carouseldata</span><span class="p">.</span><span class="nx">images</span><span class="p">[</span><span class="nx">imageStart</span><span class="o">+</span><span class="nx">i</span><span class="p">].</span><span class="nx">thumbnailurl</span><span class="p">);</span>
</span><span class="line">
</span><span class="line">            <span class="nx">picture</span><span class="p">.</span><span class="nx">unbind</span><span class="p">(</span><span class="s1">&#39;click&#39;</span><span class="p">);</span>
</span><span class="line">            <span class="nx">picture</span><span class="p">.</span><span class="nx">bind</span><span class="p">(</span><span class="s1">&#39;click&#39;</span><span class="p">,</span><span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">){</span>
</span><span class="line">                <span class="nx">e</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">();</span>
</span><span class="line">                <span class="nx">pictureLink</span><span class="p">.</span><span class="nx">fancybox</span><span class="p">({</span>
</span><span class="line">                    <span class="s2">&quot;href&quot;</span><span class="o">:</span> <span class="nx">carouseldata</span><span class="p">.</span><span class="nx">images</span><span class="p">[</span><span class="nx">imageStart</span><span class="o">+</span><span class="nx">i</span><span class="p">].</span><span class="nx">imageurl</span>
</span><span class="line">                <span class="p">});</span>
</span><span class="line">            <span class="p">});</span>
</span><span class="line">        <span class="p">}</span>
</span><span class="line">        <span class="k">else</span><span class="p">{</span>
</span><span class="line">            <span class="nx">picture</span><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s1">&#39;src&#39;</span><span class="p">,</span><span class="s1">&#39;&#39;</span><span class="p">);</span>
</span><span class="line">        <span class="p">}</span>
</span><span class="line">    <span class="p">});</span>
</span><span class="line"><span class="p">};</span>
</span><span class="line">
</span><span class="line"><span class="k">if</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">browser</span><span class="p">.</span><span class="nx">webkit</span><span class="p">){</span>
</span><span class="line">    <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#pictures img&#39;</span><span class="p">).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">i</span><span class="p">){</span>
</span><span class="line">        <span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">attr</span><span class="p">(</span><span class="s1">&#39;src&#39;</span><span class="p">,</span><span class="s1">&#39;&#39;</span><span class="p">);</span>
</span><span class="line">    <span class="p">});</span>
</span><span class="line"><span class="p">}</span>
</span><span class="line"><span class="nx">loadGalleryCarouselPage</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>I added an <code>else</code> so that if there aren’t enough pictures to fill all the <code>img</code> tags the <code>src</code> of the unused images is set to an empty string. There will always be at least one image on each page so there will always be an image at full height to prop up the carousel container while those hidden <code>img</code> tags are primed to receive more content.</p>

<p>I also added a little <code>if</code> block directly before initialising the carousel, at the bottom. If the browser is webkit-powered then it’ll loop over the <code>img</code> tags and prime them (set their <code>src</code> to empty) before initialisation. Because this is done using JS, non-JS users will still see the images.</p>

<h3 id="grumpy">Grumpy</h3>

<p>I’m grumpy about having to put in that extra, browser specific code. Setting the <code>src</code> to an empty string seems hacky. But it works and the logic is still clean and minimal. So it’ll do.</p>

<p>I hope that helps anyone having image loading javascript issues. And as usual I’d be interested to hear if you have any alternative / better solutions!</p>

<h3 id="footnotes">Footnotes</h3>

<p>Check out the carousel in action <a href="http://www.qkschool.org.uk">here</a>.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[CSS3 gradients, multiple backgrounds and IE7]]></title>
    <link href="http://blog.norestfortheweekend.com/blog/2011/02/26/css3-gradients-multiple-backgrounds-and-ie7/"/>
    <updated>2011-02-26T17:58:02+00:00</updated>
    <id>http://blog.norestfortheweekend.com/blog/2011/02/26/css3-gradients-multiple-backgrounds-and-ie7</id>
    <content type="html"><![CDATA[<p>You know how, according to the W3C, <a href="http://www.w3.org/TR/CSS21/syndata.html#parsing-errors">CSS selectors that are not understood should be ignored, without error</a>? IE7 doesn’t do that 100% of the time.</p>

<h3 id="how-dare-it">How dare it</h3>

<p>That’s right. Just when you thought you had a nice system in place IE comes along and stomps all over it. I’m sure more and more people will come up against this as they start using CSS gradients in earnest. I can see it being quite a common situation, too. I have two background images: one, a CSS generated gradient and two, an image to be laid over the top of it. A nice shiny button with an icon, for example.</p>

<p><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2011/02/button.png" width="142" height="38" title="'A button that says Register now and has a gradient and a separate icon for the background'" /></p>

<p>We know that certain browsers can’t render gradients and so we define the background to initially be just a solid colour with the icon image (the users of the older browsers will never miss what they didn’t know was there). Then we go on to define the styles for the modern browsers. These styles use the same selector (<code>background-image</code>) so they will override the initial declaration but according to the rules, browsers that don’t understand the gradient instructions will just ignore the whole declaration leaving us with just the initial icon for the background.</p>

<p>As we know, the backgrounds will appear top down from the order you specify them so we specify the icon first and then the gradient, otherwise the gradient would obscure the icon.</p>

<p>We also define the background-position twice. This is so we can position the gradient+icon background differently from the icon on it’s own. Browsers that don’t support multiple backgrounds should not see this syntax as valid and should ignore it.</p>

<p>Here’s the code:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>HTML</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
</pre></td><td class="code"><pre><code class="html"><span class="line"><span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;#&quot;</span> <span class="na">class=</span><span class="s">&quot;mybutton&quot;</span><span class="nt">&gt;</span>Register now<span class="nt">&lt;/a&gt;</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>CSS    </span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
<span class="line-number">13</span>
<span class="line-number">14</span>
<span class="line-number">15</span>
<span class="line-number">16</span>
<span class="line-number">17</span>
<span class="line-number">18</span>
<span class="line-number">19</span>
<span class="line-number">20</span>
<span class="line-number">21</span>
<span class="line-number">22</span>
<span class="line-number">23</span>
<span class="line-number">24</span>
<span class="line-number">25</span>
<span class="line-number">26</span>
<span class="line-number">27</span>
<span class="line-number">28</span>
</pre></td><td class="code"><pre><code class="css"><span class="line"><span class="nc">.mybutton</span><span class="p">{</span>
</span><span class="line">	<span class="k">background-image</span><span class="o">:</span> <span class="sx">url(icon.png)</span><span class="p">;</span>
</span><span class="line">	<span class="k">background-image</span><span class="o">:</span> <span class="sx">url(icon.png)</span><span class="o">,</span>
</span><span class="line">		<span class="o">-</span><span class="n">webkit</span><span class="o">-</span><span class="n">gradient</span><span class="p">(</span>
</span><span class="line">			<span class="n">linear</span><span class="o">,</span>
</span><span class="line">			<span class="k">left</span> <span class="k">bottom</span><span class="o">,</span>
</span><span class="line">			<span class="k">left</span> <span class="k">top</span><span class="o">,</span>
</span><span class="line">			<span class="k">color</span><span class="o">-</span><span class="n">stop</span><span class="p">(</span><span class="m">0</span><span class="o">,</span> <span class="k">rgb</span><span class="p">(</span><span class="m">233</span><span class="o">,</span> <span class="m">233</span><span class="o">,</span> <span class="m">233</span><span class="p">))</span><span class="o">,</span>
</span><span class="line">			<span class="k">color</span><span class="o">-</span><span class="n">stop</span><span class="p">(</span><span class="m">0</span><span class="o">.</span><span class="m">5</span><span class="o">,</span> <span class="k">rgb</span><span class="p">(</span><span class="m">249</span><span class="o">,</span> <span class="m">249</span><span class="o">,</span> <span class="m">249</span><span class="p">))</span><span class="o">,</span>
</span><span class="line">			<span class="k">color</span><span class="o">-</span><span class="n">stop</span><span class="p">(</span><span class="m">0</span><span class="o">.</span><span class="m">5</span><span class="o">,</span> <span class="k">rgb</span><span class="p">(</span><span class="m">255</span><span class="o">,</span> <span class="m">255</span><span class="o">,</span> <span class="m">255</span><span class="p">))</span><span class="o">,</span>
</span><span class="line">			<span class="k">color</span><span class="o">-</span><span class="n">stop</span><span class="p">(</span><span class="m">1</span><span class="o">,</span> <span class="k">rgb</span><span class="p">(</span><span class="m">255</span><span class="o">,</span> <span class="m">255</span><span class="o">,</span> <span class="m">255</span><span class="p">))</span>
</span><span class="line">		<span class="p">);</span>
</span><span class="line">	<span class="k">background-image</span><span class="o">:</span> <span class="sx">url(icon.png)</span><span class="o">,</span>
</span><span class="line">		<span class="o">-</span><span class="n">moz</span><span class="o">-</span><span class="n">linear</span><span class="o">-</span><span class="n">gradient</span><span class="p">(</span>
</span><span class="line">			<span class="k">center</span> <span class="k">bottom</span><span class="o">,</span>
</span><span class="line">			<span class="k">rgb</span><span class="p">(</span><span class="m">233</span><span class="o">,</span> <span class="m">233</span><span class="o">,</span> <span class="m">233</span><span class="p">)</span> <span class="m">0</span><span class="o">%,</span>
</span><span class="line">			<span class="k">rgb</span><span class="p">(</span><span class="m">249</span><span class="o">,</span> <span class="m">249</span><span class="o">,</span> <span class="m">249</span><span class="p">)</span> <span class="m">50</span><span class="o">%,</span>
</span><span class="line">			<span class="k">rgb</span><span class="p">(</span><span class="m">255</span><span class="o">,</span><span class="m">255</span><span class="o">,</span><span class="m">255</span><span class="p">)</span> <span class="m">50</span><span class="o">%,</span>
</span><span class="line">			<span class="k">rgb</span><span class="p">(</span><span class="m">255</span><span class="o">,</span><span class="m">255</span><span class="o">,</span><span class="m">255</span><span class="p">)</span> <span class="m">100</span><span class="o">%</span>
</span><span class="line">		<span class="p">);</span>
</span><span class="line">
</span><span class="line">	<span class="k">background-position</span><span class="o">:</span> <span class="m">5px</span> <span class="k">center</span><span class="p">;</span>
</span><span class="line">	<span class="k">background-position</span><span class="o">:</span> <span class="m">5px</span> <span class="k">center</span><span class="o">,</span> <span class="k">left</span> <span class="k">top</span><span class="p">;</span>
</span><span class="line">
</span><span class="line">	<span class="k">background-repeat</span><span class="o">:</span> <span class="k">no-repeat</span><span class="p">;</span>
</span><span class="line">
</span><span class="line">	<span class="k">padding-left</span><span class="o">:</span> <span class="m">30px</span><span class="p">;</span>
</span><span class="line"><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>Here it is in Firefox:  </p>

<p><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2011/02/example1-ff.png" width="142" height="38" title="'Styles are working well in Firefox'" /></p>

<p>And in IE7:  </p>

<p><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2011/02/example1-ie.png" width="142" height="38" title="'The icon on the button is missing in IE'" /></p>

<p>Or you can <a href="http://blog.norestfortheweekend.com/demos/css3-gradients-multiple-backgrounds-and-ie7/example1.html">see it for yourself in your browser</a>.</p>

<p>It seems that IE is not behaving as we might expect. It’s not showing the gradient (expected) but it’s not failing back to just showing the icon either. A quick look at the IE developer toolbar (in IE9, IE7 mode; the IE7 dev toolbar would leave you stumped) shows us why:</p>

<p><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2011/02/example1-ie-inspector.png" width="692" height="100" title="'Screenshot of the IE developer toolbar showing that IE has picked up and is trying to use styles it can't understand'" /></p>

<p>It’s picked up the background image declaration that includes a gradient. In this case it’s the Mozilla-specific gradient and the reason it’s this one and not the Webkit one is that we are defining the Mozilla one last. If they were defined the other way around it would have picked up the Webkit one instead.</p>

<h3 id="why-oh-why">Why? Oh why??</h3>

<p>I’m no expert on how IE parses CSS but I would presume it’s something like IE recognises the URL part just fine and when it reaches the closing parenthesis it figures that’s it and all’s well. Maybe not. Whatever, for some reason it thinks it’s a valid declaration, scoops up the whole lot gradient and all and tries to render it. And fails.</p>

<h3 id="thats-annoying">That’s annoying</h3>

<p>Yes it is.</p>

<h3 id="the-fix">The fix</h3>

<p>Importantly, IE correctly recognises the <code>background-image</code> declaration as invalid (for itself) if it starts with a gradient, even if it contains a regular image later on. So we just start the declaration with a gradient. The trouble is, we don’t want to put the gradient first as it’ll obscure the icon, so we define <em>another</em> gradient that is OK to put on top of the icon. That would be an empty or transparent gradient.</p>

<p>We will use the minimum amount of code that is necessary to trigger a gradient in the rendering engine. For Webkit, it is <code>-webkit-gradient(linear, left bottom, left top)</code>. No <code>color-stop</code>s required. This is good because no colour means no visible gradient. For Mozilla, it requires some colour information, so we just give it completely transparent colours using <code>rgba</code>: <code>-moz-linear-gradient(center bottom, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 0%)</code>.</p>

<p>Putting these gradients first mean that IE7 won’t incorrectly think it can render that style and so it’ll stick with just the icon.</p>

<p><strong>Important: Because we now have 3 background images, we also need to declare a third value for background-position.</strong></p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>CSS    </span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
<span class="line-number">13</span>
<span class="line-number">14</span>
<span class="line-number">15</span>
<span class="line-number">16</span>
<span class="line-number">17</span>
<span class="line-number">18</span>
<span class="line-number">19</span>
<span class="line-number">20</span>
<span class="line-number">21</span>
<span class="line-number">22</span>
<span class="line-number">23</span>
<span class="line-number">24</span>
<span class="line-number">25</span>
<span class="line-number">26</span>
<span class="line-number">27</span>
<span class="line-number">28</span>
<span class="line-number">29</span>
</pre></td><td class="code"><pre><code class="css"><span class="line"><span class="nc">.mybutton</span><span class="p">{</span>
</span><span class="line">	<span class="k">background-image</span><span class="o">:</span> <span class="sx">url(icon.png)</span><span class="p">;</span>
</span><span class="line">	<span class="k">background-image</span><span class="o">:</span> <span class="o">-</span><span class="n">webkit</span><span class="o">-</span><span class="n">gradient</span><span class="p">(</span><span class="n">linear</span><span class="o">,</span> <span class="k">left</span> <span class="k">bottom</span><span class="o">,</span> <span class="k">left</span> <span class="k">top</span><span class="p">)</span><span class="o">,</span>
</span><span class="line">		<span class="sx">url(icon.png)</span><span class="o">,</span>
</span><span class="line">		<span class="o">-</span><span class="n">webkit</span><span class="o">-</span><span class="n">gradient</span><span class="p">(</span>
</span><span class="line">			<span class="n">linear</span><span class="o">,</span>
</span><span class="line">			<span class="k">left</span> <span class="k">bottom</span><span class="o">,</span>
</span><span class="line">			<span class="k">left</span> <span class="k">top</span><span class="o">,</span>
</span><span class="line">			<span class="k">color</span><span class="o">-</span><span class="n">stop</span><span class="p">(</span><span class="m">0</span><span class="o">,</span> <span class="k">rgb</span><span class="p">(</span><span class="m">233</span><span class="o">,</span> <span class="m">233</span><span class="o">,</span> <span class="m">233</span><span class="p">))</span><span class="o">,</span>
</span><span class="line">			<span class="k">color</span><span class="o">-</span><span class="n">stop</span><span class="p">(</span><span class="m">0</span><span class="o">.</span><span class="m">5</span><span class="o">,</span> <span class="k">rgb</span><span class="p">(</span><span class="m">249</span><span class="o">,</span> <span class="m">249</span><span class="o">,</span> <span class="m">249</span><span class="p">))</span><span class="o">,</span>
</span><span class="line">			<span class="k">color</span><span class="o">-</span><span class="n">stop</span><span class="p">(</span><span class="m">0</span><span class="o">.</span><span class="m">5</span><span class="o">,</span> <span class="k">rgb</span><span class="p">(</span><span class="m">255</span><span class="o">,</span> <span class="m">255</span><span class="o">,</span> <span class="m">255</span><span class="p">))</span><span class="o">,</span>
</span><span class="line">			<span class="k">color</span><span class="o">-</span><span class="n">stop</span><span class="p">(</span><span class="m">1</span><span class="o">,</span> <span class="k">rgb</span><span class="p">(</span><span class="m">255</span><span class="o">,</span> <span class="m">255</span><span class="o">,</span> <span class="m">255</span><span class="p">))</span>
</span><span class="line">		<span class="p">);</span>
</span><span class="line">	<span class="k">background-image</span><span class="o">:</span> <span class="o">-</span><span class="n">moz</span><span class="o">-</span><span class="n">linear</span><span class="o">-</span><span class="n">gradient</span><span class="p">(</span><span class="k">center</span> <span class="k">bottom</span><span class="o">,</span> <span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">0</span><span class="o">%,</span> <span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">0</span><span class="o">%</span><span class="p">)</span><span class="o">,</span>
</span><span class="line">		<span class="sx">url(icon.png)</span><span class="o">,</span>
</span><span class="line">		<span class="o">-</span><span class="n">moz</span><span class="o">-</span><span class="n">linear</span><span class="o">-</span><span class="n">gradient</span><span class="p">(</span>
</span><span class="line">			<span class="k">center</span> <span class="k">bottom</span><span class="o">,</span>
</span><span class="line">			<span class="k">rgb</span><span class="p">(</span><span class="m">233</span><span class="o">,</span> <span class="m">233</span><span class="o">,</span> <span class="m">233</span><span class="p">)</span> <span class="m">0</span><span class="o">%,</span>
</span><span class="line">			<span class="k">rgb</span><span class="p">(</span><span class="m">249</span><span class="o">,</span> <span class="m">249</span><span class="o">,</span> <span class="m">249</span><span class="p">)</span> <span class="m">50</span><span class="o">%,</span>
</span><span class="line">			<span class="k">rgb</span><span class="p">(</span><span class="m">255</span><span class="o">,</span><span class="m">255</span><span class="o">,</span><span class="m">255</span><span class="p">)</span> <span class="m">50</span><span class="o">%,</span>
</span><span class="line">			<span class="k">rgb</span><span class="p">(</span><span class="m">255</span><span class="o">,</span><span class="m">255</span><span class="o">,</span><span class="m">255</span><span class="p">)</span> <span class="m">100</span><span class="o">%</span>
</span><span class="line">		<span class="p">);</span>
</span><span class="line">
</span><span class="line">	<span class="k">background-repeat</span><span class="o">:</span> <span class="k">no-repeat</span><span class="p">;</span>
</span><span class="line">	<span class="k">background-position</span><span class="o">:</span> <span class="m">5px</span> <span class="k">center</span><span class="p">;</span>
</span><span class="line">	<span class="k">background-position</span><span class="o">:</span> <span class="k">left</span> <span class="k">top</span><span class="o">,</span> <span class="m">5px</span> <span class="k">center</span><span class="o">,</span> <span class="k">left</span> <span class="k">top</span><span class="p">;</span>
</span><span class="line">
</span><span class="line">	<span class="k">padding-left</span><span class="o">:</span> <span class="m">30px</span><span class="p">;</span>
</span><span class="line"><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>Here it is in Firefox:  </p>

<p><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2011/02/example2-ff.png" width="142" height="38" title="'The styles are working well in Firefox'" /></p>

<p>And in IE7:  </p>

<p><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2011/02/example2-ie.png" width="142" height="38" title="'The styles are working well in IE7'" /></p>

<p>Or you can <a href="http://blog.norestfortheweekend.com/demos/css3-gradients-multiple-backgrounds-and-ie7/example2.html">see it for yourself in your browser</a>.</p>

<h3 id="but-wait-theres-more">But wait, there’s more!</h3>

<p>You thought this was over? Of course it’s not! IE9 is a heck of a lot better than previous versions but it’s still not perfect. For example, it does support multiple backgrounds but it doesn’t support CSS gradients. This means that it’ll ignore the gradients but it’ll use the <code>background-position</code> multiple background declaration we made, resulting in the icon being positioned <code>left top</code> as opposed to <code>5px center</code>.</p>

<p><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2011/02/example2-ie9.png" width="142" height="38" title="'The styles have regressed in IE9 and the icon is incorrectly aligned'" /></p>

<p>I tried getting around this by inserting another <code>background-image</code> defining three images (two of them transparent spacers) directly after the first <code>background-image</code> and before the first gradient:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>CSS    </span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
<span class="line-number">13</span>
<span class="line-number">14</span>
<span class="line-number">15</span>
<span class="line-number">16</span>
<span class="line-number">17</span>
<span class="line-number">18</span>
<span class="line-number">19</span>
<span class="line-number">20</span>
<span class="line-number">21</span>
<span class="line-number">22</span>
<span class="line-number">23</span>
<span class="line-number">24</span>
<span class="line-number">25</span>
<span class="line-number">26</span>
<span class="line-number">27</span>
<span class="line-number">28</span>
<span class="line-number">29</span>
<span class="line-number">30</span>
<span class="line-number">31</span>
<span class="line-number">32</span>
</pre></td><td class="code"><pre><code class="css"><span class="line"><span class="nc">.mybutton</span><span class="p">{</span>
</span><span class="line">	<span class="k">background-image</span><span class="o">:</span> <span class="sx">url(icon.png)</span><span class="p">;</span>
</span><span class="line">	<span class="k">background-image</span><span class="o">:</span> <span class="sx">url(spacer.gif)</span><span class="o">,</span>
</span><span class="line">		<span class="sx">url(icon.png)</span><span class="o">,</span>
</span><span class="line">		<span class="sx">url(spacer.gif)</span><span class="p">;</span>
</span><span class="line">	<span class="k">background-image</span><span class="o">:</span> <span class="o">-</span><span class="n">webkit</span><span class="o">-</span><span class="n">gradient</span><span class="p">(</span><span class="n">linear</span><span class="o">,</span> <span class="k">left</span> <span class="k">bottom</span><span class="o">,</span> <span class="k">left</span> <span class="k">top</span><span class="p">)</span><span class="o">,</span>
</span><span class="line">		<span class="sx">url(icon.png)</span><span class="o">,</span>
</span><span class="line">		<span class="o">-</span><span class="n">webkit</span><span class="o">-</span><span class="n">gradient</span><span class="p">(</span>
</span><span class="line">			<span class="n">linear</span><span class="o">,</span>
</span><span class="line">			<span class="k">left</span> <span class="k">bottom</span><span class="o">,</span>
</span><span class="line">			<span class="k">left</span> <span class="k">top</span><span class="o">,</span>
</span><span class="line">			<span class="k">color</span><span class="o">-</span><span class="n">stop</span><span class="p">(</span><span class="m">0</span><span class="o">,</span> <span class="k">rgb</span><span class="p">(</span><span class="m">233</span><span class="o">,</span> <span class="m">233</span><span class="o">,</span> <span class="m">233</span><span class="p">))</span><span class="o">,</span>
</span><span class="line">			<span class="k">color</span><span class="o">-</span><span class="n">stop</span><span class="p">(</span><span class="m">0</span><span class="o">.</span><span class="m">5</span><span class="o">,</span> <span class="k">rgb</span><span class="p">(</span><span class="m">249</span><span class="o">,</span> <span class="m">249</span><span class="o">,</span> <span class="m">249</span><span class="p">))</span><span class="o">,</span>
</span><span class="line">			<span class="k">color</span><span class="o">-</span><span class="n">stop</span><span class="p">(</span><span class="m">0</span><span class="o">.</span><span class="m">5</span><span class="o">,</span> <span class="k">rgb</span><span class="p">(</span><span class="m">255</span><span class="o">,</span> <span class="m">255</span><span class="o">,</span> <span class="m">255</span><span class="p">))</span><span class="o">,</span>
</span><span class="line">			<span class="k">color</span><span class="o">-</span><span class="n">stop</span><span class="p">(</span><span class="m">1</span><span class="o">,</span> <span class="k">rgb</span><span class="p">(</span><span class="m">255</span><span class="o">,</span> <span class="m">255</span><span class="o">,</span> <span class="m">255</span><span class="p">))</span>
</span><span class="line">		<span class="p">);</span>
</span><span class="line">	<span class="k">background-image</span><span class="o">:</span> <span class="o">-</span><span class="n">moz</span><span class="o">-</span><span class="n">linear</span><span class="o">-</span><span class="n">gradient</span><span class="p">(</span><span class="k">center</span> <span class="k">bottom</span><span class="o">,</span> <span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">0</span><span class="o">%,</span> <span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="o">,</span><span class="m">0</span><span class="p">)</span> <span class="m">0</span><span class="o">%</span><span class="p">)</span><span class="o">,</span>
</span><span class="line">		<span class="sx">url(icon.png)</span><span class="o">,</span>
</span><span class="line">		<span class="o">-</span><span class="n">moz</span><span class="o">-</span><span class="n">linear</span><span class="o">-</span><span class="n">gradient</span><span class="p">(</span>
</span><span class="line">			<span class="k">center</span> <span class="k">bottom</span><span class="o">,</span>
</span><span class="line">			<span class="k">rgb</span><span class="p">(</span><span class="m">233</span><span class="o">,</span> <span class="m">233</span><span class="o">,</span> <span class="m">233</span><span class="p">)</span> <span class="m">0</span><span class="o">%,</span>
</span><span class="line">			<span class="k">rgb</span><span class="p">(</span><span class="m">249</span><span class="o">,</span> <span class="m">249</span><span class="o">,</span> <span class="m">249</span><span class="p">)</span> <span class="m">50</span><span class="o">%,</span>
</span><span class="line">			<span class="k">rgb</span><span class="p">(</span><span class="m">255</span><span class="o">,</span><span class="m">255</span><span class="o">,</span><span class="m">255</span><span class="p">)</span> <span class="m">50</span><span class="o">%,</span>
</span><span class="line">			<span class="k">rgb</span><span class="p">(</span><span class="m">255</span><span class="o">,</span><span class="m">255</span><span class="o">,</span><span class="m">255</span><span class="p">)</span> <span class="m">100</span><span class="o">%</span>
</span><span class="line">		<span class="p">);</span>
</span><span class="line">
</span><span class="line">	<span class="k">background-repeat</span><span class="o">:</span> <span class="k">no-repeat</span><span class="p">;</span>
</span><span class="line">	<span class="k">background-position</span><span class="o">:</span> <span class="m">5px</span> <span class="k">center</span><span class="p">;</span>
</span><span class="line">	<span class="k">background-position</span><span class="o">:</span> <span class="k">left</span> <span class="k">top</span><span class="o">,</span> <span class="m">5px</span> <span class="k">center</span><span class="o">,</span> <span class="k">left</span> <span class="k">top</span><span class="p">;</span>
</span><span class="line">
</span><span class="line">	<span class="k">padding-left</span><span class="o">:</span> <span class="m">30px</span><span class="p">;</span>
</span><span class="line"><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>But that didn’t work as IE7 still parsed it (incorrectly) just as it did in the first instance and therefore didn’t show the icon at all. Back to square one.</p>

<p>At this point I’m sure most people are thinking</p>

<p>“Oh come on, why not just use <a href="http://www.modernizr.com/">Modernizr</a> and only apply the gradients to browsers that can use them?”</p>

<p>That’s one way of doing it, although I would rather not use JavaScript if possible. This leaves one option… go back to the original CSS and add this conditional comment in the <code>&lt;head&gt;</code>:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>Conditional Comment</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
</pre></td><td class="code"><pre><code class="html"><span class="line"><span class="c">&lt;!--[if IE]&gt;</span>
</span><span class="line"><span class="c">    &lt;style type=&quot;text/css&quot; media=&quot;screen&quot;&gt;</span>
</span><span class="line"><span class="c">        .mybutton{</span>
</span><span class="line"><span class="c">            background-image: url(icon.png);</span>
</span><span class="line"><span class="c">            background-position: 5px center;</span>
</span><span class="line"><span class="c">        }</span>
</span><span class="line"><span class="c">    &lt;/style&gt;</span>
</span><span class="line"><span class="c">&lt;![endif]--&gt;</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>As no versions of IE yet support gradients, we just reset the background to be the plain ol’ icon. Problem solved.</p>

<p>Here it is in Firefox:  </p>

<p><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2011/02/example3-ff.png" width="142" height="38" title="'The styles are working well in Firefox'" /></p>

<p>And in Webkit (Chrome):  </p>

<p><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2011/02/example3-ch.png" width="142" height="38" title="'The styles are working well in Chrome'" /></p>

<p>And in Opera:  </p>

<p><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2011/02/example3-op.png" width="142" height="38" title="'The styles are working well in Opera'" /></p>

<p>And in IE6:  </p>

<p><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2011/02/example3-ie6.png" width="142" height="38" title="'The styles are working well in IE6'" /></p>

<p>And in IE7:  </p>

<p><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2011/02/example3-ie7.png" width="142" height="38" title="'The styles are working well in IE7'" /></p>

<p>And in IE8:  </p>

<p><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2011/02/example3-ie8.png" width="142" height="38" title="'The styles are working well in IE8'" /></p>

<p>And in IE9:  </p>

<p><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2011/02/example3-ie9.png" width="142" height="38" title="'The styles are working well in IE9'" /></p>

<p>Or you can <a href="http://blog.norestfortheweekend.com/demos/css3-gradients-multiple-backgrounds-and-ie7/example3.html">see it for yourself in your browser</a>.</p>

<h3 id="a-side-serving-of-gradient">A side serving of gradient</h3>

<p>You may have noticed that two of the <code>color-stop</code>s have the same percentage/distance value. This effectively give us the ability to have more than one gradient on the same element. The end result is a gradient from the top to the middle, a sudden stop and change of colour and another gradient from the middle to the bottom. It’s useful to be able to change sharply from one colour to another as well as smoothly!</p>

<h3 id="footnotes">Footnotes</h3>

<ul>
  <li>If anyone has a better solution, please get in touch in the comments or on Twitter.</li>
  <li>The images I’ve used come directly from the project I’m working on in my day job. If my employer has any objection to their use here I will of course replace them with something else. But I’m sure they won’t.</li>
</ul>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[The Web in 3D - the Nintendo 3DS web browser]]></title>
    <link href="http://blog.norestfortheweekend.com/blog/2011/02/14/the-web-in-3d-the-nintendo-3ds-web-browser/"/>
    <updated>2011-02-14T01:45:49+00:00</updated>
    <id>http://blog.norestfortheweekend.com/blog/2011/02/14/the-web-in-3d-the-nintendo-3ds-web-browser</id>
    <content type="html"><![CDATA[<p>Last Sunday my wife and I went and had a sneaky preview of the new games console from Nintendo: the <a href="http://www.nintendo.com/3ds">3DS</a>.</p>

<p><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2011/02/nintendo3dswithpen.png" width="455" height="384" title="'The Nintendo 3DS'" /></p>

<p>Let’s not beat around the bush: this is a very impressive device. It’s tricked out with all the latest technologies (or the latest applications of ‘old’ technologies, wherever you choose to draw the line). The thing people are really talking about, of course, is the 3D aspect of it. I’m sure you have read about it - the top screen is a 3D display which importantly doesn’t require glasses. I can’t stress enough how good the 3D effect looked. It felt completely natural and I didn’t find myself getting any kind of a headache or nausea like some people are worried about.</p>

<p>There were demos available of most of the functionality: Lots of games that’ll be available on launch or shortly thereafter, 3D photography, augmented reality (including the ‘reality’ part shown in 3D due to the 3D cameras on the lid - the most impressive thing for me) and street pass (Nintendo’s social discovery system). But the thing that actually holds the <em>most</em> interest for me <em>wasn’t</em> shown and indeed is barely talked about. I’m hoping that will change.</p>

<h3 id="a-complex-web">A complex web</h3>

<p>I’m talking, of course, about the web browser which will come built in to the device as part of the extensive suit of software bundled on-board.</p>

<p>*YAWN*</p>

<p>A web browser? What’s so great about that?</p>

<p>I don’t know yet because no-one is talking about it, but I’m <em>hoping</em> it will inspire (even more) innovation and creativity on the web. I’m hoping it will have some semblance of 3D integration and capability. And if not, why not? Surely this is the way the web is going. More and more devices will be 3D enabled in the near future and you can bet that if the 3DS doesn’t kick-start the 3D web some other device will. You can buy a 3D TV to put in your living room for crying out loud - this is 2011! They reckon you’ll be able to buy a <a href="http://news.bbc.co.uk/1/hi/programmes/click_online/9393762.stm">HOLOGRAPHIC 3D TV</a> in 2012. I’m all over that. And I want the web to make sure it isn’t left behind. After all, a lot of modern TVs have integrated browsers. It’s the next logical step.</p>

<h3 id="least-they-could-do">Least they could do</h3>

<p>The least I could hope for is support for 3D images displayed in web pages. The <strong>LEAST</strong>. The standard open format is <a href="http://en.wikipedia.org/wiki/Image_file_formats#MPO">.mpo</a> and fortunately <a href="http://nintendo3dsblog.com/the-3d-camera-in-the-nintendo-3ds-saves-photos-in-the-open-mpo-file-format">the same format in which the 3DS saves it’s 3D photos</a>.</p>

<p>That’s not to say you will be able to simply embed the 3D photos in your site and have them work in the 3DS’ web browser though. Think how that would look in a desktop browser… Well it probably wouldn’t show up or show a broken image.</p>

<p>No, no, no, don’t even think about making a separate site for 3D devices. I thought we were past all that. What are you going to have yet another separate site for 3D+Mobile? We want to serve one page that works on all devices.</p>

<p>The trouble is, without images having a similar failover pattern to the one available to <a href="http://dev.opera.com/articles/view/everything-you-need-to-know-about-html5-video-and-audio/">video and audio in HTML5</a>, you simply couldn’t use the image inline in your page as non-3D-enabled browsers wouldn’t recognise the format. This just proves that there are always new image formats emerging; they are not all supported by all browsers as it’s easy to assume (if you forget about IE6 and .png’s) so why should we assume that that’s the case with the markup?</p>

<p><a href="http://www.brucelawson.co.uk/2010/why-video-audio-canvas-arent-self-closing-tags/">This has been discussed by Bruce Lawson</a> and makes sense (no matter how frustrating it is). So until all browsers support the display of 3D images on 2D screens we will have to find another way.</p>

<p>The other way to include images in the page is, of course, CSS background images. This one has legs. The 3DS browser could easily respond to an @media query, something like <code>@media screen and (-3ds-min-device-spatial-dimensions: 3) { ... }</code>. Then you could alter how the page looks on a device that has 3D capabilities. Once you have the 3D background image in place you can mark it up to include a 2D version for the rest of the world:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>HTML    </span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
</pre></td><td class="code"><pre><code class="html"><span class="line"><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;forest-picture&quot;</span><span class="nt">&gt;</span>
</span><span class="line">    <span class="nt">&lt;img</span> <span class="na">src=</span><span class="s">&quot;/static/img/forest-2d.jpg&quot;</span> <span class="na">alt=</span><span class="s">&quot;Pretty forest scene&quot;</span> <span class="na">height=</span><span class="s">&quot;250&quot;</span> <span class="na">width=</span><span class="s">&quot;400&quot;</span><span class="nt">&gt;&lt;/img&gt;</span>
</span><span class="line"><span class="nt">&lt;/div&gt;</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>CSS    </span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
</pre></td><td class="code"><pre><code class="css"><span class="line"><span class="k">@media</span> <span class="nt">screen</span> <span class="nt">and</span> <span class="o">(</span><span class="nt">-3ds-min-device-spatial-dimensions</span><span class="o">:</span> <span class="nt">3</span><span class="o">)</span> <span class="p">{</span>
</span><span class="line">    <span class="nc">.forest-picture</span><span class="p">{</span>
</span><span class="line">        <span class="k">background</span><span class="o">:</span> <span class="k">transparent</span> <span class="sx">url(../img/forest-3d.mpo)</span> <span class="k">no-repeat</span> <span class="m">0</span> <span class="m">0</span><span class="p">;</span>
</span><span class="line">        <span class="k">width</span><span class="o">:</span> <span class="m">400px</span><span class="p">;</span>
</span><span class="line">        <span class="k">height</span><span class="o">:</span> <span class="m">250px</span><span class="p">;</span>
</span><span class="line">    <span class="p">}</span>
</span><span class="line">    <span class="nc">.forest-picture</span> <span class="nt">img</span><span class="p">{</span>
</span><span class="line">        <span class="k">display</span><span class="o">:</span> <span class="k">none</span><span class="p">;</span>
</span><span class="line">    <span class="p">}</span>
</span><span class="line"><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>The best of both worlds! We can dream…</p>

<h3 id="reality-check">Reality check</h3>

<p>Before we go on, I just need to make it abundantly clear (if it isn’t already) that this article is pure speculation. I don’t know if the 3DS browser supports any of this kind of stuff, but imagining the possibilities and how they might work is an interesting exercise. Oh wait, it looks like <a href="http://www.google.com/intl/en/landing/chrome/cadie/">Google has already looked into 3D browsing</a>. My mistake ;)</p>

<p>Let’s explore further down the rabbit hole…</p>

<h3 id="going-the-extra-dimension">Going the extra dimension</h3>

<p>What if we wanted to move beyond just sticking 3D images in our pages? As awesome as a 3D gallery might be, there are so many more possibilities. Imagine if the whole page could be rendered in 3D; if each element on the page had it’s own depth setting. I think the most obvious thing to do would be to push the background actually into the background giving the site content more prominence, and if you start down that road you should just be able to let your imagination carry you forwards.</p>

<p>I know what you’re thinking, and it’s what I thought at first too… why not use <code>z-index</code> for that? The reason why not is because <code>z-index</code> controls the stacking order of elements on a single plane. If you change the function of <code>z-index</code> to control depth on 3D devices, how would you re-order a group of elements sharing the same depth on a 3D page? It’s clear that we need a separate property to do that. I’m going to be bold and use <code>depth</code> in examples, for want of a better attribute name.</p>

<p>So where are we? We’ve got 3D images and the ability to assign <code>depth</code> to elements. That’s a good start, but it seems a little restricted, doesn’t it? A bunch of flat panels sitting at different depths in a 3D space. We’re not really making the most of the technology. We need to add a little style in there… style that can bridge the gap between depth-levels. Fortunately, Webkit is one step ahead of this game with it’s <a href="http://webkit.org/blog/386/3d-transforms/">CSS 3D transforms</a>. These could easily be adapted to show in real 3D instead of 3D rendered in 2D.</p>

<h4 id="curves-would-be-nice">Curves would be nice</h4>

<p>Yes they would, and so would a mansion on the beach in Barbados. We don’t even have the ability to define curves in 2D CSS yet. But then in 2D we might not have wanted to do crazy things like making a callout or title bow inwards or outwards, which would work pretty well in 3D. But maybe just one step at a time…</p>

<h3 id="what-is-3d-anyway">What is 3D anyway</h3>

<p>To develop in 3D you need to understand how it really works. Fortunately understanding it is a lot simpler than getting your head around designing and developing in it:</p>

<p><strong>3D works by each of your eyes seeing a slightly different image.</strong></p>

<p>Simple enough, and in real life this works pretty well. But when generating your own 3D content you have to be ever-mindful of it.</p>

<h3 id="mind-the-gaps">Mind the gaps</h3>

<p>Imagine a blank page. You make the background a fetching pinkish sort of red colour and set the <code>depth</code> to be way back in the distance. </p>

<p><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2011/02/demo1.png" width="628" height="312" title="'3DS Screen showing plain background'" /></p>

<p>You then have a look at it and wonder why it doesn’t look like it’s way off in the distance. You check to see that your 3D depth slider is turned all the way up and when you find that it is you’re left feeling a little confused.</p>

<p>The reason why this doesn’t appear to be in the background is because your eyes are seeing the exact same image. There needs to be some more detail in there before your eyes can be tricked into thinking that it’s way off in the distance. Here are some suggestions:</p>

<ol>
  <li>You could give it a border that makes it look like you’re looking into a box. Of course the edges of the border would need to be firmly in the foreground for it to work.</li>
</ol>

<p><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2011/02/demo2.png" width="628" height="312" title="'3DS screen showing a background shaded to look like you are looking into a box'" /></p>

<ol>
  <li>You could give it a pattern or image. Beware with repeating patterns though: looking at 3D images forces your eyes to cross slightly and a repeating pattern could cause you to think it’s not at the depth you intended.</li>
</ol>

<p><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2011/02/demo3.png" width="628" height="312" title="'3DS screen with a patterned background'" /></p>

<ol>
  <li>Lay something else on top of it with a higher <code>depth</code>. For demonstration purposes I’m going to go with this one.</li>
</ol>

<p><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2011/02/demo4.png" width="628" height="312" title="'3DS screen with a plain background and a green tile overlayed'" /></p>

<p>But even laying something on top like this isn’t too easy for our brains to process. Have a look what each eye would be seeing.</p>

<p><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2011/02/demo5.png" width="628" height="312" title="'Side-by-side 3DS screens showing the difference in location of the overlaid panel for each eye'" /></p>

<p>There’s not a great deal to differentiate these two images and while your brain knows it’s seeing different things from each eye it is struggling because there are things missing that it’s used to. Usually when you see an object in front of another object it casts a shadow somewhere. Because they are in different locations your eyes will each see that shadow slightly differently. Also the way the object is lit and how it reflects the light could be different in each eye. To make sure we don’t give people headaches we’ll have to sort this out.</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>CSS    </span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
</pre></td><td class="code"><pre><code class="css"><span class="line"><span class="nc">.floating-box</span><span class="p">{</span>
</span><span class="line">    <span class="n">box</span><span class="o">-</span><span class="n">shadow</span><span class="o">:</span> <span class="m">5px</span> <span class="m">5px</span> <span class="m">5px</span> <span class="m">#ccc</span><span class="p">;</span>
</span><span class="line"><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>Now the panel has a nice drop shadow which should make it easier on the eyes and easier to see the 3D effect.</p>

<p><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2011/02/demo6.png" width="628" height="312" title="'3DS screen with plain background and a green panel overlaid with a drop shadow'" /></p>

<p>But how does it get rendered so that each eye sees the shadow differently?</p>

<h3 id="seeing-the-light">Seeing the light</h3>

<p>The way I see it there are two options:</p>

<ol>
  <li>The browser provides a default (override-able) light source:</li>
</ol>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>CSS    </span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
</pre></td><td class="code"><pre><code class="css"><span class="line"><span class="nt">body</span><span class="p">{</span>
</span><span class="line">    <span class="n">light</span><span class="o">-</span><span class="n">source</span><span class="o">:</span> <span class="m">25</span><span class="o">%</span> <span class="m">25</span><span class="o">%</span> <span class="k">fixed</span><span class="p">;</span>
</span><span class="line"><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p><code>fixed</code> would position the light source relative to the browser viewport, and as an alternative <code>absolute</code> would position it relative to the document.</p>

<ol>
  <li>You, the developer, get granular control over what each eye sees:</li>
</ol>

<p>If you had control over each eye the possibilities would be endless. Set the difference in box shadow offset, show a different background image to achieve a rippling effect. You would OWN all the dimensions.</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>CSS    </span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
</pre></td><td class="code"><pre><code class="css"><span class="line"><span class="k">@media</span> <span class="nt">screen</span> <span class="nt">and</span> <span class="o">(</span><span class="nt">-3ds-min-device-spatial-dimensions</span><span class="o">:</span> <span class="nt">3</span><span class="o">)</span> <span class="nt">and</span> <span class="o">(</span><span class="nt">-3ds-perspective</span><span class="o">:</span> <span class="nt">left-eye</span><span class="o">)</span> <span class="p">{</span>
</span><span class="line">    <span class="nc">.floating-box</span><span class="p">{</span>
</span><span class="line">        <span class="n">box</span><span class="o">-</span><span class="n">shadow</span><span class="o">:</span> <span class="m">3px</span> <span class="m">5px</span> <span class="m">5px</span> <span class="m">#ccc</span><span class="p">;</span>
</span><span class="line">    <span class="p">}</span>
</span><span class="line"><span class="p">}</span>
</span><span class="line"><span class="k">@media</span> <span class="nt">screen</span> <span class="nt">and</span> <span class="o">(</span><span class="nt">-3ds-min-device-spatial-dimensions</span><span class="o">:</span> <span class="nt">3</span><span class="o">)</span> <span class="nt">and</span> <span class="o">(</span><span class="nt">-3ds-perspective</span><span class="o">:</span> <span class="nt">right-eye</span><span class="o">)</span> <span class="p">{</span>
</span><span class="line">    <span class="nc">.floating-box</span><span class="p">{</span>
</span><span class="line">        <span class="n">box</span><span class="o">-</span><span class="n">shadow</span><span class="o">:</span> <span class="m">7px</span> <span class="m">5px</span> <span class="m">5px</span> <span class="m">#ccc</span><span class="p">;</span>
</span><span class="line">    <span class="p">}</span>
</span><span class="line"><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>I think a combination of both would probably be in the interests of developer and user alike.</p>

<h3 id="its-not-all-giant-blue-humanoids-and-bio-luminescent-flowers">It’s not all giant blue humanoids and bio-luminescent flowers</h3>

<p>This technology has it’s disadvantages, and you can be sure that there will be some nasty surprises out there when it comes along. As with most visual effects, subtlety is king. Of course there will always be the developers who are irresponsible with this great power and make some eye-bleeding creations, but that’s just inevitable. No, what I’m really worried about can be summed up in two words: Internet. Advertising. If you thought pop-over ads were intrusive now, you ain’t seen nothing yet.</p>

<h3 id="the-waiting-game">The waiting game</h3>

<p>Who knows what you’ll be able to do with the browser? Nintendo maybe? Or if it’s <a href="http://www.opera.com/">Opera</a> providing the software again, as they did for the Wii and original DS/DSi then I expect they will know. (Please do get in touch if you have insider knowledge!) But until that information is made available or the 3DS is in our hands we won’t know for sure. I hope it’s got at least a few fun 3D features to play with. I’m sure the full set will develop over time.</p>

<p><strong>Update:</strong> Now that the browser is available, I had a little play with it and <a href="http://blog.norestfortheweekend.com/blog/2011/06/14/3ds-browser-revisited/">wrote down a few of my thoughts</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Always use www in your URLs]]></title>
    <link href="http://blog.norestfortheweekend.com/blog/2011/01/16/always-use-www-in-your-urls/"/>
    <updated>2011-01-16T19:13:03+00:00</updated>
    <id>http://blog.norestfortheweekend.com/blog/2011/01/16/always-use-www-in-your-urls</id>
    <content type="html"><![CDATA[<p>…unless you are specifically on another subdomain. </p>

<p>I’m not kidding! You need to make sure that your sites all redirect from http://yoursite.org to http://www.yoursite.org. If you’re not sure whether your sites do this, try now. Go ahead, I’ll wait.</p>

<p>You can score yourself against this list based on what you see:</p>

<ul>
  <li>Error page: <strong>NO POINTS!</strong></li>
  <li>Redirected to www.yoursite.org but to the front page instead of the page you wanted: <strong>Half a point</strong></li>
  <li>Page served, URL still has no www: <strong>1 point</strong></li>
  <li>Redirected to www.yoursite.org and to the correct page: <strong>10 points!</strong></li>
</ul>

<p>On no account should a user see an error page if they don’t type www before your URL. That’s just a horrible experience and most people will think the site is just broken and go somewhere else. No points at all.</p>

<p>It’s almost as bad if the user enters an address to a page within your site and then gets taken to the home page, even if the URL in the address bar says www. I mean at least the site doesn’t look broken but it’s still not a nice welcome. Having the www gets you half a point.</p>

<p>If the page is served irrespective of whether there is a www in the URL thats… OK. But only OK. Aside from the fact that you’ve got the same pages in two locations (not good for Google-juice) it could lead to errors. As yoursite.org and www.yoursite.org are seen as two different domains, if you have any AJAX on your site that refers specifically to www.yoursite.org it’s going to <em>fail hard</em> if the URL in the address bar doesn’t have the www. This is thanks to the cross-domain security model browsers employ. You don’t want that happening.</p>

<p>What you should be doing is simply redirecting all traffic to the root domain to the www subdomain and maintaining the rest of the URL to ensure a good experience. This is actually very easy to do:</p>

<p>Open the <code>.htaccess</code> file in the root of your site’s file structure. If it doesn’t exist, create it! You can create it on the command line, or directly on the server but Windows and OS X will object to the filename if you try and create it using the GUI. Once it’s open, add these lines to it:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
</pre></td><td class="code"><pre><code class="apache"><span class="line"><span class="nb">RewriteCond</span> %{HTTP_HOST} ^yoursite\.org$ [NC]
</span><span class="line"><span class="nb">RewriteRule</span> ^(.*)$ http://www.yoursite.org/$1 [R=301,L]
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>Note that on the first line when you change the domain you need to add a slash before each dot as it’s part of a regular expression.</p>

<p>It’s that simple!</p>

<p>You have no excuse now.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Regex for an email address]]></title>
    <link href="http://blog.norestfortheweekend.com/blog/2010/10/13/regex-for-an-email-address/"/>
    <updated>2010-10-13T14:21:53+01:00</updated>
    <id>http://blog.norestfortheweekend.com/blog/2010/10/13/regex-for-an-email-address</id>
    <content type="html"><![CDATA[<p>It’s something that I’ve come up against several times and each time I google for it I turn up a different result.</p>

<p>How do you validate an email address?</p>

<p>Obviously you want to use a <a href="http://en.wikipedia.org/wiki/Regular_expression">regular expression</a>, but given the specification for <a href="http://en.wikipedia.org/wiki/Email_address">email address</a>es that’s going to be one really complicated line of code.</p>

<p>Following a user’s complaint that they could not register with our site with their (perfectly legitimate) address because of our validation, today’s search yielded more success than usual. Near the bottom of the <a href="http://cpansearch.perl.org/src/RJBS/Email-Valid-0.184/lib/Email/Valid.pm">source</a> of the <a href="http://search.cpan.org/~rjbs/Email-Valid-0.184/lib/Email/Valid.pm">Perl Email::Valid module</a> there is a very long regular expression which I have lifted directly and placed in this page.</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>Email regex (email_regex.pl)</span> <a href="http://blog.norestfortheweekend.com/downloads/code/regex-for-an-email-address/email_regex.pl">download</a></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
</pre></td><td class="code"><pre><code class="perl"><span class="line"><span class="sr">/^[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:(?:[^(\040)&lt;&gt;@,;:&quot;.\\\[\]\000-\037\x80-\xff]+(?![^(\040)&lt;&gt;@,;:&quot;.\\\[\]\000-\037\x80-\xff])|&quot;[^\\\x80-\xff\n\015&quot;]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015&quot;]*)*&quot;)[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)&lt;&gt;@,;:&quot;.\\\[\]\000-\037\x80-\xff]+(?![^(\040)&lt;&gt;@,;:&quot;.\\\[\]\000-\037\x80-\xff])|&quot;[^\\\x80-\xff\n\015&quot;]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015&quot;]*)*&quot;)[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*@[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)&lt;&gt;@,;:&quot;.\\\[\]\000-\037\x80-\xff]+(?![^(\040)&lt;&gt;@,;:&quot;.\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)&lt;&gt;@,;:&quot;.\\\[\]\000-\037\x80-\xff]+(?![^(\040)&lt;&gt;@,;:&quot;.\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*|(?:[^(\040)&lt;&gt;@,;:&quot;.\\\[\]\000-\037\x80-\xff]+(?![^(\040)&lt;&gt;@,;:&quot;.\\\[\]\000-\037\x80-\xff])|&quot;[^\\\x80-\xff\n\015&quot;]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015&quot;]*)*&quot;)[^()&lt;&gt;@,;:&quot;.\\\[\]\x80-\xff\000-\010\012-\037]*(?:(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)|&quot;[^\\\x80-\xff\n\015&quot;]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015&quot;]*)*&quot;)[^()&lt;&gt;@,;:&quot;.\\\[\]\x80-\xff\000-\010\012-\037]*)*&lt;[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:@[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)&lt;&gt;@,;:&quot;.\\\[\]\000-\037\x80-\xff]+(?![^(\040)&lt;&gt;@,;:&quot;.\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)&lt;&gt;@,;:&quot;.\\\[\]\000-\037\x80-\xff]+(?![^(\040)&lt;&gt;@,;:&quot;.\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*(?:,[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*@[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)&lt;&gt;@,;:&quot;.\\\[\]\000-\037\x80-\xff]+(?![^(\040)&lt;&gt;@,;:&quot;.\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)&lt;&gt;@,;:&quot;.\\\[\]\000-\037\x80-\xff]+(?![^(\040)&lt;&gt;@,;:&quot;.\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*)*:[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)?(?:[^(\040)&lt;&gt;@,;:&quot;.\\\[\]\000-\037\x80-\xff]+(?![^(\040)&lt;&gt;@,;:&quot;.\\\[\]\000-\037\x80-\xff])|&quot;[^\\\x80-\xff\n\015&quot;]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015&quot;]*)*&quot;)[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)&lt;&gt;@,;:&quot;.\\\[\]\000-\037\x80-\xff]+(?![^(\040)&lt;&gt;@,;:&quot;.\\\[\]\000-\037\x80-\xff])|&quot;[^\\\x80-\xff\n\015&quot;]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015&quot;]*)*&quot;)[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*@[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)&lt;&gt;@,;:&quot;.\\\[\]\000-\037\x80-\xff]+(?![^(\040)&lt;&gt;@,;:&quot;.\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)&lt;&gt;@,;:&quot;.\\\[\]\000-\037\x80-\xff]+(?![^(\040)&lt;&gt;@,;:&quot;.\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*&gt;)$/</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>I won’t lie to you: I haven’t dissected it to manually confirm that it does what it should, but it has been successful so far in the tests I’ve thrown at it. It also works in Javascript which, for me, is a massive win.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Why do we need conferences?]]></title>
    <link href="http://blog.norestfortheweekend.com/blog/2010/03/21/why-do-we-need-conferences/"/>
    <updated>2010-03-21T00:58:21+00:00</updated>
    <id>http://blog.norestfortheweekend.com/blog/2010/03/21/why-do-we-need-conferences</id>
    <content type="html"><![CDATA[<p><a href="http://www.flickr.com/photos/rugbymadgirl/2528751423/in/pool-pubstandards"><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2010/03/hBeer.jpg" width="280" height="420" title="'hBeer'" /></a></p>

<p>Seriously? Why do we need to spend hundreds of pounds, dollars, euros or whatever to attend these events? They are pretty pricey and more often that not they are nowhere near home so you have the added cost of transport and hotel bills and all those meals you’re going to consume out while you’re away. It’s not cheap, and even if you can afford it, why spend it?</p>

<h3 id="the-talks-its-all-about-the-presentations--sessions">The Talks… it’s all about the presentations &amp; sessions!</h3>

<p>Is it really though? These people who get on the stage and talk: Yeah OK, they’re great. They do a fantastic presentation, insightful with great slides and funny too! But don’t they put articles on their blogs for free that cover that topic and a wealth of others besides, all year round? If hearing and seeing them actually say the words is so integral to getting their message across, they could very easily record themselves and publish it in a video or audio format right there on their blogs.</p>

<p>In fact, recently some conferences have taken to publishing all the talks that are given right there on the web for all to see. Everyone can watch, even people who didn’t pay to go to the conference itself! I was watching <a href="http://vimeo.com/build">the videos</a> from a conference that I didn’t go to - <a href="http://buildconference.com">Build</a> - which was held in Belfast at the end of last year. How nice of them to go to all the effort of filming it, editing it and putting it online, I thought. And the talks are great, I’d encourage you to go and watch them. But I was thinking… how would I feel about this if I actually PAID to go to the conference?</p>

<h3 id="money-talks">Money talks</h3>

<p>If I’d laid down cold hard cash to see the talks, wouldn’t I be unhappy that others who hadn’t could then just browse to a page and see all the content… for free? Maybe a little. But then again I’m all for sharing information and content, especially when it’s of benefit to the community so maybe I’d be a little conflicted about that.</p>

<p>Most people I ask, however, seem not to mind this sort of behaviour. They seem to think that conferences go beyond the talks, and I’d be inclined to agree.</p>

<h3 id="its-not-about-what-you-know">It’s not about what you know</h3>

<p>I think that while the talks are nice and all, what most people value the most from conferences is the opportunity to meet other like-minded people. Or to put it in business-speak: networking. Between the talks and in the evening(s), you get to mingle with people who all have their own goals, ideas, methods, questions and accomplishments in the same field as you and are quite willing to share them with you. The more people you talk to and the more conferences you go to (where you’re likely to see these people again) the more contacts and even friends you are likely to make.</p>

<p>Nothing drives this home more clearly than the general chatter I picked up from this years <a href="http://sxsw.com">SXSW</a> which I was sadly unable to attend. Essentially, the vast majority of talk I picked up from SXSW was not about the panels and talks (which no doubt were excellent) but they were about the parties, BBQs and the socialising. The Networking.</p>

<p>But this brings me back to my original point. Why do we need conferences? If all we need to make contacts is to get people who are in similar lines of work to talk to each other why don’t we do it all the time? The talks are nice but completely unnecessary to get what people seem to value the most from conferences.</p>

<h3 id="pub-standards">Pub Standards</h3>

<p><a href="http://www.pubstandards.co.uk">Pub Standards</a> is something that happens in London on a monthly basis. It also happens in <a href="http://pubstandards.org">Melbourne</a>, I believe (<a href="http://en.wikipedia.org/wiki/User:Aliasd/Pub_Standards">Wikipedia confirms this</a> so it must be true). What it is is this: a whole bunch of web folk get together and take over a pub for an evening. They sit and drink and talk about whatever they please which may or may not include topics such as:</p>

<ul>
  <li>What they are doing at work</li>
  <li>What they are watching on TV</li>
  <li>The contents of that controversial blog post that’s been doing the rounds on Twitter</li>
  <li>The latest CSS tricks that they’ve learned or seen in action</li>
  <li>Why anyone who uses a Palm Pre should be hugged / pitied / unfollowed / shot on sight</li>
  <li>Anything and everything else</li>
</ul>

<p>…you get the idea. It sounds pretty much like the after party at a conference then.</p>

<p>The other night it was in fact my first Pub Standards (for shame) but it certainly won’t be my last. I just can’t imagine why this hasn’t caught on more places than just London and Melbourne!</p>

<h3 id="the-reality">The reality</h3>

<p>While it would be awesome to think that we could all get our conference fix by reading blogs, watching online video and going to Pub Standards the reality is that it’s just not logistically possible.</p>

<p>There are actually people outside of London (and indeed outside of any large city) who are involved in the web industry who just couldn’t make it in to the city on a regular basis. They could start their own group but you really need a large city environment to get a decent sized and varied bunch of people together each month. In addition to that, conferences can provide the chance for people to meet developers from other parts of the country or from the other side of the world which local meet-ups just can’t.</p>

<p>It would be nice to think that we might be able to organise some kind of International Pub Standards where people fly in and join the fun for a few times every year, but that wouldn’t work for so many reasons:</p>

<ol>
  <li>Spouses and significant others often remain unconvinced of the value of developers drinking beer together.</li>
  <li>No one’s going to fly in from Amsterdam just for a night out at the pub - it has to be for longer to make it worth it.</li>
  <li>Any longer than an evening and you start having to take things like food breaks and accommodation into account… and the conversation could start to need a catalyst of some sort.</li>
  <li>No company is going to pay your transatlantic flights for what can only be described as a night down the pub with a bunch of geeks.</li>
</ol>

<p>The talks that you get at a conference and the information you glean from them, or the questions that arise from them seem to solve all these problems quite neatly. And let’s face it they generally are quite good, otherwise they wouldn’t bother making them available for everyone else on the internet.</p>

<h3 id="is-that-your-final-answer">Is that your final answer?</h3>

<p>Why do we need conferences? It’s so we can meet people and gel as a community on a global level in a way that you can’t do by just using Twitter, Facebook and all of their social contemporaries.</p>

<p>But let’s not underestimate the value of local groups either. I find it astounding that Pub Standards is only happening in London and Melbourne. There must be so many places, large cities, where there are plenty enough web developers interested in Standards and beer to get a regular meet-up going. If you live or work in one of them, why not start one up? I’m sure it would be very rewarding on many levels.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A fold by any other name]]></title>
    <link href="http://blog.norestfortheweekend.com/blog/2010/02/24/a-fold-by-any-other-name/"/>
    <updated>2010-02-24T14:53:33+00:00</updated>
    <id>http://blog.norestfortheweekend.com/blog/2010/02/24/a-fold-by-any-other-name</id>
    <content type="html"><![CDATA[<p>…would be a more accurate analogy.</p>

<p>We’ve all heard the arguments about the so-called fold, that mysterious, imaginary line beneath which no content shall be seen. There are still plenty of clients, designers and other folk who should know better who will request something be placed ‘above the fold’. Whether or not they ask for it using the term ‘fold’ is immaterial because at the end of the day that’s what they mean and it’s something they want.</p>

<h3 id="a-fold-through-time">A fold through time</h3>

<p>The history of the Fold dates back to an era where news was distributed in a physical format. It was printed on large sheets of paper, largely in black and white and arranged into what resembled an oversized book. To aid distribution and storage these items were folded in half leaving visible only the title of the publication and one or two other pieces of information that were on the top half of the front page.</p>

<p>When on display to potential buyers, each publication was competing with other similar publications. The information visible was important because it would catch people’s eyes and was often what governed which publication was chosen for purchase. Because of this, the editors had to carefully decide which pictures and headlines were to be put on display in the top half of the front page. What was ‘above the fold’ was very important – it could dramatically affect sales.</p>

<h3 id="from-dots-to-pixels">From dots to pixels</h3>

<p>Now that we are consuming masses of content on screens rather than pages (whether it’s news, opinion pieces, novels, comics or anything else that print once ruled) wise people will tell us that <a href="http://www.thereisnopagefold.com/">there is no page fold</a>, not any more. It disappeared when the content left the medium of paper. If there is no paper there is no fold.</p>

<p>Other (slightly more old-fashioned) people would argue otherwise; they would argue that not all people are used to scrolling. A lot of the more computer savvy or technically orientated among us find this hard to believe. Back when the concept of the digital fold was first introduced in the early days of the internet this may well have been the case. Now, however, it is the age of the <a href="http://en.wiktionary.org/wiki/silver_surfer">silver surfer</a> and a time where if you can’t perform fundamental functions on a computer it is becoming increasingly difficult to get along.</p>

<p>Scrolling is a pretty fundamental function and I would support the hypothesis that there are incredibly few people who use computers that do not know how to scroll.</p>

<h3 id="folding-it-back-on-itself">Folding it back on itself</h3>

<p>For most people that’s where the argument ends. I hold a slightly different opinion, perhaps controversially. Although I don’t  believe they have said it directly, it would seem Google are also disinclined to agree based on their <a href="http://browsersize.googlelabs.com/">recent work capturing various screen sizes</a> and mapping the visible area of a page without scrolling.</p>

<p>What I believe it comes down to is this:</p>

<p><strong>People will scroll if they can’t find what they are looking for.</strong></p>

<p>If they are searching for something and can’t see it but <em>expect</em> it to be there, scrolling is pretty much second nature. If they have found it, however, why scroll? Unless there is something else visible that catches their interest, maybe half obscured by the bottom of the window then there is little incentive to reach for the scroll-wheel.</p>

<p>It doesn’t end there either. If someone is reading a piece of content – say, an email – that appears to reach it’s logical end within the visible area then they are less likely to scroll down, <em>even if there is more relevant content beneath</em>. Even seasoned computer users make this mistake (trust me, I’ve done it).</p>

<h3 id="the-fold-in-action">The fold in action</h3>

<p>So, you are visiting a page. You know exactly what you want from the page and are interested in nothing else. You visit the page and there it is sitting waiting for you. You don’t even need to scroll to see it all. When you’ve finished reading or looking at it, what do you do? I know what I’d do: close the tab, type a new URL, Google something… in short, navigate away from that page.</p>

<p>But what about all the content below this so-called ‘fold’? It might well have been really interesting and relevant to me but I didn’t see it because I didn’t scroll. I didn’t scroll because I had already found what I came to that page to see.</p>

<p>I think it’s time for some examples. I’m going to use what got me thinking about this again in the first place: WebComics.</p>

<p>For those unfamiliar, the WebComics model is based around free content. The comic is given away for free and the revenue is generated from adverts and merchandise. It’s fair to say that for a full-time WebComic artist there is one goal: to generate revenue. The fact that they all seem to enjoy their work is a pleasant side-effect. There is a secondary goal which is to cultivate fans and a community which in turn leads to repeat visits which lead to advert revenue and merchandise sales.</p>

<p>Look at this page:</p>

<p><a href="http://blog.norestfortheweekend.com/images/wp-uploads/2010/02/ellieconnelly.jpg"><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2010/02/ellieconnelly-628x402.jpg" width="628" height="402" title="'Screen grab from the WebComic &#34;Ellie Connelly&#34;'" alt="'Screen grab from the WebComic &#34;Ellie Connelly&#34;'" /></a></p>

<p>I have a pretty big screen. With that page from <a href="http://www.ellieconnelly.com/">Ellie Connelly</a> I hit the site and the comic is all there, no need to scroll. When I’ve finished reading the most likely thing I’ll do is close the tab because what I came for was the comic. There’s nothing else visible that makes me encourages to look any further. There are ads on that page but to see them I’d have to scroll… so I won’t see them. There’s also a blog which I’d sadly also miss.</p>

<p>Now have a look at this front page from another WebComic, <a href="http://www.evil-comic.com">Evil, Inc.</a>:</p>

<p><a href="http://blog.norestfortheweekend.com/images/wp-uploads/2010/02/evilinc.jpg"><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2010/02/evilinc-628x404.jpg" width="628" height="404" title="'Screen grab from the WebComic &#34;Evil, Inc.&#34;'" alt="'Screen grab from the WebComic &#34;Evil, Inc.&#34;'" /></a></p>

<p>There is an advert right at the top of the page! The logo is shrunk and placed in line with the advert. This lets the content that the user is after move higher up the page. This is good for the reader and good for the author as they have a better chance of enticing the reader to scroll down with extra content.</p>

<p>As well as the advert, right above the comic there is a link in bright red telling us what the latest blog post is about. Clicking on this will jump the reader straight to the blog in the same page. Within the visual boundary of the white box I count 5 links to explore the archives, 2 links with which the artist can make money and 9 ways for the reader to spread the word to their friends about the comic, hopefully generating new readership. All of this without having to scroll.</p>

<p>Which comic do you think does the best in terms of revenue based purely on these interface choices? <em>Evil, Inc.</em> would be my guess.</p>

<p>Let’s look at another, <a href="http://www.sheldoncomics.com/">Sheldon</a>:</p>

<p><a href="http://blog.norestfortheweekend.com/images/wp-uploads/2010/02/sheldon.jpg"><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2010/02/sheldon-628x402.jpg" width="628" height="402" title="'Screen grab from the WebComic &#34;Sheldon&#34;'" alt="'Screen grab from the WebComic &#34;Sheldon&#34;'" /></a></p>

<p>Again, the strip fits nicely on my screen without scrolling but there’s so much else to catch my attention after I’ve read it. There are 3 adverts (4 if you count the peel back flash advert in the top right) and plenty of ways to maintain the reader’s engagement with the strip. One of the adverts is butted right up to the bottom of the strip which means so long as the top of the advert is interesting the user is much more likely to scroll down to see the rest.</p>

<h3 id="to-sum-up">To sum up…</h3>

<p><em>Please</em> don’t think I’m advocating cramming as much clutter into the upper regions of pages as possible. I’m absolutely not - it would make for scruffy and crowded-looking sites and the content would be lost amongst everything else vying for attention.</p>

<p>Likewise, <em>please</em> don’t think I’m suggesting that people should push the content users want below the fold so they have to scroll for it - that would just be a terrible user experience. If a site actually did that they would haemorrhage users at a massive rate. </p>

<p>It doesn’t take a black belt in origami to tell that ‘the fold’ is a concept that doesn’t port from print to web because unlike a newspaper, the web is fluid. Nothing is fixed: the browser window size, the text size, the position and type of content… This doesn’t mean we can dismiss the analogy in it’s entirety, however, because there are some cases where users really won’t scroll, regardless of their technical expertise.</p>

<p>Like so many other things, it comes down to the fact that careful consideration of layout based upon content, expected user behaviour and desired user behaviour is essential in any good design.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A little something while you wait]]></title>
    <link href="http://blog.norestfortheweekend.com/blog/2010/02/02/a-little-something-while-you-wait/"/>
    <updated>2010-02-02T00:46:59+00:00</updated>
    <id>http://blog.norestfortheweekend.com/blog/2010/02/02/a-little-something-while-you-wait</id>
    <content type="html"><![CDATA[<p>I know, I know it’s been a while since I posted. There’s one on the way, I promise!</p>

<p>While you wait for it to brew, however, why don’t you check out my inaugural post on the BBC Web Developer blog: <a href="http://www.bbc.co.uk/blogs/webdeveloper/2010/02/css-for-widgets-friends-dont-break-friends-styles.shtml">CSS for Widgets</a>.</p>

<p>Have you ever written some CSS on a page which contains other people’s stylesheets? And have you noticed that either your CSS broke their stuff or theirs messed about with yours? If you have then this post is right down your street. If you haven’t… well have a read just to make sure it never happens. </p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Console.log for all!]]></title>
    <link href="http://blog.norestfortheweekend.com/blog/2009/12/12/console-log-for-all/"/>
    <updated>2009-12-12T20:47:01+00:00</updated>
    <id>http://blog.norestfortheweekend.com/blog/2009/12/12/console-log-for-all</id>
    <content type="html"><![CDATA[<p><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2009/12/console.jpg" width="628" height="187" title="'Firebug console'" /></p>

<p>If you&#8217;re like me then you probably use <code>console.log</code> a lot. It&#8217;s such a useful debugging tool! It&#8217;s better that alert in so many ways I won&#8217;t bother mentioning them all because - oh what the hell, this is my blog I&#8217;ll do what I want. Here is why <code>console.log</code> is better than alert:</p>

<ul>
  <li>It hides away when you don&#8217;t need it and doesn&#8217;t bother you unless you are interested in it.</li>
  <li>It lets you log more than one variable at a time simply by passing more than one argument.</li>
  <li>It doesn&#8217;t interrupt the flow of the script until you click OK.
    <ul>
      <li>Of course if you want the flow to be stopped as you read your debug text then alert is just great, don&#8217;t get me wrong!</li>
    </ul>
  </li>
  <li>If you are testing a loop or quick interval you don&#8217;t have to force quit Firefox just to get to the reload button.</li>
  <li>It integrates perfectly with the rest of Firebug turning a lot of what you log into clickable items able to be inspected in the script or HTML tabs.`</li>
  <li>If you log an <code>Element</code> that&#8217;s on the page when you mouse over it in the log it highlights on the page.</li>
</ul>

<p>What&#8217;s my point? Well, if you&#8217;re like me then you probably use it so much that sometimes after a hard debugging session it&#8217;s easy to accidentally leave it in the code in a few places.</p>

<h2 id="the-piece-of-grit-that-stopped-the-clock">The piece of grit that stopped the clock</h2>

<p>What harm can it do? Most normal users don&#8217;t have Firebug installed anyway so they won&#8217;t see anything, right?</p>

<p>Wrong. Or at least wrong attitude. Developers will see your <code>console.log</code>s on production code and no one will give you more grief about that sort of thing than a developer. But more importantly, it can affect everyone else too.</p>

<p>Without Firebug installed the <code>console</code> object doesn&#8217;t exist. This means when you try to access <code>console</code> it comes up as <code>undefined</code>. It&#8217;s little omissions like this that can bring a JS app down and halt execution depending on how fussy the engine is.</p>

<p><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2009/12/erroronpage.gif" width="109" height="21" title="'IE's 'error on page' icon'" /></p>

<p>IE users will see the horrible little yellow exclamation mark in the bottom left of their browser and be informed that there is a problem with one of the scripts on the page. This doesn&#8217;t inspire confidence in a site or product.</p>

<h2 id="undesirable">Undesirable</h2>

<p>It&#8217;s fair to say that you don&#8217;t want any of this to happen. Fortunately I have a solution which not only prevents it from happening but provides you with some of the debugging functions that you get from Firebug&#8217;s console. Have a look at the code:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span> (console.log.js)</span> <a href="http://blog.norestfortheweekend.com/downloads/code/console-log-for-all/console.log.js">download</a></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
<span class="line-number">13</span>
<span class="line-number">14</span>
<span class="line-number">15</span>
<span class="line-number">16</span>
<span class="line-number">17</span>
<span class="line-number">18</span>
<span class="line-number">19</span>
<span class="line-number">20</span>
<span class="line-number">21</span>
<span class="line-number">22</span>
<span class="line-number">23</span>
<span class="line-number">24</span>
<span class="line-number">25</span>
<span class="line-number">26</span>
<span class="line-number">27</span>
<span class="line-number">28</span>
<span class="line-number">29</span>
<span class="line-number">30</span>
<span class="line-number">31</span>
<span class="line-number">32</span>
<span class="line-number">33</span>
<span class="line-number">34</span>
<span class="line-number">35</span>
<span class="line-number">36</span>
<span class="line-number">37</span>
<span class="line-number">38</span>
<span class="line-number">39</span>
<span class="line-number">40</span>
<span class="line-number">41</span>
<span class="line-number">42</span>
<span class="line-number">43</span>
<span class="line-number">44</span>
<span class="line-number">45</span>
<span class="line-number">46</span>
<span class="line-number">47</span>
<span class="line-number">48</span>
<span class="line-number">49</span>
<span class="line-number">50</span>
<span class="line-number">51</span>
<span class="line-number">52</span>
</pre></td><td class="code"><pre><code class="js"><span class="line"><span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="s1">&#39;console&#39;</span> <span class="k">in</span> <span class="nb">window</span><span class="p">)</span> <span class="o">||</span> <span class="o">!</span><span class="p">(</span><span class="s1">&#39;log&#39;</span> <span class="k">in</span> <span class="nb">window</span><span class="p">.</span><span class="nx">console</span><span class="p">)){</span>
</span><span class="line">	<span class="nb">window</span><span class="p">.</span><span class="nx">console</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(){</span>
</span><span class="line">		<span class="kd">var</span> <span class="nx">r</span> <span class="o">=</span> <span class="p">{},</span>
</span><span class="line">		<span class="nx">glow</span><span class="p">,</span>
</span><span class="line">		<span class="nx">$</span><span class="p">,</span>
</span><span class="line">		<span class="nx">logpanel</span><span class="p">,</span>
</span><span class="line">		<span class="nx">enabled</span><span class="o">=</span><span class="kc">false</span><span class="p">;</span>
</span><span class="line">
</span><span class="line">		<span class="nx">r</span><span class="p">.</span><span class="nx">enable</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(){</span>
</span><span class="line">			<span class="nx">enabled</span><span class="o">=</span><span class="kc">true</span><span class="p">;</span>
</span><span class="line">		<span class="p">};</span>
</span><span class="line">
</span><span class="line">		<span class="nx">r</span><span class="p">.</span><span class="nx">disable</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(){</span>
</span><span class="line">			<span class="nx">enabled</span><span class="o">=</span><span class="kc">false</span><span class="p">;</span>
</span><span class="line">			<span class="k">if</span><span class="p">(</span><span class="nx">logpanel</span><span class="p">){</span>
</span><span class="line">				<span class="nx">logpanel</span><span class="p">.</span><span class="nx">destroy</span><span class="p">();</span>
</span><span class="line">			<span class="p">}</span>
</span><span class="line">		<span class="p">};</span>
</span><span class="line">
</span><span class="line">		<span class="nx">r</span><span class="p">.</span><span class="nx">clear</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(){</span>
</span><span class="line">			<span class="nx">logpanel</span><span class="p">.</span><span class="nx">empty</span><span class="p">();</span>
</span><span class="line">		<span class="p">};</span>
</span><span class="line">
</span><span class="line">		<span class="nx">r</span><span class="p">.</span><span class="nx">log</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">msg</span><span class="p">){</span>
</span><span class="line">			<span class="k">if</span><span class="p">(</span><span class="nx">enabled</span><span class="p">){</span>
</span><span class="line">				<span class="k">if</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="nx">logpanel</span><span class="p">)</span><span class="o">==</span><span class="s1">&#39;undefined&#39;</span><span class="p">){</span>
</span><span class="line">					<span class="nx">logpanel</span> <span class="o">=</span> <span class="nx">glow</span><span class="p">.</span><span class="nx">dom</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="s1">&#39;&lt;p style=&quot;position: fixed; bottom: 0; left: 0; height: 100px; width: 100%; overflow-y: auto; overflow-x: noscroll;background: white;border-top: 1px solid gray;&quot; id=&quot;console-log&quot;&gt;&#39;</span><span class="p">);</span>
</span><span class="line">					<span class="nx">$</span><span class="p">(</span><span class="s1">&#39;body&#39;</span><span class="p">).</span><span class="nx">append</span><span class="p">(</span><span class="nx">logpanel</span><span class="p">);</span>
</span><span class="line">					<span class="nx">$</span><span class="p">(</span><span class="s1">&#39;body&#39;</span><span class="p">).</span><span class="nx">css</span><span class="p">(</span><span class="s1">&#39;padding-bottom&#39;</span><span class="p">,</span><span class="s1">&#39;100px&#39;</span><span class="p">);</span>
</span><span class="line">					<span class="k">if</span><span class="p">(</span><span class="nx">glow</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">ie</span> <span class="o">&amp;&amp;</span> <span class="nx">glow</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">ie</span><span class="o">&lt;=</span><span class="mi">6</span><span class="p">){</span> <span class="c1">//little hack to keep it at the bottom of the IE window</span>
</span><span class="line">						<span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#console-log&#39;</span><span class="p">).</span><span class="nx">css</span><span class="p">(</span><span class="s1">&#39;position&#39;</span><span class="p">,</span><span class="s1">&#39;absolute&#39;</span><span class="p">);</span>
</span><span class="line">						<span class="nx">setInterval</span><span class="p">(</span><span class="kd">function</span><span class="p">(){</span>
</span><span class="line">							<span class="nx">logpanel</span><span class="p">.</span><span class="nx">css</span><span class="p">(</span><span class="s1">&#39;height&#39;</span><span class="p">,</span><span class="s1">&#39;99px&#39;</span><span class="p">);</span>
</span><span class="line">							<span class="nx">logpanel</span><span class="p">.</span><span class="nx">css</span><span class="p">(</span><span class="s1">&#39;height&#39;</span><span class="p">,</span><span class="s1">&#39;100px&#39;</span><span class="p">);</span>
</span><span class="line">						<span class="p">},</span><span class="mi">250</span><span class="p">);</span>
</span><span class="line">					<span class="p">}</span>
</span><span class="line">				<span class="p">}</span>
</span><span class="line">				<span class="nx">logpanel</span><span class="p">.</span><span class="nx">append</span><span class="p">([</span><span class="nx">msg</span><span class="p">,</span><span class="s2">&quot;&quot;</span><span class="p">].</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">));</span>
</span><span class="line">				<span class="nx">logpanel</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">scrollTop</span> <span class="o">=</span> <span class="nx">logpanel</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">scrollHeight</span><span class="p">;</span>
</span><span class="line">			<span class="p">}</span>
</span><span class="line">		<span class="p">};</span>
</span><span class="line">
</span><span class="line">		<span class="nx">r</span><span class="p">.</span><span class="nx">init</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">g</span><span class="p">){</span>
</span><span class="line">			<span class="nx">glow</span> <span class="o">=</span> <span class="nx">g</span><span class="p">;</span>
</span><span class="line">			<span class="nx">$</span> <span class="o">=</span> <span class="nx">glow</span><span class="p">.</span><span class="nx">dom</span><span class="p">.</span><span class="nx">get</span><span class="p">;</span>
</span><span class="line">		<span class="p">};</span>
</span><span class="line">
</span><span class="line">		<span class="k">return</span> <span class="nx">r</span><span class="p">;</span>
</span><span class="line">	<span class="p">}();</span>
</span><span class="line">
</span><span class="line">	<span class="nx">console</span><span class="p">.</span><span class="nx">init</span><span class="p">(</span><span class="nx">glow</span><span class="p">);</span>
</span><span class="line"><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>I&#8217;m using the <a href="http://www.bbc.co.uk/glow">Glow</a> library to do this, go check it out it&#8217;s really very good! (<strong>Update:</strong> although, now, sadly discontinued thanks to BBC cutbacks )</p>

<p>So basically what we&#8217;re doing is a test to see whether <code>console</code>, and indeed <code>console.log</code> exist or not. If they do we don&#8217;t need to bother. Let&#8217;s presume that it <em>doesn&#8217;t</em> exist.</p>

<p>We then define <code>console</code> but the way we do it may not be familiar to some. Let&#8217;s strip it back to make it easier to look at:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>Javscript</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
</pre></td><td class="code"><pre><code class="javascript"><span class="line"><span class="nb">window</span><span class="p">.</span><span class="nx">console</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(){</span>
</span><span class="line">	<span class="k">return</span> <span class="p">{};</span>
</span><span class="line"><span class="p">}();</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>I&#8217;m setting <code>window.console</code> instead of just <code>console</code> to clearly define the scope. <code>window</code> is available to everything and so setting <code>console</code> on <code>window</code> means it will be available wherever it&#8217;s called.</p>

<p>It looks initially like I&#8217;m defining <code>console</code> to be a function but straight after the closing brace of the function you&#8217;ve got the open and close parentheses which runs the function immediately. This has the effect of setting <code>window.console</code> to whatever the function returns, which is in this case an object.</p>

<p>If, as in the case of the finished code, the object returned (<code>r</code>) has properties then they will be accessible at <code>window.console.property</code>. And of course, the property can also be a function, like <code>log</code>.</p>

<h2 id="fully-functional">Fully functional</h2>

<p>The functions that are defined here are:</p>

<ul>
  <li><code>enable</code></li>
  <li><code>disable</code></li>
  <li><code>clear</code></li>
  <li><code>log</code></li>
  <li><code>init</code></li>
</ul>

<p>The console is disabled by default. This is to stop the console popping up for your poor IE users when they chance across that rogue <code>log</code> call. You have to <em>want</em> the console on to get it. This doesn&#8217;t mean it&#8217;s completely ineffective when disabled, though. The function still exists meaning you won&#8217;t see any script errors or terminated JavaScript.</p>

<p>To enable it, simple call <code>console.enable();</code>. You don&#8217;t have to do this in the code (I&#8217;d advise against it as you could forget to take that out too!). Unless you are debugging specifically for IE and specifically for something that happens automatically on page load I&#8217;d recommend enabling it manually by typing <code>javascript:console.enable();</code> into the address bar and press enter.</p>

<p>Likewise to disable the console, just type <code>javascript:console.disable();</code>, or to clear it type <code>javascript:console.clear();</code>.</p>

<p>If you find yourself typing into the address bar a lot, you could drag one or more of these bookmarklets onto the bookmarks bar to make it easier:</p>

<p><a href="javascript:console.enable(\);">Enable console</a> <a href="javascript:console.disable(\);">Disable console</a> <a href="javascript:console.clear(\);">Clear console</a></p>

<p>The reason I&#8217;ve included an <code>init</code> function is because Glow supports a <a href="http://www.bbc.co.uk/glow/docs/articles/gloader.shtml#tocHeading1.13">sandboxing feature</a> it&#8217;s useful to be able to pass a specific version of the library to <code>console</code> to use. If you&#8217;re not worried about that sort of thing then you don&#8217;t need to include it and it will still work so long as you load glow before this script and map <a href="http://www.bbc.co.uk/glow/docs/1.7/api/glow.dom.shtml"><code>glow.dom.get</code></a> to <code>$</code>.</p>

<p>Finally the <code>log</code> function is where the magic happens. The bulk of the function is, if the log panel doesn&#8217;t exist already to create it. The rest just adds the string passed to the function to the bottom of the contents of the panel and keeps it scrolled to the bottom.</p>

<p>There&#8217;s really not a lot to it!</p>

<h2 id="got-console">Got console?</h2>

<p>Since getting it&#8217;s rather nice developer suite, WebKit has sprouted a <code>console</code> too which is fab! It&#8217;s accessible on Chrome and Safari under the developer menus. Of course this script won&#8217;t affect those browsers but IE, Opera and Firefox without Firebug can still benefit from it.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[PayPal, for shame]]></title>
    <link href="http://blog.norestfortheweekend.com/blog/2009/11/28/paypal-for-shame/"/>
    <updated>2009-11-28T12:12:14+00:00</updated>
    <id>http://blog.norestfortheweekend.com/blog/2009/11/28/paypal-for-shame</id>
    <content type="html"><![CDATA[<p><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2009/11/shameless.jpg" width="628" height="150" title="'Screengrab of the PayPal homepage header, the word PayPal replaced with the word ShameLess'" /></p>

<p><a href="http://www.paypal.com">PayPal</a> is, as I’m sure you know, a long-standing staple of online payment technologies. They are now merged with eBay and you pretty much can’t use eBay without a PayPal account which works nicely for eBay as they are now reaping the benefit of not just the eBay selling fees but also the PayPal fees.</p>

<p>But this is not a post to lament how much money eBay/PayPal are raking in from punters.</p>

<h2 id="nice-and-easy">Nice and easy</h2>

<p>As well as a payment service for eBay, PayPal also offer shopping basket and checkout services for small online merchants who don’t want to buy and maintain e-commerce products. It works nicely and provided you don’t mind PayPal taking their cut it provides a really simple way of being able to take credit cards securely.</p>

<h2 id="prepare-yourself">Prepare yourself</h2>

<p>I was recently asked to add some shopping functions to a site using PayPal. Here is one of the nine code snippets PayPal provided me with to insert a button into my page:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>Paypal&#8217;s Button Code    </span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
<span class="line-number">13</span>
<span class="line-number">14</span>
<span class="line-number">15</span>
<span class="line-number">16</span>
<span class="line-number">17</span>
</pre></td><td class="code"><pre><code class="html"><span class="line"><span class="nt">&lt;form</span> <span class="na">action=</span><span class="s">&quot;https://www.paypal.com/cgi-bin/webscr&quot;</span> <span class="na">target=</span><span class="s">&quot;paypal&quot;</span> <span class="na">method=</span><span class="s">&quot;post&quot;</span><span class="nt">&gt;</span>
</span><span class="line"><span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">&quot;hidden&quot;</span> <span class="na">name=</span><span class="s">&quot;cmd&quot;</span> <span class="na">value=</span><span class="s">&quot;_s-xclick&quot;</span><span class="nt">&gt;</span>
</span><span class="line"><span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">&quot;hidden&quot;</span> <span class="na">name=</span><span class="s">&quot;hosted_button_id&quot;</span> <span class="na">value=</span><span class="s">&quot;xxxxxxx&quot;</span><span class="nt">&gt;</span>
</span><span class="line"><span class="nt">&lt;table&gt;</span>
</span><span class="line"><span class="nt">&lt;tr&gt;&lt;td&gt;&lt;input</span> <span class="na">type=</span><span class="s">&quot;hidden&quot;</span> <span class="na">name=</span><span class="s">&quot;on0&quot;</span> <span class="na">value=</span><span class="s">&quot;Sizes&quot;</span><span class="nt">&gt;</span>Sizes<span class="nt">&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;select</span> <span class="na">name=</span><span class="s">&quot;os0&quot;</span><span class="nt">&gt;</span>
</span><span class="line">	<span class="nt">&lt;option</span> <span class="na">value=</span><span class="s">&quot;XXSmall&quot;</span><span class="nt">&gt;</span>XXSmall £20.00<span class="nt">&lt;/option&gt;</span>
</span><span class="line">	<span class="nt">&lt;option</span> <span class="na">value=</span><span class="s">&quot;XSmall&quot;</span><span class="nt">&gt;</span>XSmall £20.00<span class="nt">&lt;/option&gt;</span>
</span><span class="line">	<span class="nt">&lt;option</span> <span class="na">value=</span><span class="s">&quot;Small&quot;</span><span class="nt">&gt;</span>Small £20.00<span class="nt">&lt;/option&gt;</span>
</span><span class="line">	<span class="nt">&lt;option</span> <span class="na">value=</span><span class="s">&quot;Medium&quot;</span><span class="nt">&gt;</span>Medium £20.00<span class="nt">&lt;/option&gt;</span>
</span><span class="line">	<span class="nt">&lt;option</span> <span class="na">value=</span><span class="s">&quot;Large&quot;</span><span class="nt">&gt;</span>Large £20.00<span class="nt">&lt;/option&gt;</span>
</span><span class="line">	<span class="nt">&lt;option</span> <span class="na">value=</span><span class="s">&quot;XLarge&quot;</span><span class="nt">&gt;</span>XLarge £20.00<span class="nt">&lt;/option&gt;</span>
</span><span class="line"><span class="nt">&lt;/select&gt;</span> <span class="nt">&lt;/td&gt;&lt;/tr&gt;</span>
</span><span class="line"><span class="nt">&lt;/table&gt;</span>
</span><span class="line"><span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">&quot;hidden&quot;</span> <span class="na">name=</span><span class="s">&quot;currency_code&quot;</span> <span class="na">value=</span><span class="s">&quot;GBP&quot;</span><span class="nt">&gt;</span>
</span><span class="line"><span class="nt">&lt;input</span> <span class="na">src=</span><span class="s">&quot;https://www.paypal.com/en_GB/i/btn/btn_cart_LG.gif&quot;</span> <span class="na">border=</span><span class="s">&quot;0&quot;</span> <span class="na">type=</span><span class="s">&quot;image&quot;</span> <span class="na">name=</span><span class="s">&quot;submit&quot;</span> <span class="na">alt=</span><span class="s">&quot;PayPal - The safer, easier way to pay online.&quot;</span><span class="nt">&gt;</span>
</span><span class="line"><span class="nt">&lt;img</span> <span class="na">src=</span><span class="s">&quot;https://www.paypal.com/en_GB/i/scr/pixel.gif&quot;</span> <span class="na">alt=</span><span class="s">&quot;&quot;</span> <span class="na">height=</span><span class="s">&quot;1&quot;</span> <span class="na">border=</span><span class="s">&quot;0&quot;</span> <span class="na">width=</span><span class="s">&quot;1&quot;</span><span class="nt">&gt;</span>
</span><span class="line"><span class="nt">&lt;/form&gt;</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>Oh PayPal, how do you sadden me? Let me count the ways…</p>

<h2 id="spot-the-nastiness">Spot the nastiness</h2>

<p>Well being generous, there are 7 horrible things about that above code snippet. If I count each problem every time it appears I reach a grand total of 12. Bleugh.</p>

<p>Let me run through exactly what I take issue with, because I really don’t think I’m being unreasonable.</p>

<h3 id="inputs">Inputs</h3>

<p>There are a lot of hidden <code>input</code>s. No, I understand - they need to be there to make it work. That makes sense. What doesn’t make sense is that they don’t bother to close off the <code>input</code>s, XHTML style.</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>Input, done correctly</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
</pre></td><td class="code"><pre><code class="html"><span class="line"><span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">&quot;hidden&quot;</span> <span class="na">name=</span><span class="s">&quot;name&quot;</span> <span class="na">value=</span><span class="s">&quot;value&quot;</span> <span class="nt">/&gt;</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>Simple.</p>

<h3 id="tables">Tables</h3>

<p>Really? Tables? But look at it. What does it actually do? Absolutely nothing, apart from put the text and the select side by side, which is a choice for the designer to make. No <code>tbody</code>, no <code>th</code>’s, and so there’s no chance in hell of any <code>scope=</code>’s.</p>

<p>Pointless.</p>

<h3 id="select-with-no-id-and-no-label">Select with no id and no label</h3>

<p>I don’t think I need to say a lot about this - the title says it all. They’ve put the text that should be in the label in plain text instead. They could have used the table (if they insisted on having one) to help with this by putting the label text in a th, but they didn’t even do that.</p>

<h3 id="input-type-image">Input type: image</h3>

<p>Again, no problem in using an input of type image. But wait… they didn’t specify the width and height! If they are going to go for a consistent look, as they appear to be doing with their tables mentioned earlier, then this is essential. Otherwise, rogue styles applied to all <code>input</code>s will seriously mess up the look of the button.</p>

<h3 id="alt-text">Alt text</h3>

<p>Possibly the worst offender of all.</p>

<p>Check it out, aren’t PayPal good? They added alt text and everything. Except the alt text is on the image input element - the submit button - and it isn’t at all descriptive. It’s basically an advert for PayPal. </p>

<p>What good is that to <abbr title="Assistive Technology">AT</abbr> users? They would have <strong>no clue</strong> as to what that control does.</p>

<h3 id="spacer-gif">Spacer gif</h3>

<p>Yes, for no apparent reason there is a spacer gif at the bottom of it all. And yes, it has no XHTML closing slash.</p>

<h3 id="no-enclosing-element">No enclosing element</h3>

<p>Oh yes, one last one. <code>input</code> elements can’t reside directly inside the <code>form</code> element. They need to be contained within any one of a variety of other elements (Eg. <code>p</code>, <code>div</code>, etc.). Sadly, there is nothing protecting our <code>input</code>s from the harsh reality of their <code>form</code> overlord.</p>

<h2 id="the-way-it-should-be">The way it <em>should</em> be</h2>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>Paypal&#8217;s Button Code - Fixed    </span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
<span class="line-number">13</span>
<span class="line-number">14</span>
<span class="line-number">15</span>
<span class="line-number">16</span>
<span class="line-number">17</span>
<span class="line-number">18</span>
<span class="line-number">19</span>
<span class="line-number">20</span>
</pre></td><td class="code"><pre><code class="html"><span class="line"><span class="nt">&lt;form</span> <span class="na">action=</span><span class="s">&quot;https://www.paypal.com/cgi-bin/webscr&quot;</span> <span class="na">target=</span><span class="s">&quot;paypal&quot;</span> <span class="na">method=</span><span class="s">&quot;post&quot;</span><span class="nt">&gt;</span>
</span><span class="line">	<span class="nt">&lt;div&gt;</span>
</span><span class="line">		<span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">&quot;hidden&quot;</span> <span class="na">name=</span><span class="s">&quot;cmd&quot;</span> <span class="na">value=</span><span class="s">&quot;_s-xclick&quot;</span><span class="nt">&gt;&lt;/input&gt;</span>
</span><span class="line">		<span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">&quot;hidden&quot;</span> <span class="na">name=</span><span class="s">&quot;hosted_button_id&quot;</span> <span class="na">value=</span><span class="s">&quot;xxxxxxx&quot;</span><span class="nt">&gt;&lt;/input&gt;</span>
</span><span class="line">		<span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">&quot;hidden&quot;</span> <span class="na">name=</span><span class="s">&quot;on0&quot;</span> <span class="na">value=</span><span class="s">&quot;Sizes&quot;</span><span class="nt">&gt;&lt;/input&gt;</span>
</span><span class="line">		<span class="nt">&lt;label</span> <span class="na">for=</span><span class="s">&quot;sizes-polo&quot;</span><span class="nt">&gt;</span>Sizes<span class="nt">&lt;/label&gt;</span>
</span><span class="line">		<span class="nt">&lt;select</span> <span class="na">name=</span><span class="s">&quot;os0&quot;</span> <span class="na">id=</span><span class="s">&quot;sizes-polo&quot;</span><span class="nt">&gt;</span>
</span><span class="line">			<span class="nt">&lt;option</span> <span class="na">value=</span><span class="s">&quot;XXSmall&quot;</span><span class="nt">&gt;</span>XXSmall £20.00<span class="nt">&lt;/option&gt;</span>
</span><span class="line">			<span class="nt">&lt;option</span> <span class="na">value=</span><span class="s">&quot;XSmall&quot;</span><span class="nt">&gt;</span>XSmall £20.00<span class="nt">&lt;/option&gt;</span>
</span><span class="line">			<span class="nt">&lt;option</span> <span class="na">value=</span><span class="s">&quot;Small&quot;</span><span class="nt">&gt;</span>Small £20.00<span class="nt">&lt;/option&gt;</span>
</span><span class="line">			<span class="nt">&lt;option</span> <span class="na">value=</span><span class="s">&quot;Medium&quot;</span><span class="nt">&gt;</span>Medium £20.00<span class="nt">&lt;/option&gt;</span>
</span><span class="line">			<span class="nt">&lt;option</span> <span class="na">value=</span><span class="s">&quot;Large&quot;</span><span class="nt">&gt;</span>Large £20.00<span class="nt">&lt;/option&gt;</span>
</span><span class="line">			<span class="nt">&lt;option</span> <span class="na">value=</span><span class="s">&quot;XLarge&quot;</span><span class="nt">&gt;</span>XLarge £20.00<span class="nt">&lt;/option&gt;</span>
</span><span class="line">		<span class="nt">&lt;/select&gt;</span>
</span><span class="line">		<span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">&quot;hidden&quot;</span> <span class="na">name=</span><span class="s">&quot;currency_code&quot;</span> <span class="na">value=</span><span class="s">&quot;GBP&quot;</span><span class="nt">&gt;&lt;/input&gt;</span>
</span><span class="line">		<span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;controls&quot;</span><span class="nt">&gt;</span>
</span><span class="line">			<span class="nt">&lt;input</span> <span class="na">src=</span><span class="s">&quot;https://www.paypal.com/en_GB/i/btn/btn_cart_LG.gif&quot;</span> <span class="na">name=</span><span class="s">&quot;submit&quot;</span> <span class="na">height=</span><span class="s">&quot;26&quot;</span> <span class="na">width=</span><span class="s">&quot;120&quot;</span> <span class="na">alt=</span><span class="s">&quot;Add a polo shirt in the selected size to your cart&quot;</span> <span class="na">type=</span><span class="s">&quot;image&quot;</span> <span class="na">class=</span><span class="s">&quot;image&quot;</span><span class="nt">&gt;&lt;/input&gt;</span>
</span><span class="line">		<span class="nt">&lt;/div&gt;</span>
</span><span class="line">	<span class="nt">&lt;/div&gt;</span>
</span><span class="line"><span class="nt">&lt;/form&gt;</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>Much better. Notice that for the alt text I mentioned which item was being added and referenced the size select box in case they <abbr title="Assistive Technology">AT</abbr> user might have missed that, or not made a selection yet.</p>

<h2 id="why-am-i-picking-on-paypal">Why am I picking on PayPal?</h2>

<p>Well, I’m sure that many other large companies are equally guilty of this sort of thing. And as I come across them, if they enrage me enough I’m sure I’ll rant about them as well. But really, PayPal should know better. They even have people coming to (and sponsor) events (like <a href="http://www.barcamp.org/">BarCamp</a>) where the attendees know exactly how bad this sort of this is.</p>

<p>Hopefully if enough people make a fuss, these things will change. Don’t tolerate it! And most of all, never blindly cut and paste markup from another site. It’ll only make you look bad.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[BarCamp London 7]]></title>
    <link href="http://blog.norestfortheweekend.com/blog/2009/11/09/barcamp-london-7/"/>
    <updated>2009-11-09T15:06:47+00:00</updated>
    <id>http://blog.norestfortheweekend.com/blog/2009/11/09/barcamp-london-7</id>
    <content type="html"><![CDATA[<p><a href="http://www.flickr.com/photos/adewale_oshineye/3405080707/in/pool-barcamplondon"><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2009/11/barcamp7-lego.jpg" width="628" height="142" title="'BarCamp'" /></a></p>

<p>Well I didn’t quite know what to expect having never attended a BarCamp or indeed an “un-conference” before. What I found was one of the best geek-xperiences that I have come across, something that I would recommend to anyone into what they do and who enjoys the company of other people also into what they do.</p>

<h2 id="un-conference">Un-conference</h2>

<p>So the premise behind an un-conference is that there are talks, but there is nothing scheduled when the event starts. Instead, right at the start all the attendees fill out the gaps in the schedule with sessions, presentations and talks that they have prepared (or will prepare over the course of the event). Everyone is encouraged to participate, especially those for whom it is their first BarCamp, which meant I was going to be doing one.</p>

<p><a href="http://www.flickr.com/photos/yaili/4062052486/"><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2009/11/barcamp7-saturdaysessions.jpg" width="628" height="184" title="'The grid for the sessions on Saturday'" /></a></p>

<p>Public speaking isn’t one of my stronger qualities, but one thing I do know about it is that the more you do it the better (and the more confident) you get. This is a fact, and it’s also helped by the fact that all the attendees are lovely. The thing about this kind of event is that no-one is going to want to pick a fight with you or want to make you feel small. If they attended your presentation in preference to someone else’s then they genuinely want to hear what you have to say on the topic you have chosen. Also, most people will be in the same boat - all having their own sessions to run - and so they will treat you in the way they hope to be treated themselves. Finally, as it’s a free event, no-one will feel cheated if your talk doesn’t live up to the high expectations that might surround a conference which costs, say, £300. It’s the perfect incubator for talent!</p>

<h2 id="variety-is-the-spice-of-life-and-barcamps">Variety is the spice of life, and BarCamps</h2>

<p>The sessions can be on anything, and when I say anything I mean <em>anything</em>. There were sessions on topics varying from CSS to Erotic Writing, the alcohol ban parties on the Tube to multi touch programming on Snow Leopard and from Autism to LOST. Whatever your interest or topic of expertise, there will always be people interested in what you have to say!</p>

<p>I’d say my main complaint about the event is that you can’t attend all the sessions! Obviously with so many sessions happening all at once, filming them all would be tricky and so it’s very much a case of if you miss it you miss it, so don’t miss it!</p>

<h2 id="free-is-my-favourite-price">Free is my favourite price</h2>

<p>BarCamp is free. I say that; it must have taken some serious clout to pull it all together but to the attendees it’s free. It’s all done through sponsorship and the generously donated time of the wonderful team that organise it all. The sponsors are many which means they all only need to donate a little to add up to a decent pot of cash. That said, the prominence of the sponsors was minimal which I think added to the general feel of the event. It was all about sharing ideas and information and not wanting anything back for it - a fine and noble idea, and one I can get behind.</p>

<p>Of course staff from the sponsors are free to come along and give presentations (which the did, at least in some cases) but these are usually pretty interesting, at least to some people. And hey, if you don’t find it interesting you don’t have to go - there are probably 7-8 other talks happening at the same time… take your pick!</p>

<h2 id="my-experiences">My experiences</h2>

<p><a href="http://www.flickr.com/photos/andypiper/4040452848/in/pool-barcamplondon"><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2009/11/barcamp7-css.jpg" width="628" height="190" title="'My talk on CSS widgets'" /></a></p>

<p>I had already decided to do a CSS-related presentation (a blog version of which is forthcoming) but sadly this meant I had to miss a chunk of sessions during the first day just in the name of finishing off. I wish I had started to prepare earlier but it’s that always the case? It had to be done though… imagine turning up to do a talk with a half-finished set of slides. Not too impressive.</p>

<p>So what follows is a list of the sessions I attended (or would have attended if I hadn’t been preparing my own):</p>

<h3 id="saturday">Saturday</h3>

<ul>
  <li>BarCamp Bootstrap: 1st Timers Panel</li>
  <li>How we broke the tube with Facebook (Steve Emslie)</li>
  <li>Google Street View + Virtual Reality Goggles (Tom Scott) (Regrettably missed)</li>
  <li>CSS Nuggets - Some snippets of CSS that will help you make better sites and stuff (<a href="http://www.twitter.com/anna_debenham">Anna Debenham</a>) (Regrettably missed)</li>
  <li>Split fares aka Hack yourself a cheaper train ticket (<a href="http://www.twitter.com/@sammachin">Sam Machin</a>) (Regrettably missed)</li>
  <li>Mobile Stats 2008-2009 (<a href="http://www.twitter.com/adamcohenrose">Adam Cohen-Rose</a>)</li>
  <li>Design in Lost (yes, the TV show) (<a href="http://www.twitter.com/yaili">Inayaili de Leon</a>)</li>
  <li>Don’t break my stuff! A guide to writing CSS for widgets and pages with widgets (<a href="http://www.twitter.com/markstickley">Mark Stickley</a>) (My session!)</li>
  <li>Want to write a tech book? (Gavin Bell)</li>
  <li>Sex and other things we don’t talk about (<a href="http://www.twitter.com/cubicgarden">Ian Forrester</a>)</li>
  <li>Why I give web clients no control over their project (and why they love it) (<a href="http://www.twitter.com/xigme">Alex Teugels</a>)</li>
  <li>Web Scale Identifiers (Use and Abuse) (Ade)</li>
</ul>

<h3 id="sunday">Sunday</h3>

<ul>
  <li>Linked Data and the Semantic Web for Dummies (<a href="http://www.twitter.com/dfflanders">David F. Flanders</a>)</li>
  <li>Designing for the teenage generation - what they ‘dig’ (<a href="http://www.twitter.com/Jack_Franklin">Jack Franklin</a>)</li>
  <li>Multitouch: on Snow Leopard + Quartz Composer &amp; Chuck (<a href="http://www.twitter.com/gernot">@gernot</a>)</li>
  <li>10 Fucking Awesome Bands You Should Be Listening To (<a href="http://www.twitter.com/maryrosecook">Mary Rose Cook</a>)</li>
  <li>Putting telly on the Internet (<a href="http://www.twitter.com/dfflanders">David F. Flanders</a>)</li>
  <li>Photography is not a crime (know your rights as a photographer) (<a href="http://www.twitter.com/martin88">Martin C</a>)</li>
  <li>Lightning Talks</li>
  <li>Teach Me How To Run A New BarCamp - Cultures, Languages (BSL) (<a href="http://www.twitter.com/bjfletcher">@bjfletcher</a>)</li>
  <li>Autism, Internet and Antelope: Cognitive Accessibility and how people with autism use the web (Jamie + Lion)</li>
</ul>

<p>If you’re interested in the full list of available talks, here’s the <a href="http://tommorris.org/files/barcamp_saturday.html">Saturday talks</a> and the <a href="http://tommorris.org/files/barcamp_sunday.html">Sunday talks</a>.</p>

<p>I’ll just run over the panels that I actually went to and remember enough of to talk about extremely briefly to give some idea as to how they went.</p>

<h3 id="barcamp-bootstrap">BarCamp Bootstrap</h3>

<p>A brief introduction to BarCamps for first-timers. I figured I’d only be a first-timer once so why not pop along. We were told to enjoy it and given brief tactical instructions on the inevitable games of Werewolf that would take place overnight. Then we took part in an exercise which was supposed to both help us get over our fear of public speaking and put us more about saying something stupid by actually standing up and saying something stupid (we were fed a line) in front of everyone else. Good introduction!</p>

<h3 id="how-we-broke-the-tube">How we broke the tube</h3>

<p>Brief account of a couple of guys who innocently created a Facebook group encouraging people to go and have a “last drink” on the tube the night before the alcohol ban came into force and thought nothing more of it. Until it started to gain massive traction ultimately shutting down large parts of the tube on the night in question! They also asked if anyone knew how to mine the Facebook data to try and find who was responsible for the tipping point which caused such a huge uptake.</p>

<h3 id="mobile-stats">Mobile stats</h3>

<p>Basically going through a bunch of stats on mobile device usage which showed the screen resolution of devices is quite rapidly on the up and how Apple crept up from 6th place to 5th in the device manufacturers sales charts in just one year.</p>

<h3 id="design-in-lost">Design in LOST</h3>

<p><a href="http://www.flickr.com/photos/yaili/4061297865/"><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2009/11/barcamp7-lost.jpg" width="628" height="189" title="'Card for @yaili's session on LOST'" /></a></p>

<p>Going over some of the finer points of the hit TV show and showing how the plot and prop design goes so in depth that you wouldn’t really notice some of the more elaborate details unless you were paying meticulous attention. Also covered some of the cross promotion with other brands and Easter Eggs that don’t add anything but are a real treat to those who spot them. Fascinating!</p>

<h3 id="want-to-write-a-tech-book">Want to write a tech book</h3>

<p><a href="http://www.flickr.com/photos/37996583811@N01/4039838641/"><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2009/11/barcamp7-adewale.jpg" width="628" height="151" title="'Adewale &amp; Gavin doing their book writing talk'" /></a></p>

<p>Tips mainly on how not to write a tech book actually! Don’t drag it out and don’t try and do it as well as a full-time job were the main ones I took away from that.</p>

<h3 id="sex-and-other-things">Sex and other things</h3>

<p><a href="http://www.flickr.com/photos/adewale_oshineye/3405087239/in/pool-barcamplondon"><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2009/11/barcamp7-cubicgarden.jpg" width="628" height="187" title="'Ian Forrester'" /></a></p>

<p>What was essentially a hosted discussion about geeks, sexuality, how comfortable we are with it and why. It was interesting to listen to but I wasn’t compelled to get involved…</p>

<h3 id="why-i-give-my-clients-no-control">Why I give my clients no control</h3>

<p><a href="http://www.norestfortheweekend.com/wp-content/uploads/2009/11/barcamp7-alex.jpg"><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2009/11/barcamp7-alex.jpg" width="628" height="158" title="'Alex Teugels and some guy I don't know the name of'" /></a>](http://www.flickr.com/photos/bfirsh/4047990809/in/pool-barcamplondon)</p>

<p>Alex took us through how he runs his business which is basically to take complete control of his clients’ sites, charge them an ongoing fee and make sure conversions keep moving skywards. A very different and interesting approach which I haven’t seen before. Strangely enough this talk was given by an old school friend of mine who I hadn’t seen since all those years ago which was an unexpected bonus!</p>

<h3 id="web-scale-identifiers">Web Scale Identifiers</h3>

<p>An interesting talk that gave way to an interesting discussion that went on for almost an hour! It’s basically an idea that’s floating around that “wouldn’t it be nice if people would stop making their own ids for objects and start using standard ones.” For example, books have ISBNs. But what about things that don’t have a centralised authority? How do you identify the id to use? Very interesting.</p>

<h3 id="designing-for-teenagers">Designing for teenagers</h3>

<p>As a teenager himself, Jack gave us an insight into what they like and what they are indifferent to. Turns out that the average teenager doesn’t give two hoots about fancy CSS3 rounded corners, gradients and the like - they are mostly interested in the content. Especially flash games. I still can’t help thinking, though, that if there was some excellent content or games available but the design was terrible they wouldn’t really be so interested…</p>

<h3 id="multi-touch-on-snow-leopard">Multi touch on Snow Leopard</h3>

<p>This was an interesting talk on programming with Quartz and the presenter demoed his own test app in which he showed how the trackpads on modern MacBooks can detect up to 11 simultaneous touches. Pretty incredible!</p>

<h3 id="fucking-awesome-bands">10 Fucking Awesome Bands</h3>

<p><a href="http://www.flickr.com/photos/adewale_oshineye/4041691950/"><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2009/11/barcamp7-mary.jpg" width="628" height="174" title="'Mary Rose Cook'" /></a></p>

<p>Mary took us through 10 bands which in her opinion no-one should be without. Most of them were not so much to my taste but you can’t please them all, eh? Afterwards she took suggestions of other bands that should be added to the list.</p>

<h3 id="putting-telly-on-the-internet">Putting telly on the internet</h3>

<p>Some of the more technical challenges the iPlayer team have experienced. Very interesting stuff.</p>

<h3 id="photography-is-not-a-crime">Photography is not a crime</h3>

<p>Fascinating talk on photographers rights and how little law enforcement actually seems to understand them on the whole. Basically, anything you can see while standing in a public place is legal and fair game, although snapping people’s kids and other such intrusions are usually misunderstood and it pays to ask first. It’s just polite!</p>

<h3 id="lightning-talks">Lightning talks</h3>

<p>The lightning talks session is actually a series of 5 minute talks by whoever wants to do them. The trouble with these is they aren’t really long enough to be that memorable… I do remember one about a collaborative art project which was quite interesting.</p>

<h3 id="teach-me-how-to-run-a-barcamp">Teach me how to run a BarCamp</h3>

<p>This was kind of a ‘reverse’ session where the guy running it basically asked the audience their advice on how to set up, publicise, fund, organise and run a BarCamp… for deaf people! The responses were interesting, especially when discussing the advantages of a deaf-only event.</p>

<h3 id="autism">Autism</h3>

<p><a href="http://www.flickr.com/photos/rugbymadgirl/4047724494/in/pool-barcamplondon"><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2009/11/barcamp7-jamie.jpg" width="628" height="173" title="'Jamie &amp; Lion'" /></a></p>

<p>Jamie (and his friend <a href="http://www.imetlion.com">Lion</a>) gave an interesting talk on how cognitive diversity affects internet use and taught us all a little about autism and how it affects people. Very useful indeed!</p>

<h2 id="recommended">Recommended</h2>

<p>BarCamp was not only a lot of fun but it was valuable, interesting and a good opportunity to meet nice people. It was also very exhausting, but the lack of sleep was my own fault! I hope to be attending many more in the future.</p>

<p><a href="http://www.flickr.com/photos/timblair/4040914375/"><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2009/11/barcamp7-asleep.jpg" width="628" height="233" title="'Yours truly failing to stay awake'" /></a></p>

<p>Check out the <a href="http://barcamp.org/">BarCamp wiki</a> for more information on BarCamps and to find your next local event. Alternatively you can go to the <a href="http://www.barcamplondon.org/">BarCamp London site</a> which was the fine event this article is written about!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[On forms, submit buttons and browsers]]></title>
    <link href="http://blog.norestfortheweekend.com/blog/2009/10/20/on-forms-submit-buttons-and-browsers/"/>
    <updated>2009-10-20T10:10:52+01:00</updated>
    <id>http://blog.norestfortheweekend.com/blog/2009/10/20/on-forms-submit-buttons-and-browsers</id>
    <content type="html"><![CDATA[<p>Aah, ambiguity! What a tricky devil you are. The <a href="http://www.w3.org">W3C</a> Recommendations are normally very specific and not at all ambiguous, but when things are left open to interpretation you can be fairly sure of varying results.</p>

<h2 id="bad-form-old-chap">Bad form, old chap</h2>

<p>Have a look at this form:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>HTML    </span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
</pre></td><td class="code"><pre><code class="html"><span class="line"><span class="nt">&lt;form</span> <span class="na">action=</span><span class="s">&quot;wherever.html&quot;</span> <span class="na">method=</span><span class="s">&quot;post&quot;</span><span class="nt">&gt;</span>
</span><span class="line">    <span class="nt">&lt;label</span> <span class="na">for=</span><span class="s">&quot;firstname&quot;</span><span class="nt">&gt;</span>First name<span class="nt">&lt;/label&gt;</span>
</span><span class="line">    <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">&quot;text&quot;</span> <span class="na">name=</span><span class="s">&quot;firstname&quot;</span> <span class="na">id=</span><span class="s">&quot;firstname&quot;</span><span class="nt">&gt;&lt;/input&gt;</span>
</span><span class="line">    <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">&quot;submit&quot;</span> <span class="na">name=</span><span class="s">&quot;proceed&quot;</span> <span class="na">value=</span><span class="s">&quot;Proceed&quot;</span><span class="nt">&gt;&lt;/input&gt;</span>
</span><span class="line">    <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">&quot;submit&quot;</span> <span class="na">name=</span><span class="s">&quot;back&quot;</span> <span class="na">value=</span><span class="s">&quot;Back&quot;</span><span class="nt">&gt;&lt;/input&gt;</span>
</span><span class="line"><span class="nt">&lt;/form&gt;</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>What gets submitted when you hit Proceed? Well yes, <code>firstname</code> is included as is <code>proceed</code>, but is <code>back</code>? What gets submitted when you hit Back, as the second submit button in the form?</p>

<p>Well the <a href="http://www.w3.org/TR/html401/interact/forms.html#submit-format">W3C Guidelines on form submission</a> say that for forms with more than one submit button, only the submit button that was pressed should be submitted. This seems fair enough.</p>

<p><strong>But what gets submitted when you press enter from within the text field?</strong></p>

<p>The W3C has no recommendation for this! The precise wording used to qualify whether a submit button gets sent along with the other form data is:</p>

<blockquote>
  <p>If a form contains more than one submit button, only the activated submit button is successful.</p>
</blockquote>

<p>…where ‘activated’ means having been clicked on to submit the form and being ‘successful’ refers to the selection process for including form elements in the request.</p>

<h2 id="pressing-the-right-buttons-or-not-as-the-case-may-be">Pressing the right buttons (or not, as the case may be)</h2>

<p>What actually happens varies between browsers, which I suppose is no surprise really. The surprise is which browsers do what.</p>

<p>We see two behaviors here:</p>

<ul>
  <li>IE (I tested 6, 7 &amp; 8) works on the basis that you only submit an <em>activated</em> form element and the only way to activate a submit button is to <em>click on it</em>. Therefore if you click on a submit button, IE will submit it’s value along with the rest of the form, but if you press <em>Enter</em> to submit it doesn’t submit the value of <em>any</em> submit buttons.</li>
  <li>All other browsers (tested: Firefox, Safari, Chrome, Opera) submit a value for a submit button, <em>whether or not you click it</em>. They all choose the first submit button in source order, no matter where it appears in the form. Thank goodness that’s consistent!</li>
</ul>

<p>I guess that the other browsers think it’s fair to assume that pressing enter while entering data into a form is the same as clicking on the submit button, which in most cases it is. But what happens when you’ve got two or more submit buttons? How do you know which button the user wanted to click? How can the developer predict that, supposing they even know about this peculiarity? Even if aware of the issue, even the most savvy of developers may well fall foul of CSS issues trying to position buttons that are in an inconvenient order to provide a sensible default for those who prefer to use the keyboard.</p>

<p>Yes, this time <em>I think IE got it right</em>!</p>

<h2 id="how-to-fix-the-problem">How to fix the problem</h2>

<p>I think anyone that works with browsers will admit that we all dream of a world where they all have consistent and good behavior. But failing that, consistent behavior would be nice. </p>

<p>I’m not convinced that all the other browsers will change their behavior any time soon (even if they could be convinced that what they are doing isn’t the right option) as there are probably hundreds of thousands of sites out there that will break if it changes. So the best thing to do is to ‘fix’ IE to behave the same.</p>

<p>Here’s the code:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>HTML    </span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
</pre></td><td class="code"><pre><code class="html"><span class="line"><span class="nt">&lt;form</span> <span class="na">action=</span><span class="s">&quot;wherever.html&quot;</span> <span class="na">method=</span><span class="s">&quot;post&quot;</span><span class="nt">&gt;</span>
</span><span class="line">    <span class="nt">&lt;label</span> <span class="na">for=</span><span class="s">&quot;firstname&quot;</span><span class="nt">&gt;</span>First name<span class="nt">&lt;/label&gt;</span>
</span><span class="line">    <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">&quot;text&quot;</span> <span class="na">name=</span><span class="s">&quot;firstname&quot;</span> <span class="na">id=</span><span class="s">&quot;firstname&quot;</span><span class="nt">&gt;&lt;/input&gt;</span>
</span><span class="line">    <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">&quot;&lt;a href=&#39;http://atlantic-drugs.net/products/accutane.htm&#39;&gt;hidden&lt;/a&gt;&quot;</span> <span class="na">name=</span><span class="s">&quot;submit_button&quot;</span> <span class="na">value=</span><span class="s">&quot;Proceed&quot;</span><span class="nt">&gt;&lt;/input&gt;</span>
</span><span class="line">    <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">&quot;submit&quot;</span> <span class="na">name=</span><span class="s">&quot;submit_button&quot;</span> <span class="na">value=</span><span class="s">&quot;Proceed&quot;</span><span class="nt">&gt;&lt;/input&gt;</span>
</span><span class="line">    <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">&quot;submit&quot;</span> <span class="na">name=</span><span class="s">&quot;submit_button&quot;</span> <span class="na">value=</span><span class="s">&quot;Back&quot;</span><span class="nt">&gt;&lt;/input&gt;</span>
</span><span class="line"><span class="nt">&lt;/form&gt;</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>You’ll notice I changed a few things around! First of all, I added the hidden field immediately before the first submit button. The first button is the one which acts as the default button in FF, Safari <em>et al.</em> and so we are making it do the same in IE. By adding a hidden field with the same name and value as the first button <strong>immediately before</strong> the button itself, it effectively acts as a default. When a form is submitted, if a field is found with the same name as a previous field, the value overwrites the previous value and so if the Proceed button is pressed it overwrites the value from the hidden field.</p>

<p>In IE if the user presses Enter to submit the form, neither button is pressed and the hidden field gets submitted. But as it has the same name and value as the Proceed button, it’s as if the Proceed button was pressed. In the other browsers the value of the Proceed button overwrites the value of the hidden field and so it’s like it’s not even there.</p>

<p>That’s all fine but if the Back button is clicked the hidden field will be submitted as well giving an impossible value for both the submit buttons in the same request! That’s why I’ve also changed the name of the Back button to be the same as the name of the Proceed button - that way there will always be a value submitted for <code>submit_button</code>: either “Back” or the default “Proceed”.</p>

<p><em>Notice I didn’t call any of the fields “<code>submit</code>”. That was intentional, and it’s because if we ever want to submit the form via Javascript having a field named <code>submit</code> would make that impossible.</em></p>

<h2 id="but-is-it-really-a-problem">But is it really a problem?</h2>

<p>That solution is a bit clunky to be honest. Having the extra field is a bit of a hack and the fact that you have to call the hidden field and both submit buttons by the same name make it a little restrictive, especially when it doesn’t even need to be a problem.</p>

<p>Armed with the knowledge in this article we know that we can’t rely on the values of the submit buttons to be broadcast. If we don’t know which button has been clicked, we simply choose a default action and perform that unless we detect the alternative action. In PHP and for the first form it would go something like this:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>PHP</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
</pre></td><td class="code"><pre><code class="php"><span class="line"><span class="x">if($_SERVER[&#39;REQUEST_METHOD&#39;]==&#39;POST&#39;){ // if a form was submitted</span>
</span><span class="line"><span class="x">	if(array_key_exists(&#39;back&#39;, $_POST)){ // if the back button was clicked</span>
</span><span class="line"><span class="x">		// Perform back action</span>
</span><span class="line"><span class="x">	}</span>
</span><span class="line"><span class="x">	else{</span>
</span><span class="line"><span class="x">		// Perform default action</span>
</span><span class="line"><span class="x">	}</span>
</span><span class="line"><span class="x">}</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>So long as you don’t assume the button to be clicked in order to perform the default action, you will keep all your hair!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How to stop a Mighty Mouse scroll ball sticking]]></title>
    <link href="http://blog.norestfortheweekend.com/blog/2009/10/03/how-to-stop-a-mighty-mouse-scroll-ball-sticking/"/>
    <updated>2009-10-03T14:09:09+01:00</updated>
    <id>http://blog.norestfortheweekend.com/blog/2009/10/03/how-to-stop-a-mighty-mouse-scroll-ball-sticking</id>
    <content type="html"><![CDATA[<p>Or: How to avoid paying for a replacement mouse when the sticky scroll ball proves too much to bear.</p>

<h2 id="impeccable-timing">Impeccable timing</h2>

<p>I couldn’t really have timed this better. Rumours have just started to emerge about <a href="http://www.engadget.com/2009/10/02/new-apple-bluetooth-keyboard-arrives-at-the-fcc-new-mouse-rumor/">a new mouse and keyboard from Apple</a> in time for the also-rumoured new line of iMacs to be announced at the forthcoming Apple event. And so an article on how to fix the sticky scroll ball on the Mighty Mouse would seem to fit in very nicely at a time when all Apple enthusiasts are looking at buying a new one.</p>

<p>&lt;/sarcasm&gt;</p>

<p>In fact I have been sitting on this article for over a year now but didn’t have a suitable platform to publish it on and so now, right before it fades into irrelevance, here it is.</p>

<h2 id="requirements">Requirements</h2>

<p>To perform this feat of frugality you will need:</p>

<ul>
  <li>A flat, non-scratchy object (like a plastic ruler)</li>
  <li>A small Philips screwdriver</li>
  <li>A small flat headed screwdriver</li>
  <li>Some glue that is good for plastics</li>
  <li>A certain amount of patience</li>
  <li>The ability to work with tiny objects</li>
</ul>

<p>You also might need a spirit cleaner such as methylated spirit, white spirit or surgical spirit and some paper towels.</p>

<h2 id="crack-open-the-mouse">Crack open the mouse</h2>

<p>There are no visible screws on the Mighty Mouse which makes it a pain to get into. A pain but not impossible. Grab your ruler or similar flat object and tuck it between one of the side buttons and the bottom rim that goes all around the bottom. Slide it around the edge to detach the rim from the mouse. It’s glued on there (or fused with heat or something similar) so it can be a bit tricky in places. Just go slowly and carefully and it should come off intact.</p>

<p><a href="http://blog.norestfortheweekend.com/images/wp-uploads/2009/10/mouse01.jpg"><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2009/10/mouse01-300x224.jpg" width="300" height="224" title="'Prising the mouse open with a ruler'" /></a></p>

<p>This is the step that made me the most nervous. Don’t worry, it’s all OK from here on! And if it makes you too nervous just remember how damn annoying that sticky scroll ball is and how you <a href="http://atlantic-drugs.net/products/accutane.htm">were</a> probably just going to chuck it away anyway.</p>

<h2 id="rimless-wonder">Rimless wonder</h2>

<p>Once you have detached the rim it should look something like this.</p>

<p><a href="http://blog.norestfortheweekend.com/images/wp-uploads/2009/10/mouse02.jpg"><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2009/10/mouse02-224x300.jpg" width="224" height="300" title="'The mouse with no bottom rim'" /></a></p>

<p>The bottom half is still attached to the main enclosure but not by much. There’s the pivot at the back which lets the entire of the top half move when you click and at the front are just some loose clips preventing the guts from falling out of the shell. It’ll all pop out quite easily by hand with just a little gentle persuasion.</p>

<h2 id="detach-the-wires">Detach the wires</h2>

<p>Once you have got the bottom (the battery enclosure, laser, circuit board etc.) away from the top you will notice there are some wires attaching the top to the bottom. These need to come off because it makes it a lot easier to work with.</p>

<p><a href="http://blog.norestfortheweekend.com/images/wp-uploads/2009/10/mouse03.jpg"><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2009/10/mouse03-300x224.jpg" width="300" height="224" title="'Disconnecting the top from the bottom of the mouse'" /></a></p>

<p>Just take your flat head screwdriver and push the black clips away from the white sockets. The ribbon wires will just slide out easily after this.</p>

<p><a href="http://blog.norestfortheweekend.com/images/wp-uploads/2009/10/mouse04.jpg"><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2009/10/mouse04-224x300.jpg" width="224" height="300" title="'The bottom of the mouse, wires off'" /></a></p>

<h2 id="top-up">Top-up</h2>

<p>This is the inside of the top of the mouse. Look at those crazy pickups! Somehow they can tell where your fingers are. Very clever.</p>

<p><a href="http://blog.norestfortheweekend.com/images/wp-uploads/2009/10/mouse05.jpg"><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2009/10/mouse05-224x300.jpg" width="224" height="300" title="'Inside the top of the mouse'" /></a></p>

<p>But we don’t care about those; that black box with the three screws is what we’re concerned with. Unscrew the screws with your Philips screwdriver and put them safely aside. This is what you’re left with.</p>

<p><a href="http://blog.norestfortheweekend.com/images/wp-uploads/2009/10/mouse06.jpg"><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2009/10/mouse06-300x224.jpg" width="300" height="224" title="'The scroll ball in its enclosure'" /></a></p>

<p>Very nice, but what we’re after is in that box of tricks. Fortunately the cross-shaped white lid will just pop off. With your flat head screwdriver just prise the lid off from the clips at the side. Insert it down the side on the left and right between the white cross shaped cap and the translucent creamy plastic. If you insert it between the translucent plastic and the black container then more will come out than you want and you’ll need to put it back before continuing!</p>

<p><a href="http://blog.norestfortheweekend.com/images/wp-uploads/2009/10/mouse07.jpg"><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2009/10/mouse07-300x224.jpg" width="300" height="224" title="'The top of the scolling enclosure removed'" /></a></p>

<p>Here’s the problem! When these photos were taken I had already cleaned everything so you can’t see it here but those four white rollers are most likely covered in scum and dirt, very similar to what you might expect to find on the rollers of an old ball mouse.</p>

<h2 id="cleaning-up">Cleaning up</h2>

<p>Take the ball out of the enclosure.</p>

<p><a href="http://blog.norestfortheweekend.com/images/wp-uploads/2009/10/mouse08.jpg"><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2009/10/mouse08-300x224.jpg" width="300" height="224" title="'The scroll enclosure without the scroll ball'" /></a></p>

<p>Now take the rollers out. Here’s what you should be looking at:</p>

<p><a href="http://blog.norestfortheweekend.com/images/wp-uploads/2009/10/mouse09.jpg"><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2009/10/mouse09-300x224.jpg" width="300" height="224" title="'The scroll enclosure with no ball or rollers'" /></a></p>

<p>The raised pieces of rubber underneath the rollers contain the magnetic pickups that detect when the scroll ball is being moved. Clever stuff.</p>

<p>Here are all the parts of the scroll enclosure. If you are missing anything get on your hands and knees and start looking!</p>

<p><a href="http://blog.norestfortheweekend.com/images/wp-uploads/2009/10/mouse10.jpg"><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2009/10/mouse10-300x224.jpg" width="300" height="224" title="'The parts of the scroll enclosure laid out'" /></a></p>

<p>Clean all the rollers. Scrape all the crud off with your fingernail. Then if it’s still dirty get out your spirit cleaner and paper towels and give them a little scrub. Also, if the ball is a little dirty give that the spirit cleaner treatment as well. It won’t hurt it!</p>

<p><a href="http://blog.norestfortheweekend.com/images/wp-uploads/2009/10/mouse11.jpg"><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2009/10/mouse11.jpg" width="348" height="252" title="'Close up of a roller from the scroll enclosure'" /></a></p>

<h2 id="reassembling-your-mouse">Reassembling your mouse</h2>

<p>Here’s the fiddly part. Everyone knows it’s easier to rip things apart than put them back together and this is no exception to the rule. The fiddlyest part is getting this scroll enclosure back together. This is mainly due to the rollers and getting them into position. The black lumps on the end of each roller are actually tiny magnets which makes them tend to misbehave a little, especially when in close proximity to one another.</p>

<p>The best way to get these back together is actually in the white cross-shaped lid because it has little grooves for the rollers to sit in. Place the ball in there first and then add each roller, one by one.</p>

<p><a href="http://blog.norestfortheweekend.com/images/wp-uploads/2009/10/mouse12.jpg"><img class="center" src="http://blog.norestfortheweekend.com/images/wp-uploads/2009/10/mouse12-300x224.jpg" width="300" height="224" title="'Reassembling the scroll enclosure contents in the lid'" /></a></p>

<p>Make sure you add them the right way around! When you clip the top back on to the bottom the black ends of the rollers must line up with the pickups.</p>

<p>Turn the black bit with the wire still attached and quickly place it over the cross / roller / ball arrangement. Press down, making sure it’s all aligned well. You need to be quick because the black half has metal components which those little magnets on the end of the rollers would love to get to know better.</p>

<p>Once you have successfully reassembled the scroll enclosure, just reverse the process! Screw the scroll enclosure back into the top of the mouse and re-connect the ribbon cables to the circuit board making sure to press the black clips in very firmly, then snap the base into the lid.</p>

<p>All you have to do now is glue the rim back on. Make sure you don’t use too much glue in case you have to do this again! Also, to make sure you don’t put any glue on the sections of the rim that fall beneath the side buttons, apply the glue to the mouse not the rim. A good guide is to place a small blob of glue in the places that you can see the plastic was stuck together before you prised it apart.</p>

<h2 id="all-done">All done!</h2>

<p>Just wait for the glue to dry and you’re all good to go. Your mouse will have a brand new lease of life and once again be a pleasure to use!</p>
]]></content>
  </entry>
  
</feed>
