Why you should develop vanilla HTML first and CSS, JavaScript, Flash, et al last

Imagine you own an concert hall.  The year is 2005 and you’re finally getting into the online ticketing game.  You want to let users pick their seats off a map of the concert hall so you use Flash.  You create a slick seat picker that does asynchronous calls to get the available seats and prices, lets users pick their seats, and then populates the values to a hidden input field.  I’m sure you know by now that there are many problems with this approach, but let’s go over them.

The obvious one is that Flash is not a 100%-reliable technology.  Before the iPhone came out we considered it ubiquitous but it has had many historical issues.  It isn’t a default feature of the operating system, when people get a new browser it may not be installed, and there was a period where IE blocked plugins by default.  Your more cautious users may even block Flash to prevent security risks.  At the very least, imagining a world where everyone can have and wants to have Flash, you’re still dealing with the scenario where they don’t have it right now.  You’re going to have to put up a “Download Flash” link and have your users go through that process before they can access the site.  Your site’s main goal is to have users buy tickets and have a positive experience doing it.  Your goal is not to increase the number of Flash-enabled browsers.

There’s also a risk of vendor lock-in.  What happens when you open a second theatre or demolish a few seats to add wheelchair seating?  Did you design that ticketing UI in a way it is easily configured?  You may need a second engagement to get the interface to reflect your on-the-ground changes.  You could pay through the nose to keep your dates from slipping.

There’s the disruptive scenario we skipped over above, where users are on an iPhone and cannot use your site.  What do you do?  This is a big market.  You can’t retool your site easily.  Make an app!  Now you have two UI’s to maintain along with a handful of frontend services to recreate the ticket buying process.  Maybe instead you go with an HTML5 mobile UI.  Now you’re stuck supporting multiple mobile browsers.  You go ahead and do it anyway to provide quick support for Android, Blackberry, and Windows Phone 7.  Now you have three interfaces: Flash, iPhone, mobile web.  But you’re still not prepared for everything.

Another disruptive scenario where your theatre becomes popular with a audience.  They love your venue but hate your UIs.  Nothing is accessible so they have to call in their ticket orders.  To keep this customer base you must retrofit all your UIs at a high cost due to your multiple vendor partners.  You do it now but who knows what the future may hold.

How could this mess have been avoided?

I would argue that you need to go back to your roots.  While not sexy, an HTML3.2-compatible form coupled with basic PHP/JSP/ASP is the answer.  Get rid of all the frills and thrills and make a dumb-old web page.  While it may not impress anyone, it can accomplish your two goals getting people through the ordering process and keeping them happy.  While it is harder to use an <select multiple> than a flash seat picker, users will probably be impressed with the wicked speed of its one HTTP request.  Ordering happens in the blink of an eye, possibly faster than an XHR request.

It also meets all your past and possibly future use cases.  Smart phone users have no problem. Neither do blind users.  Given HTML’s track record, I would guess that your eyeball tattoo web browser will be able to use it 10 years from now.

No, no, no.  I’m not advocating ugly web pages.

Ugly webpages are your baseline.  Everything from here is to enhance the experience for users that can benefit from it and not hinder the experience for users that can’t.

The first thing you do is make your site beautiful.  You create CSS to style your page and possibly add a few <div> elements and class names to make it all work.  Of course, you do all this in an object-oriented, semantic manner.

The second thing you do is add JavaScript where it makes sense.  You’ll probably want to show the order total.  This will involve attaching dollar-values to the seat <option> elements.  Following rules you would end up with something like <option value=”A1″ data-price=”100.00″>A1 ($100.00)</option>.  You will also end up with more elements with ID’s.  Your first impulse may be to write:

    <th>Total Cost:</th>
    <td id="totalCost"></td>

This works, but gives the user a confusing experience if JavaScript is disabled.  You have three options for the page to make sense for that use case, hide the element with CSS by default and show it with JavaScript if enabled, inject it via JavaScript and DOM manipulation when the page loads, or put a meaningful default message that will be seen if JavaScript is disabled.

The first option is fine but you have to be careful.  You’ll want to have a script like Modernizr configure the page in the head so the user experience isn’t jarring with the element appearing later and moving content.  You also have to worry about the scenario where JavaScript is enabled but your particular script fails due to a defect.  The second solution all but guarantees you’ll make a user visible change to the page.  It does however eliminate the risk of showing the element if the script fails.  The third option is my favorite because it has low risk and introduces no extra integration points.  Think of the following:

    <th>Total Cost:</th>
    <td id="totalCost">Visible in cart.</td>

This gives JavaScript-less users useful information and requires zero extra work.  You don’t have to worry about CSS or user-visible painting or any of the other complexity that goes along with it.

The third thing you do is add the flash object.  Because you are now constrained by the <select> object you’re manipulating, you will need your Flash UI to pull from and write to that data source.   You will hopefully realize that you need a truly configurable interface that doesn’t just work for one theatre layout but it’s okay if you don’t.  You’re already saving money by avoiding that async interface for getting seat configurations.  To make it truly compatible with all use cases, use JavaScript to show the Flash and hide the <select> if Flash is supported.  If you’re truly invested in a resilient design, don’t even hide the <select>.  Place it to the side and let the user use either input.

Cool, I’m back where I started, how does this solve my problems?

Let’s step through the scenarios.

Flash doesn’t work?  No problem.  Users get a <select multiple>.  Same for JavaScript, CSS, et al.  The page is resistant to failures of all non-essential components.

New theatre or seating change you didn’t design for?  No problem.  You can disable Flash for those use cases until you get your new resources from the vendor.

iPhone comes out?  No sweat.  Your script detects that Flash isn’t supported and degrades to the drop-down giving you time to work on an iOS app or HTML5 canvas interface.  Your page isn’t mobile friendly but if you removed all the CSS and added a <meta name=”viewport”> it would be.  You create mobile-friendly CSS and use media queries and you’ve pretty much invented responsive web design.  Your site is so simple and fast that you may even bypass the app in general.

Windows Phone 7 becomes popular (with your demographic)?  If your CSS breaks on that device, no biggie.  A custom stylesheet gets you back on track.

Popularity among blind users?  Quick usability testing shows your semantic site is 90% there.  You do some tweaking to make the <select> always accessible even if not visible and make screen readers ignore the Flash UI.

The one scenario where it seems like it would be worse is if you go with a native smartphone app since you skipped the async seat loading in the Flash UI which could be an asset for the phone.  I would argue that it isn’t worth it since the increased complexity increases the workload for analyzing and reimplementing the total process.  Now because all the technical work is being done by a single web page, even if you have a terrible design with database calls and business logic in the frontend layer (e.g., PHP), you only have one frontend layer to deal with.  You could abstract that out into two files the logic and the form.  You then use the logic the web service.  You’re not hunting through multiple source codes in multiple languages to capture all use cases.

Wait, isn’t this just called progressive enhancement?

You caught me.  This is nothing new.  Progressive enhancement is often sold as a way of improving performance, reducing last-minute issues, et al.  I want to sell it as something more basic.  It is a way to cut through the complexity of your designs and future-proof your site.  When you start with nothing and build on top of that, you have to thing of things as logical layers.  When things aren’t working with an enhancement, you can always peel it back.  Your core message isn’t lost in a sea of “Please install flash” or “Please download our app”.


If you got to the end, I hope you enjoyed reading it as much as I did writing it and forgive my lack of editing.  I’ve been trying to get this blog restarted for a while but keep getting caught up on the little things.  Hopefully this marks the first of many more posts.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s