Tim Bray on Software in 2014

In his article “Software in 2014” Tim Bray says about the present state of front-end development:

Thus, for ac­tu­ally build­ing ap­pli­ca­tions, you’re going to have to pick a higher-level frame­work. There are lots of them and they com­pete vig­or­ously, it’s easy to poke around the Web and find knock­outs and cage matches; one good high-level com­paro is Rich JavaScript Ap­pli­ca­tions – the Seven Frame­works (Throne of JS, 2012) but wait it’s eigh­teen months old thus prob­a­bly now wrong, which is a symp­tom of the prob­lem. “What prob­lem,” you ask, “choice is good, right?” It is, but this isn’t an or­derly choice, it’s a Cam­brian Ex­plo­sion. I’m sure the soft­ware arche­ol­o­gists of 2113 will enjoy study­ing it, but it’s a prob­lem.

ongoing by Tim Bray · Software in 2014.

I completely agree, right down to the term “Cambrian Explosion”, and I ranted a bit about it in one of the few posts I wrote last year. Client-side development is a scary mess right now, where almost every choice you make stands a chance of blowing up in your face a year down the line.

Marching ants in CSS

A couple of days ago I noticed that Goooogle uses a marching ants effect on their new mini-calendar event view. It highlights the target time frame for the event you’re editing, and it indicates a draggable and expandable area. (It’s probably been there for ages, but I’m slow like that.)

Marching ants effect in Google Calendar.

Being a colossal geek, the first thing I did was run up Firebug to see how they’re doing it, because there is no “border-style: marchingants” in CSS. It looks like Google is doing it with JavaScript. The area in question is bounded by four long but thin div elements (tall and narrow for the vertical borders, short and wide for the horizontal borders).

<div class="sc-ants sc-ants-top"></div>
<div class="sc-ants sc-ants-left"></div>
<div class="sc-ants sc-ants-right"></div>
<div class="sc-ants sc-ants-bottom"></div>

These divs sit inside a parent container with overflow:hidden, so you only see a small slice of their full extent. The border divs themselves have size, but no content. Their entire area is taken up by a 2px-wide dashed border:

.sc-ants-top  {
    border-top:2px dashed #6688EE;

Finally, there is a JavaScript timer that changes the position of these divs, moving them a pixel at a time to achieve the marching ants effect.

Even in native applications, marching ants are not all that common, and I think this is the first time I've seen them in a web application. Given that draggable/resizeable areas are also not all that common in web apps, I think it's a clever and elegant way of highlighting that there is something different an unusual about that area.

On the other hand, I'm not mad keen on keeping JavaScript timers running just to keep screen elements in their appropriate position, so I wondered if there was a way of doing this with just CSS instead. And of course there is: have a look at the demo page.

I started with a block of HTML in the standard module format, because it's a good basis for isolating areas of content. The div.bd holds the actual content to be highlighted, and the other parts of the module are used for creating the borders, as follows:

  • The outermost div is given a left-hand pseudo-border by using a background image with repeat-y only, positioned slightly to the left of the left edge, so that only the rightmost two pixels of the image are visible.
  • Likewise, the .inner container is given a top pseudo-border.
  • The .hd block makes the right-hand border. It is positioned absolutely on the right edge of the module, 2px wide and 100% tall, and has a background image with repeat-y.
  • The .ft block makes the bottom border. It is 2px tall and 100% wide, and also has a background image.

Here's how it looks inline:

Marching ants!

The actual animation is achieved with a couple of old-skool animated GIFs, ants-horizontal.gif and ants-vertical.gif. The horizontal GIF contains two checkerboard patterns, one moving to the left, and one moving to the right; the vertical GIF has the checkerboard patterns moving up and down. Each border only uses half of one of the GIFs, which is you only need two images rather than four.

If you are content with the border being a single pixel thick, and the ants flowing from one corner to the opposite, then you could get away with just one animated GIF — see the wikipedia article on marching ants for an illustration. Personally, I prefer the animation to flow round the border in a continuous pattern.

Of course, this is far from the only way you could implement the marching ants effect. You could use webkit's CSS animations instead. The demo page includes an example of how to do this as well. The basic principles are exactly the same: set up a standard module, and use GIF images to form the necessary borders. But instead of using animated GIFs, you can use just a single static checkerboard image, and use up/down/left/right animations to move around the background instead:

.marchingants {
	-webkit-animation-name: march-up;
	-webkit-animation-duration: 0.3s;
	-webkit-animation-iteration-count: infinite;
	-webkit-animation-timing-function: linear;
@-webkit-keyframes march-up {
	from {
		background-position-y: 8px;
	to {
		background-position-y: 0;

One neat thing about the CSS animation version is that you can vary the speed of the animation without having to edit the GIF file. The obvious drawback is that it (for now) only webkit browsers support CSS animations. But given how easy it is to implement this in a cross-browser compatible manner, right now I'd suggest sticking to the animated GIF version.

How to detect a page request from Safari 4’s Top Sites feature

While reading Jeremy Keith’s blog entry “Safari Askew” I remembered that I had looked at this just before Christmas, and found an answer.

The problem is to do with Safari 4’s “Top Sites” feature, which shows you a pretty grid of thumbnails for the sites you visit most regularly (or that you have pinned in place). The interesting thing is that these thumbnails are live (ish) previews of what those pages currently look like. If you don’t happen to have a Top Sites page open in a tab, and if Safari considers that the current thumbnail is sufficiently out of date, it will automatically go and retrieve the latest version.

Safari 4's Top Sites feature

This can cause headaches for site owners, because in order to show the actual state of the page, Safari relies on full page requests: it downloads all the HTML, CSS, images, and JavaScript for the page, and then displays everything exactly as if the user were viewing the page in a standard tab. Adverts are rendered, page tracking scripts are executed, and to the server it looks just like a regular page hit. This can lead to the site recording unnecessary actions, and your site analytics being all messed up.

At Skyscanner, for example, we noticed this because Google Analytics was showing an unusually high number of Safari users (8.5%) with an abnormally high bounce rate (the proportion of sessions where users view a single page, then walk away with no further interaction): Safari 4 users were twice as likely to bounce as other browsers. Useless sessions generated by Top Sites were the problem.

As Jeremy noted, the user agent that Safari 4 reports for a Top Sites request is exactly the same as for a normal page request. Fortunately, there is a way to distinguish the two types of request: in the current version of Safari 4 (4.0.4) the Top Sites request for the base page (but not its JS/CSS/image resources) carries an additional HTTP header, namely “X-Purpose: preview“.

An easy way to verify this is to use an HTTP debugging proxy like Fiddler or Charles to watch what happens when Top Sites makes a request — see the screen grabs below:

Normal and Top Sites HTTP requests from Safari 4

If your pages are dynamically generated, you can adjust your server-side code to examine the HTTP headers of the incoming request, and take appropriate action if this is a “preview” request. Here’s some sample PHP code:

if ($_SERVER["HTTP_X_PURPOSE"] == "preview") {
	echo "preview";
} else {
	echo "normal";

("X-Purpose" is not a standard HTTP header, and you won’t find “HTTP_X_PURPOSE” in the PHP documentation. It’s the CGI specification that specifies how HTTP headers should be handled: they should be made into an environment variable with an “HTTP_” prefix followed by the header name, with dashes replaced by underscores. Hence, the value of the "X-Purpose" header is placed in the "HTTP_X_PURPOSE" environment variable, and retrieved as $_SERVER["HTTP_X_PURPOSE"].)

If all you’re looking to do it fix your site stats in Google Analytics, then you should just make sure that you don’t write out the GA tracking code for preview requests. If you are concerned about excessive load on your servers, unwanted user actions, or spurious advert impressions, you can take more aggressive action, perhaps by rendering a lightweight version of the page. An extreme possibility I considered was generating a completely different version of the page, specifically designed to look good in the thumbnail format of the Top Sites preview page:

Safari 4 Top Sites with custom preview thumbnail: PROBABLY A BAD IDEA

However, doing this runs counter to the notion that these thumbnails represent previews, and I don’t know how your users would react. More importantly, Google might consider this cloaking, and come round your house in the middle of the night with a baseball bat. Just because it’s possible, doesn’t mean it’s a good idea…

The developer’s mantra

I’d like you to take the time to learn the developer’s mantra:

The Tester is always right. I will listen to the Tester. I will not ignore the Tester’s bug reports. The Tester is god. And, if this ever happens again, the Tester will personally rip your lungs out.

This comes courtesy of Abi, who subverted the Babylon 5 mantra for the purposes of educating inexperienced developers.

Ivanova and Sutherland

“Connect to a server” option in IIS Manager is not available

If you are running Vista, and are wondering why you can’t use IIS Manager to connect to any remote servers, sites, or applications…you’re running the wrong version.

Here’s what the wrong version looks like:

The wrong version of IIS Manager in Windows Vista

You need to grab the “IIS Manager for Remote Administration” instead, as shown in the picture below. It has an active toolbar in the connections panel, and extra menu options. It allows you to administer IIS sites and applications on remote machines.

The right version of IIS Manager in Windows Vista: IIS Manager for remote administration

Download links:

It took me ages to figure this out — I thought there must be some option, service, or permission I was missing that would allow me to connect to remote sites. But no, you need a completely different version of the damn tool. Vista Ultimate, my ass. I hope this makes the answer a bit easier to find for the next person who is stumped by the same issue.

@Media Ajax

@Media Ajax logoI was at the conference @Media Ajax conference last week. In hindsight, “@Media JavaScript” would have been a better title, though. It is less than two years since Jesse James Garrett coined the term “Ajax”, but we are already at the point where Ajax development is just the way we do things now, rather than something that needs to be explained, discussed, and evangelized.

During the wrap-up panel at the end of the second day, one of the questions was directed to the audience: who would have attended the conference if it had in fact been called “@Media JavaScript”? Most people put up their hand. I would not be surprised if Vivabit run a sequel to this conference next year; but the main reason for them to keep the term “Ajax” in the title would surely be to make it easier for developers to convince buzzword-hungry managers to let them attend.

Monday 19 November

Keynote presentation: “The State Of Ajax” by Dion Almaer and Ben Galbraith

Dion AlmaerBen GalbraithThis presentation set the scene for the rest of the conference, briefly covering subjects like JavaScript 2 and the heated politics surrounding it, the emergence of offline support for web apps (Google Gears) and runtimes with desktop integration for web apps (AIR, Silverlight), and the evolution and convergence of JavaScript frameworks. Their demonstration of Google Gears’ WorkerPools was an eye-opener for me; I hadn’t realized that Gears was about so much more than offline storage. They closed with a reflection on how Ajax has transformed our expectations of web applications, and how it is enabling a more attractive web.

(Note to self: get more familiar with Tamarin, ScreamingMonkey, Google Gears, AIR, HTML5, Dojo, Caja.)

“But I’m A Bloody Designer!” by Mike Stenhouse

Mike StenhouseMike talked about how in modern web development, the traditional barriers between designers and developers are breaking down. Designers need to be aware of the consequences of their choices, and how things like latency and concurrency will influence a feature. Developers need to increase their awareness of interaction design. This led to a discussion of how he feels thatBehavior-driven development has made him a better designer (and developer). He mentioned WebDriver for writing and executing BDD test cases, but the demo code he showed looked more like Ruby… I think I missed something there. Good tools and techniques to explore, though.

Update:: RSpec?

“Real World Accessibility for Ajax-enhanced Web Apps” by Derek Featherstone

Derek FeatherstoneProviding good accessibility for web content is hard enough; once you start building dynamic web apps, you’re practically off the map. Derek took the zoom/move control in Google Maps as an example of bad practice, showing how difficult it is for someone with only a voice interface to use. He walked through some more examples, with useful advice on how to make improvements in each case.

One of the toughest problems for Ajax applications is how to inform screen readers that a part of the screen has been updated. Derek noted Gez Lemon and Steve Faulkner’s technique for using the Virtual Buffer as being one of the best options for tackling this right now. Another cool technique that I hadn’t seen before was updating an input field’s <label> element with error information when the form is validated (so that a screen reader is made aware of the change), but then using CSS positioning to display the error information where a sighted user would expect to see it–possibly on the other side of the field than the label itself. Very clever.

I’m also going to have to familiarise myself with the ARIA (Accessible Rich Internet Applications) work coming out of the WAI: ARIA proposes to extend (X)HTML with additional semantics that would allow web applications to tap into the accessibility APIs of the underlying Operating System.

“How To Destroy The Web” by Stuart Langridge

Stuart LangridgeAfter lunch, Stuart Langridge put on his Master of EVIL hat, and tried to coax us to join him on the Dark Side by teaching us about all the things we can do to make a user’s experience on this hyperweb thingy as shitty and 1998-like as possible. Remember: if your app doesn’t use up all of a user’s bandwidth, they’ll only use it for downloading…well, something else. (“Horse porn” sounds so prejudicial.)

(Stuart’s slides lose a certain something when taken out of context.)

“Planning JavaScript And Ajax For Larger Teams” by Christian Heilmann

Christian HeilmannChristian works for Yahoo!, and has for a long time been a great evangelist of unobtrusive javascript and other modern JS techniques like the module pattern. In this presentation, he talked about working with JavaScript in larger teams. This is interesting, because until recently, there were no such things as “large JavaScript teams”. JS was something you copy-and-pasted into your web site, or got your resident front-end geek to bolt on as an afterthought. JavaScript has matured enormously over the last few years.

Many of Christian’s points are good software development practices in general: comment your code, follow a code standard, work as if you will never see your code again, perform code reviews, use good names, etc. Take five minutes to read through Christian’s presentation slides (they’re very readable and comprehensible, even out of context), and then take another five minutes to think about them. JavaScript is a first-class citizen of web development now: let’s treat it as such.

(Note to self: make more use of the BUILD PROCESS.)

“Ajax A Work: A Case Study” by Peter-Paul Koch

Peter-Paul KochPPK wrapped up the day with a case study of a genealogy/family tree application he is building. He walked through the decision processes behind:

  • building the app as an Ajax app in the first place
  • choosing XML instead of JSON (or HTML or CSV) for its data format on the wire
  • deciding on an optimal loading strategy to ensure a highly responsive user experience

Interestingly, PPK was the only speaker who used the “strict” definition of Ajax (i.e. Asynchronous JavaScript and XML) as the basis for his presentation. I didn’t agree with all of the decisions he described, but it was an interesting view anyway. (And besides, it’s not my app 🙂 His write-up of the conference, as well as his slides, can be found on his Quirksmode blog.

Tuesday 20 November

“The State Of Ajax” by Brendan Eich

Brendan EichBrendan Eich is the man who invented JavaScript. There are few mainstream languages that have both been adopted so widely, and dismissed out of hand by so many. In the keynote presentation, Dion and Ben characterised Brendan Eich as wanting to use the JavaScript 2 (ECMAScript 4) spec to “just let him fix his baby”. That’s a pretty crude caricature of Brendan’s position, though. He is very keenly aware of all the problems in JavaScript as it stands right now. (And there are some really big problems.) With JS2 he is trying to take the best bits of JS1, and build a language for the next 5-10 years (or more) of the web.

However: JS2 really is a different language. It adds new syntax, and it will not be compatible with existing interpreters. The other side of the “future of JavaScript” debate wants to see incremental improvements to the current implementation(s), so as to maintain compatibility and not “break the web”–because we’re still going to be stuck with IE6 for a long time to come.

I’m not going to run through the technical guts of all the things going into the JS2 spec–there are just too many of them. Take a look at Brendan’s roadmap blog to get pointers to what’s going on.

“Building Interactive Prototypes with jQuery” by John Resig

John ResigThis presentation did exactly what it said on the tin: an introduction to coding with jQuery. It appears to be compact, simple, expressive, and ideal for a lot of everyday JavaScript work.

“Metaprogramming Javascript” by Dan Webb

Dan WebbDan showed how to use some of JavaScript’s best features (prototypal inheritance, expando properties, using Functions as Objects, etc.) to produce some surprising results. Because of these techniques, JavaScript really is a language that can bootstrap itself into a better language. Very slick.

(See the slides for the presentation on Dan’s site.)

“Dojo 1.0: Great Experiences for Everyone” by Alex Russell

It appears that no @media conference is complete without a doppelgänger. I hope I’m not the only one who sees the obvious resemblance between Alex Russell and Ryan Reynolds. (Photo of Ryan Reynolds shamelessly lifted from Tharpo on Flickr.)

Hollywood star and sex symbol Ryan Reynolds Dojo toolkit lead developer Alex Russell

Alex is the lead developer for the Dojo toolkit. He talks really fast on stage! He is full of energy and seemed eager to share his insights with the audience, even though some of those insights paint a rather depressing picture of the state of the web. Personally, I lapped it up. I think it was the best presentation of the conference. Rather than talking just about Dojo, he discussed among other things:

  • the complexity of web development, and why there is a need for JavaScript libraries/frameworks in the first place
  • the burden of bringing new semantics to the web
  • how the lack of progress and competition is putting the whole open web in jeopardy

You can get the slides for the presentation on Alex’s blog, but without his lively and passionate narrative, they lose a lot of their power. Although he also talked about the technical capabilities of Dojo itself (powerful internationalization features, accessibility already built in to all its widgets, all built on top of a tiny core), it’s the strategic positioning of the toolkit that is going to make me download it and try it out.

“JavaScript: The Good Parts” by Douglas Crockford

Douglas CrockfordDouglas Crockford is one of the people most responsible for bringing JavaScript to its current level of maturity. He invented JSON, and wrote the JSLint checker and JSMin minifier. He reckons that JavaScript is the world’s most misunderstood programming language. His presentation covered some of the best bits, which you probably would not discover on a first glance at the language, such as Lambda expressions, closures, and dynamic objects.

Douglas stands in the opposite camp to Brendan Eich when it comes to evolving JavaScript. He wants to see the language become more secure (very important, given how glaringly insecure it is right now), but he thinks that the radical changes proposed for JS2 are wrong. One of the best parts of JavaScript is its stability: there have been no new design errors in the language since 1999, because that’s how long JS1 has been frozen. (There have been minor iterations to it since then, but nothing on the scale of the fundamental architectural changes that JS2 will bring.) He is still keen on evolving the language, but in a much more gradual way.

One very interesting thing that Douglas briefly mentioned was ADSafe. This is a subset of Javascript, designed for safety: a script built with the ADSafe subset can still perform useful work (it still has access to the DOM, and can make network calls), but it is not allowed to use any of the features that make JavaScript inherently unsafe (e.g. access to global variables, use of eval, etc.). ADSafe is a static checker: you run it to verify the code before you allow the code to appear on a page. If it isn’t safe, you don’t let it run. Google’s Caja works in a different way: it takes untrusted code and transforms it into safe code. To understand the use of these tools, consider Google’s iGoogle home page, where you can have widgets from a variety of sources all running on the same page. Without some kind of safety container, these scripts would have access to each other’s code and capabilities — very dangerous.

(The slides Douglas has on his blog are not quite those he used for this presentation, but they’re close enough.)

Wrap-up panel discussion with Brendan Eich, Stuart Langridge, Alex Russell, Douglas Crockford, and moderated by Jeremy Keith

Brendan EichStuart LangridgeAlex RussellDouglas CrockfordJeremy Keith Jeremy tried to keep this light-hearted, but there was clearly some tension between the panellists. I was pretty tired by this point, though, and the thing I remember most is Alex berating Yahoo! (Douglas) for not open-sourcing the YUI framework and coming together with other toolkit developers to present a unified front to browser vendors. Other subjects that came up included Google Gears (again), how badly CSS sucks (I see their point, but I still like it anyway), and capability-based security (see also The Confused Deputy).

(Jeremy’s has write-ups day 1 and day 2 on the DOM Scripting blog.)


It was a very interesting conference. It didn’t feature as much technical content as I had expected: it was more strategic than tactical. I didn’t mind at all, though, that it wasn’t just about “Ajax”. I love JavaScript, and I came away feeling excited by the amount of activity in the field.

The most important things I took on board:

  • Make more use of the build process
  • Investigate Google Gears – there is a lot of interesting stuff going on there, and it will start making its way into browser implementations soon
  • If you’re doing any kind of JavaScript development beyond simple form validation, you really should be using a library…
  • …probably jQuery…
  • …but Dojo looks REALLY interesting