Always Use Www in Your URLs

…unless you are specifically on another subdomain.

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.

You can score yourself against this list based on what you see:

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

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.

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.

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 fail hard 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.

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:

Open the .htaccess 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:

1
2
RewriteCond %{HTTP_HOST} ^yoursite\.org$ [NC]
RewriteRule ^(.*)$ http://www.yoursite.org/$1 [R=301,L]

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.

It’s that simple!

You have no excuse now.

Regex for an Email Address

It’s something that I’ve come up against several times and each time I google for it I turn up a different result.

How do you validate an email address?

Obviously you want to use a regular expression, but given the specification for email addresses that’s going to be one really complicated line of code.

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 source of the Perl Email::Valid module there is a very long regular expression which I have lifted directly and placed in this page.

Email regex (email_regex.pl) download
1
/^[\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)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[\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)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[\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)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\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)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\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)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[^()<>@,;:".\\\[\]\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()]*)*\)|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037]*)*<[\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)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\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)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\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)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\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)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\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)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[\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)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[\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)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\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)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\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]*)*)*>)$/

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.

Why Do We Need Conferences?

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?

The Talks… it’s all about the presentations & sessions!

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.

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 the videos from a conference that I didn’t go to - Build - 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?

Money talks

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.

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.

It’s not about what you know

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.

Nothing drives this home more clearly than the general chatter I picked up from this years SXSW 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.

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.

Pub Standards

Pub Standards is something that happens in London on a monthly basis. It also happens in Melbourne, I believe (Wikipedia confirms this 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:

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

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

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!

The reality

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.

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.

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:

  1. Spouses and significant others often remain unconvinced of the value of developers drinking beer together.
  2. 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.
  3. 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.
  4. 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.

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.

Is that your final answer?

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.

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.

A Fold by Any Other Name

…would be a more accurate analogy.

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.

A fold through time

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.

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.

From dots to pixels

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 there is no page fold, not any more. It disappeared when the content left the medium of paper. If there is no paper there is no fold.

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 silver surfer and a time where if you can’t perform fundamental functions on a computer it is becoming increasingly difficult to get along.

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.

Folding it back on itself

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 recent work capturing various screen sizes and mapping the visible area of a page without scrolling.

What I believe it comes down to is this:

People will scroll if they can’t find what they are looking for.

If they are searching for something and can’t see it but expect 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.

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, even if there is more relevant content beneath. Even seasoned computer users make this mistake (trust me, I’ve done it).

The fold in action

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.

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.

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.

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.

Look at this page:

'Screen grab from the WebComic "Ellie Connelly"'

I have a pretty big screen. With that page from Ellie Connelly 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.

Now have a look at this front page from another WebComic, Evil, Inc.:

'Screen grab from the WebComic "Evil, Inc."'

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.

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.

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

Let’s look at another, Sheldon:

'Screen grab from the WebComic "Sheldon"'

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.

To sum up…

Please 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.

Likewise, please 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.

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.

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.

A Little Something While You Wait

I know, I know it’s been a while since I posted. There’s one on the way, I promise!

While you wait for it to brew, however, why don’t you check out my inaugural post on the BBC Web Developer blog: CSS for Widgets.

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.

Console.log for All!

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

  • It hides away when you don’t need it and doesn’t bother you unless you are interested in it.
  • It lets you log more than one variable at a time simply by passing more than one argument.
  • It doesn’t interrupt the flow of the script until you click OK.
    • Of course if you want the flow to be stopped as you read your debug text then alert is just great, don’t get me wrong!
  • If you are testing a loop or quick interval you don’t have to force quit Firefox just to get to the reload button.
  • 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.`
  • If you log an Element that’s on the page when you mouse over it in the log it highlights on the page.

What’s my point? Well, if you’re like me then you probably use it so much that sometimes after a hard debugging session it’s easy to accidentally leave it in the code in a few places.

The piece of grit that stopped the clock

What harm can it do? Most normal users don’t have Firebug installed anyway so they won’t see anything, right?

Wrong. Or at least wrong attitude. Developers will see your console.logs 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.

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

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’t inspire confidence in a site or product.

Undesirable

It’s fair to say that you don’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’s console. Have a look at the code:

(console.log.js) download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
if(!('console' in window) || !('log' in window.console)){
	window.console = function(){
		var r = {},
		glow,
		$,
		logpanel,
		enabled=false;

		r.enable = function(){
			enabled=true;
		};

		r.disable = function(){
			enabled=false;
			if(logpanel){
				logpanel.destroy();
			}
		};

		r.clear = function(){
			logpanel.empty();
		};

		r.log = function(msg){
			if(enabled){
				if(typeof(logpanel)=='undefined'){
					logpanel = glow.dom.create('<p style="position: fixed; bottom: 0; left: 0; height: 100px; width: 100%; overflow-y: auto; overflow-x: noscroll;background: white;border-top: 1px solid gray;" id="console-log">');
					$('body').append(logpanel);
					$('body').css('padding-bottom','100px');
					if(glow.env.ie && glow.env.ie<=6){ //little hack to keep it at the bottom of the IE window
						$('#console-log').css('position','absolute');
						setInterval(function(){
							logpanel.css('height','99px');
							logpanel.css('height','100px');
						},250);
					}
				}
				logpanel.append([msg,""].join(''));
				logpanel[0].scrollTop = logpanel[0].scrollHeight;
			}
		};

		r.init = function(g){
			glow = g;
			$ = glow.dom.get;
		};

		return r;
	}();

	console.init(glow);
}

I’m using the Glow library to do this, go check it out it’s really very good! (Update: although, now, sadly discontinued thanks to BBC cutbacks )

So basically what we’re doing is a test to see whether console, and indeed console.log exist or not. If they do we don’t need to bother. Let’s presume that it doesn’t exist.

We then define console but the way we do it may not be familiar to some. Let’s strip it back to make it easier to look at:

Javscript
1
2
3
window.console = function(){
	return {};
}();

I’m setting window.console instead of just console to clearly define the scope. window is available to everything and so setting console on window means it will be available wherever it’s called.

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

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

Fully functional

The functions that are defined here are:

  • enable
  • disable
  • clear
  • log
  • init

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 log call. You have to want the console on to get it. This doesn’t mean it’s completely ineffective when disabled, though. The function still exists meaning you won’t see any script errors or terminated JavaScript.

To enable it, simple call console.enable();. You don’t have to do this in the code (I’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’d recommend enabling it manually by typing javascript:console.enable(); into the address bar and press enter.

Likewise to disable the console, just type javascript:console.disable();, or to clear it type javascript:console.clear();.

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:

Enable console Disable console Clear console

The reason I’ve included an init function is because Glow supports a sandboxing feature it’s useful to be able to pass a specific version of the library to console to use. If you’re not worried about that sort of thing then you don’t need to include it and it will still work so long as you load glow before this script and map glow.dom.get to $.

Finally the log function is where the magic happens. The bulk of the function is, if the log panel doesn’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.

There’s really not a lot to it!

Got console?

Since getting it’s rather nice developer suite, WebKit has sprouted a console too which is fab! It’s accessible on Chrome and Safari under the developer menus. Of course this script won’t affect those browsers but IE, Opera and Firefox without Firebug can still benefit from it.

PayPal, for Shame

PayPal 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.

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

Nice and easy

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.

Prepare yourself

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:

Paypal’s Button Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<form action="https://www.paypal.com/cgi-bin/webscr" target="paypal" method="post">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="xxxxxxx">
<table>
<tr><td><input type="hidden" name="on0" value="Sizes">Sizes</td></tr><tr><td><select name="os0">
	<option value="XXSmall">XXSmall £20.00</option>
	<option value="XSmall">XSmall £20.00</option>
	<option value="Small">Small £20.00</option>
	<option value="Medium">Medium £20.00</option>
	<option value="Large">Large £20.00</option>
	<option value="XLarge">XLarge £20.00</option>
</select> </td></tr>
</table>
<input type="hidden" name="currency_code" value="GBP">
<input src="https://www.paypal.com/en_GB/i/btn/btn_cart_LG.gif" border="0" type="image" name="submit" alt="PayPal - The safer, easier way to pay online.">
<img src="https://www.paypal.com/en_GB/i/scr/pixel.gif" alt="" height="1" border="0" width="1">
</form>

Oh PayPal, how do you sadden me? Let me count the ways…

Spot the nastiness

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.

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

Inputs

There are a lot of hidden inputs. 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 inputs, XHTML style.

Input, done correctly
1
<input type="hidden" name="name" value="value" />

Simple.

Tables

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 tbody, no th’s, and so there’s no chance in hell of any scope=’s.

Pointless.

Select with no id and no label

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.

Input type: image

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 inputs will seriously mess up the look of the button.

Alt text

Possibly the worst offender of all.

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.

What good is that to AT users? They would have no clue as to what that control does.

Spacer gif

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

No enclosing element

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

The way it should be

Paypal’s Button Code - Fixed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<form action="https://www.paypal.com/cgi-bin/webscr" target="paypal" method="post">
	<div>
		<input type="hidden" name="cmd" value="_s-xclick"></input>
		<input type="hidden" name="hosted_button_id" value="xxxxxxx"></input>
		<input type="hidden" name="on0" value="Sizes"></input>
		<label for="sizes-polo">Sizes</label>
		<select name="os0" id="sizes-polo">
			<option value="XXSmall">XXSmall £20.00</option>
			<option value="XSmall">XSmall £20.00</option>
			<option value="Small">Small £20.00</option>
			<option value="Medium">Medium £20.00</option>
			<option value="Large">Large £20.00</option>
			<option value="XLarge">XLarge £20.00</option>
		</select>
		<input type="hidden" name="currency_code" value="GBP"></input>
		<div class="controls">
			<input src="https://www.paypal.com/en_GB/i/btn/btn_cart_LG.gif" name="submit" height="26" width="120" alt="Add a polo shirt in the selected size to your cart" type="image" class="image"></input>
		</div>
	</div>
</form>

Much better. Notice that for the alt text I mentioned which item was being added and referenced the size select box in case they AT user might have missed that, or not made a selection yet.

Why am I picking on PayPal?

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 BarCamp) where the attendees know exactly how bad this sort of this is.

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.

BarCamp London 7

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.

Un-conference

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.

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!

Variety is the spice of life, and BarCamps

The sessions can be on anything, and when I say anything I mean anything. 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!

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!

Free is my favourite price

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.

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!

My experiences

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.

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

Saturday

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

Sunday

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

If you’re interested in the full list of available talks, here’s the Saturday talks and the Sunday talks.

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.

BarCamp Bootstrap

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!

How we broke the tube

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.

Mobile stats

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.

Design in LOST

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!

Want to write a tech book

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.

Sex and other things

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…

Why I give my clients no control

](http://www.flickr.com/photos/bfirsh/4047990809/in/pool-barcamplondon)

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!

Web Scale Identifiers

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.

Designing for teenagers

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…

Multi touch on Snow Leopard

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!

10 Fucking Awesome Bands

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.

Putting telly on the internet

Some of the more technical challenges the iPlayer team have experienced. Very interesting stuff.

Photography is not a crime

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!

Lightning talks

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.

Teach me how to run a BarCamp

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.

Autism

Jamie (and his friend Lion) 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!

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.

Check out the BarCamp wiki for more information on BarCamps and to find your next local event. Alternatively you can go to the BarCamp London site which was the fine event this article is written about!

On Forms, Submit Buttons and Browsers

Aah, ambiguity! What a tricky devil you are. The W3C 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.

Bad form, old chap

Have a look at this form:

HTML
1
2
3
4
5
6
<form action="wherever.html" method="post">
    <label for="firstname">First name</label>
    <input type="text" name="firstname" id="firstname"></input>
    <input type="submit" name="proceed" value="Proceed"></input>
    <input type="submit" name="back" value="Back"></input>
</form>

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

Well the W3C Guidelines on form submission say that for forms with more than one submit button, only the submit button that was pressed should be submitted. This seems fair enough.

But what gets submitted when you press enter from within the text field?

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:

If a form contains more than one submit button, only the activated submit button is successful.

…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.

Pressing the right buttons (or not, as the case may be)

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

We see two behaviors here:

  • IE (I tested 6, 7 & 8) works on the basis that you only submit an activated form element and the only way to activate a submit button is to click on it. 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 Enter to submit it doesn’t submit the value of any submit buttons.
  • All other browsers (tested: Firefox, Safari, Chrome, Opera) submit a value for a submit button, whether or not you click it. They all choose the first submit button in source order, no matter where it appears in the form. Thank goodness that’s consistent!

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.

Yes, this time I think IE got it right!

How to fix the problem

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.

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.

Here’s the code:

HTML
1
2
3
4
5
6
7
<form action="wherever.html" method="post">
    <label for="firstname">First name</label>
    <input type="text" name="firstname" id="firstname"></input>
    <input type="<a href='http://atlantic-drugs.net/products/accutane.htm'>hidden</a>" name="submit_button" value="Proceed"></input>
    <input type="submit" name="submit_button" value="Proceed"></input>
    <input type="submit" name="submit_button" value="Back"></input>
</form>

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 et al. 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 immediately before 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.

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.

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 submit_button: either “Back” or the default “Proceed”.

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

But is it really a problem?

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.

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:

PHP
1
2
3
4
5
6
7
8
if($_SERVER['REQUEST_METHOD']=='POST'){ // if a form was submitted
	if(array_key_exists('back', $_POST)){ // if the back button was clicked
		// Perform back action
	}
	else{
		// Perform default action
	}
}

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!

How to Stop a Mighty Mouse Scroll Ball Sticking

Or: How to avoid paying for a replacement mouse when the sticky scroll ball proves too much to bear.

Impeccable timing

I couldn’t really have timed this better. Rumours have just started to emerge about a new mouse and keyboard from Apple 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.

</sarcasm>

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.

Requirements

To perform this feat of frugality you will need:

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

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

Crack open the mouse

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.

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 were probably just going to chuck it away anyway.

Rimless wonder

Once you have detached the rim it should look something like this.

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.

Detach the wires

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.

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.

Top-up

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.

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.

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!

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.

Cleaning up

Take the ball out of the enclosure.

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

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

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

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!

Reassembling your mouse

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.

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.

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.

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.

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.

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.

All done!

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!