Responsive Web Design Revisited

1 Comment

If you are building a web application, don’t expect the RWD you read about to be the RWD you will use. RWD is going to be about abstraction, code management, and using the right methodologies

A while back, when I was a frustrated architect leading a talented team of web application developers on several initiatives with multi-screen targets, I claimed that Responsive Web Design (RWD) is not the Holy Grail of write once/deploy everywhere.

So, what has changed since then?

Still frustrated. Still working on mobile/tablet/desktop projects. Still think RWD is chasing a dream.

Since those early days of RWD (back in May), a lot of things have changed. More libraries. More JQuery plug-ins. More people claiming the virtues of RWD. More carousel plug-ins. My god, how many carousel plug-ins do we legitimately need as an enlightened society?

I tried, I really really tried, for a recent customer to get my team to build a relatively simple web application using RWD design principles — media queries, plug-ins that handle some of the heavy lifting (Masonry is actually quite excellent).

Keep in mind that my team builds web applications for Fortune 500 companies in a variety of industries, primarily working on analytics applications and other business intelligence solutions. We are a small consultancy group with engineers that have, each, over 20 years of software development experience and considerable subject matter expertise. All of us self-taught hackers. All of us love researching new ways to do things and then using them — and, of course, on the customer’s dime. Don’t tell anyone.

I’m in charge, because I can talk to customers that aren’t tech-savvy. None of my other team members are in charge, because they can’t. We all play Quake, and I’m very good with the railgun.

The point is, we’re not beginners.

So we had a relatively simple (actually, extraordinarily simple) request from a publishing company — build an interactive web application for a customer of theirs that allows users to select categories of content and display products that match those categories. The app had to work offline on an iPad and an iPhone, and had to work on the desktop as well.

So — cool stuff. The product database was relatively small, a few hundred products. We decided to store them in a JSON format on the client, and check for updates when the client was on the network. Data storage: check. Offline caching: Check. Well, sort of check — the application cache is a prickly pear in and of itself, but that’s a different topic. Didn’t even need a database server to deliver the product catalog, the customer was anticipating only quarterly changes and were more than happy to fund us to support that in an engineering way.

On to the front-end. We had two different UI’s in mind, one for the iPhone, and one for the iPad and desktop. As an aside, we’ve been doing a lot of that recently — we use the iPad experience to inform the desktop, and our customers have been very pleased with the results.

So — two different UI’s. Shouldn’t be hard, right? Figure there has to be a good methodology for handling this, some good frameworks, a plug-in or two that’ll help us.

The was some marketing-type content that we had to put up front — an introduction to customer’s products, some instructional content, author information, and so on. We laid it out, threw Masonry at it, and voila — it looked… Pretty good. Okay! On to the app portion of the application.

At it’s most basic, the UI was sort of like the iPad email application. On the iPad, a pane on the left for the product categorizations, and the main pane showing product details with various information groups along the top arranged in tabs:

There are maybe 15 different attributes that a user could refine their product search with, so it fit easily into the left pane in a nice list, pretty list, and when you click on the items, they had a nice little effect that showed you that attribute was being used in the product filtering.

And as you tapped, basic product information for each of the products would appear in the main pane, with a little thumbnail of the product, the name of the product, and a brief description. If you tapped on a selected filter, the product list would gently fade and refresh with your new list.

A series of tabs along the top would also appear, categorizing product information into buckets. The first tab would default automatically, and tapping the tabs would show the different sets of information — instructional data, pricing, contact information, and so on — for each of the selected products.

So — we have CSS driving the layout and Javascript handling the various interactions. Perfect start.

Then one of the guys took the iPad and rotated it. Not so perfect.

So, we took step one of RWD. But the first challenge presented — we wanted to hide the left pane when the user was done filtering attributes so that we could show more product data on the screen. We introduced a swipe feature on that pane, so that the user could select multiple attributes and then, when done, swipe the pane almost completely off the screen, leaving a little bit available so that the user could swipe it back.

But we didn’t want this to happen on the landscape orientation. So, in JavaScript, our first IF/THEN. If iPad AND Portrait, then add this swipe event.

OK. No big deal so far. We also had to enable scrolling on the tab list, because there were too many tabs to fit in portrait mode. But that was OK, too — we could do that for the landscape orientation as well, so this was just a CSS change.

But the attribute pane looked weird. It only had the 15 items, and so half the pane was empty. Making the item selections taller made it look like we were simply trying to fill up space. So, enter our first CSS media query — set the height of the left pane based on whether we were iPad portrait-oriented or landscape-oriented. Make the left pane sort of hover over the main pane, at half the height of the screen in portrait mode:

OK, so we’ve got a minor JavaScript branch and a few CSS media queries. Not bad, but we’ve only handled the same device so far. And looking into the crystal ball, we started to sweat.

RWD is, as I’ve suggested, primarily geared towards brochure-style sites: sites that are geared primarily towards content delivery and not interactive application functionality. The experience on an iPad can’t simply be reformatted to work on an iPhone — the experience often has to be completely different.

On an iPad, relative to an iPhone, the information and experience hierarchy is flat. If you refer to the above images, particularly the landscape one, you’ll note that everything is on-screen, all at once — the filter attributes, the product lists, the tabs. This is even the case on the portrait version, with the user having the added ability to swipe the filters away — so a slight bump in the hierarchy, if you will.

The iPhone User Experience Hierarchy

On an iPhone, the experience hierarchy can be deep. You only need to look at the Settings app on an iPhone versus and iPad to see glaring examples of how deep you might have to go on an iPhone’s navigational hierarchy as opposed to on the iPad. Go ahead and try it.

So, there were a few challenges now from a UI perspective. We needed to plan the information hierarchy — we would go from a user selecting one or more filters, and then to a user selecting a desired product (since it was only feasible to show a single product on the screen at a time), and then to the product details, separated in some fashion by the data categories previously represented by tabs.

Whoa.

At this point, we seriously considered doing what we thought would be best, and what we’ve done in the past — abstract out the JavaScript and CSS that could be leveraged by both the iPad and iPhone versions of the UI — and then have form-factor-specific CSS and JavaScript files.

But we didn’t. I wanted to forge ahead and see if there wasn’t something to this RWD thing. Is it as easy as people make it out to be?

Spoiler: It ain’t. Maybe for an online brochure it is, or a news article. But not for a web application. At least, not one you’d be proud of deploying, or one that your customer is likely to accept.

So, the first step — the left pane of filter attributes becomes the first full screen of the web application, taking up all the real estate. We do a CSS media query to handle the positioning. Turns out that the 15 or so filter attributes that fit so nicely in the pane on the iPad don’t fit on the iPhone without scrolling.

Well, in for a penny, in for a pound. We decide to use an accordion for the filter attributes, and divide the attributes up into groups that would make sense to the user. These were the same group names that separated the attributes in the left pane of the iPad user experience, so we didn’t have to think too hard.

So, we did a JavaScript branch for the iPhone — adding an accordion. We had to also re-factor some of the attribute-selection/deselection code so that it worked properly in the accordion, and also add some additional ability to indicate to the user that at least one filter attribute from the accordion group was being used in the filter. We were able to leverage that code in the iPad version as well, but it took some time to re-factor that.

Because the goal of the filter screen was to allow the user to select one or more filters, we couldn’t just display the matching products until the user was done selecting filters. Also, the user was given positive feedback in the iPad experience: as they selected filters, the products matching their criteria would appear automatically. They knew that what they were selecting was resulting in matching products.

So, we decided to show a product count — how many products matched the criteria you were selecting — and then a button that would take you to the products that matched when you were done with your selections.

Okay. So, another JavaScript branch, draw the button, add the logic for doing a product count when a filter was clicked, update the button. Add the button to the CSS file. No need to do it in a media query, really — but we were thinking that we might have to make changes in the future, and we could group by media queries, so we put it in.

Just a couple more IF/THEN’s, a couple more media queries… And our code is starting to look… Complicated.

Now, before anyone says “why didn’t you use Sencha or JQuery Mobile” or any of those other frameworks that at least handle the paging that I’m describing above, it’s because of this: if I used either of those, the app would look the same on the iPhone and the iPad; just smaller on the former, and larger on the latter. We would’ve had the same issues forking in the accordions and laying out the pages. In short — no way it would’ve worked and provided the optimal, device-specific user experience that we wanted to deliver.

Back to the task at hand.

So we have page 1 working. Now we have to show a simple product list of products matching the criteria from the filtering. We already have code that derives the product list, but the product listing itself is much different from the main pane display on the iPad. Much.

So we IF/THEN in JavaScript again. We show a simple scrolling list of products, we tack on a “Back” button so the user can get back to the filters, and we create a new action handler on the product list that will take us to the third page, where we show the product details.

Another IF/THEN in JavaScript. More CSS specific to the iPhone that had no analogous entries for the iPad, adding it to the same file as the iPad CSS.

A Brief Aside

By the way — at this time, we were showing our progress to the customer. They were happy with the direction, but wanted to change some colors and things, some global to both user experiences, some to one or the other. Our fault for thinking this was going to be simple, so I had my team re-factor the CSS and use LESS, parameterize the various colors and gradients they wanted to change, and embedded them with the media queries. Fortunately, LESS supports @media with nested rules, so while we probably should’ve used it from the start, it helped us out as the customer iterated on the UI.

LESS FTW.

Back to the story.

So, we have page 2. It’s a page that didn’t have an analog in the iPad version, so was brand new. Everything related to it was in a JavaScript IF/THEN or CSS media queries.

More branches. More queries.

On to page three. This is a completely reformatted version of the main pane in the iPad application. Once again, we had too much data to show all at once, so we converted the tabs to an accordion, and put the product information in their appropriate accordion group.

Oh, and a back button to get back to the product list. And a “Start Over” button so the user could.

And I haven’t even mentioned all the transition effects and so on, all stuff that didn’t exist in the iPad version. All in CSS. And JavaScript. In those branches I keep referring to.

So now page 3 is working. The display is great, we’ve got the transitions down pat.

And, as you can imagine, the app looks nothing like the iPad version. It couldn’t be more distinct. And the customer loves it.

But our code was grotesque — a rats nest, a rabbit warren of branching logic throughout each of the front-end components. All using so-called RWD techniques and approaches espoused by people that know little to nothing about web application development and user experience. We considered it a failure. A relatively simple application, particularly when compared to the enterprise tools we’ve delivered in the past, would cost us double-time to support in the future. Unacceptable.

So, we re-factored again. We shifted all cross-screen JavaScript and CSS to their own files. Our single-page application index.html file referenced the appropriate, form-factor-specific JavaScript and CSS files during page load. We eliminated virtually all branches in JavaScript related to screen or orientation.

And all was good again.

We presented the final application to the customer for review. He held his iPhone and said the application looked great. As he put the iPhone down on the desk, he rotated his hand ever so slightly. By the time the iPhone had hit the desk, the web app was in landscape mode.

It did not look good. But we smiled, knowing that we’d already done the heavy lifting in our re-factoring and abstraction. So when he asked if we could support landscape on the iPhone, we said “Sure.”

What RWD Is

So that is what RWD is all about — good programming practices, not the expectation that one size fits all when it comes to a web page, not just an accumulation of responsive widgets, and sure as heck not as simple as everyone makes it out to be.

If you are building a web application, don’t expect the RWD you read about to be the RWD you will use. RWD is going to be about abstraction, code management (i.e.), and using the right methodologies. Not about a carousel.

I would really love to hear from anyone who has had similar experiences or differing opinions and approaches… We are also on the hunt for code organization tools that help specifically with this type of challenge. Submit your comments!

Responsive Web Design: A Time and Place for Everything

13 Comments

The only way responsive web design works is if it is thought of as a strategic engineering approach encompassing all facets of development, not a strict presentation solution.

(me)

There’s been lots (and lots) of talk about responsive web design (RWD). There’s been lots (and lots) of development in this area, from JQuery plug-ins to CSS processors to grids.

When you’re done reading this, check out my latest post on RWD — RWD Revisited.

There have been blog posts, by many well-meaning people, on the tremendous benefits provided by responsive web design and how those who don’t do it are forking themselves. The idea is that you can use a magical technique called “responsive web design” that will prevent you from having to code around different form factors, and that it is the panacea for the web development of mobile solutions based on their big desktop ancestors.

There has been, from what I’ve seen, a few (here, here) well-thought-out criticisms of RWD. And really, those two are decent, but where they touch they touch gently, as if afraid to buck the latest du jour and inspire ire. And where they don’t touch, I think they miss.

One example would be Karen McGrane’s recent blog, which makes, in my opinion, too many assumptions in its argumentation, which in turn oversimplifies the direction she proposes that web application developers take.  She is not alone in her opinion, and I’m also not suggesting that she is completely wrong — but if you were to simply read the article and take the advice, it’s a mistake. And I grow weary of the lack of educated dissent with respect to RWD. We all need a good argument, the devil’s advocate.

Many of the proponents of responsive web design (not the library makers — they’re responding to demand) are talking about content sites. Online brochures. Menus for the local eatery. Newspapers. Blogs.

Okay. Now I get it. And it makes sense. And I would agree that using media queries and javascript to reformat your pages makes a lot of sense there. You get to leverage your CMS and the bulk of your layout code. And you probably only need to make some minor adjustments to your css.

Anything beyond those site-types, however, and you wind up doing exactly what Karen says you’d do if you didn’t use responsive web design, only it’s more insidious — you won’t be creating forks of your code, you’ll be creating a wasp’s nest within your trunk.

For web applications that deliver capabilities beyond that of your typical content consumption site, there are (often vast) differences in the use cases for those applications. Here is where Karen errs (if she is making a sweeping argument for responsive design that covers all sorts of web-deployed solutions). I couldn’t possibly disagree more with her assertion that you need to focus on losslessly cramming your desktop content down into a mobile screen. Ah, actually, I can disagree more, because I even more strongly disagree with her assertion that “[we're] going to guess wrong” when it comes to thinking about what content and features users of our desktop solutions will want on their mobile devices. Sorry, that’s snarky… But when you make your living developing screen-to-screen solutions for Fortune 500’s, and then you’re told that you won’t figure out what your users want, so give them everything you gave them on the desktop… Well, it rubs the wrong way. It teaches the wrong lesson.

Let’s talk about forking. The idea behind forking is you are essentially creating (at least) two versions of your web application — one for desktop, one for mobile. In theory, you could also have one for tablet, one for a particular brand of mobile phone, etc. Proponents of RWD says this is bad.

Let’s talk about responsive techniques. Let’s talk about media queries — the “if/then” of the css world (apologies to LESS etc.). If you build a single app and aren’t going to fork as per the implicit prescription of RWD, your css can possibly double in size. No joke. CSS defines the layout of your content, the positioning, visibility, appearance and animated properties of all of your on-screen elements. For richly interactive applications that are to be deployed to multiple form factors, a single, all-fitting css file is going to be a rabbit warren of media queries inspecting the browser dimensions and laying objects out accordingly. Have you ever seen a css for a complex web application that is attempting to leverage responsive web design? Maybe the apps I’ve seen were coded by shoddy developers — their sites look awesome, but that doesn’t mean they’re good developers — but as a developer, this is exactly the situation you will run into when you want to leverage css for responsive web design for complex web applications.

Some might then argue that you would have different css files and load them up at run-time. Hey, no cheating! What’s the difference between forking and having one css file for desktop delivery and one for mobile? I call foul. You wind up maintaining both anyway.

Now let’s talk about JavaScript. RIA’s do a lot more than present content — they present content and application functionality in interactive ways. On a desktop, that means a click on a navigation menu. On a tablet, that might mean a swipe from the left side of the screen to slide into view a navigation bar that will gracefully glide away once an option is selected. On a mobile device, it’s a menu button that slides down your menu options, which will slide up and dissolve in your selected option.

So, some of that is handled in css (there you go again with the spaghetti media queries). Some of that is handled in JavaScript. A lot, in fact. So, in your JavaScript, you are, again, inspecting browser dimensions and forking branching to the appropriate handlers (or specifying appropriate functions in your callback routines). You are, in JQuery if you’re lazy like me or straight-DOM if you’re a masochist, adding or not adding interface elements, setting format-specific event handlers.

Now, I’m not suggesting that you maintain separate JavaScript files for every screen you are targeting. Not hardly. But the proponents of RWD who exclaim “Oh! Use responsive web design and your problems are solved!” are naive. It suggests that, if you do your css just right, all your problems go away. This is disingenuous.

Let’s talk images. Sure, there are JQuery plug-ins for thumbnailing, ways in css to resize background images (but only background images — not images embedded with, you know, the IMG tag). But they’re still operating on images geared towards a desktop use — namely, they’re big. With big, bandwidth-eating byte counts. You will want to have smaller versions of the images. Same with video. No amount of RWD on the client side is going to shrink those images down for you until they’re already downloaded to the client.

You may even want different images or video based on the form factor. Karen’s argument here appears to be that you’re making a big mistake — that you should simply mobilify everything on your site via responsive design, don’t cut content, and so on. Again, that’s fine for the relatively simplistic world of content-focused sites. Applications aren’t going to work this way.

Which brings me to Karen’s next point. That we shouldn’t provide different functionality based on the form factor. This (and this is my opinion — flame away) is wrong on so many levels that would be evident to any company looking to deliver a compelling and meaningful experience on a phone — or even a tablet, which has roughly similar dimensions to a desktop, but significantly different user interactions.

Use cases are not meaningless. I can give Karen the benefit of the doubt — perhaps she really is just talking about content sites (though she did seem to indicate otherwise). Again, I agree that the use case for someone reading a newspaper is going to be the same on the desktop, tablet and phone — the use case is, “I want to read this article.”, and the subcases are “I want to read this article while sitting at my desk when I should be working”, “I want to read this article while I’m sitting on my couch drinking a cup of coffee when I should be playing with the kids”, and “I want to read this article while I should be paying attention to the road while I’m driving”.

But for web applications, the use cases can be completely, dramatically different. Take business software, for example — salesforce automation, analytics software, take your pick — there is no way the use case is the same across screens for these types of applications. And if you simply shrink down your desktop SFA solution onto your mobile device, you are doing your mobile users such a disservice that they are unlikely to use your software, you will lose your sale, you will re-enact Platoon scenes with Charlie Sheen, etc. etc. Don’t re-enact Platoon scenes with Charlie Sheen.

Screen specialization is important for your product. I don’t want to take the time to describe why, it just seems so self-evident to me. I could do it though, if I had to. I could point you to the mobile versions of LinkedIn (nope — not just “responsive web design”). Concur. RoamBI. Microstrategy. YouTube. Netflix. Zillow. Amazon. eBay. WordPress! Nope — not just “responsive web design”.

So, in summary — there’s a place for responsive web design. And it’s a big, big place — I’d say a vast majority of web sites are more content than application. But it isn’t the solution for everyone, and sometimes, you gotta fork.

One final word, though — I agree with Karen on content. Content should be display-agnostic, for the most part. Intelligent organization and inspection of media meta information should solve many of the issues related to retrieving appropriate assets for display. This is similar to back-end support for your front-end in rich internet applications: design your web services appropriately, for example, and you can leverage them in any of your front-ends. Now THAT’S responsive design.

RWD is not just CSS. It is an end-to-end development methodology that is too often oversimplified and positioned as the right, the only, approach for mobile solution development.

Uploading Files via JQuery

Leave a comment

To me, adding the ability to upload files is always such a hassle. I think it’s because I’ve only had reason to do it a few times in my career, so I never really established a solid pattern (though they typically used COS on the Java server side). 

There’s an interesting AJAX uploader JQuery plugin that really simplifies the front-end, and better yet, comes with sample back-end code for Perl, PHP, CF and, most importantly for me, Java. It executes the Java side as a typical HttpServlet, so it should be easy to incorporate into your stack.

On the front-end, it supports drag-and-drop in Chrome and Firefox, with a progress bar in Firefox, Chrome and Safari. 

So, what if you want to support Internet Explorer? Easy! Check out Google Frame, and make WebKit your go-to renderer on IE. 

So you think you have pressure at your job?

Leave a comment

Gadgetbox – Designing Windows 8, or how to redesign a religion.

This guy… He’s got pressure.

Build Business Apps Like Blizzard Would

3 Comments

BI Like StarCraft

The interface between a user and the functionality a software solution provides is critical. I’ve presented software of my design to med device, pharmaceutical, banking, entertainment and consumer packaged goods companies, and if I’ve done a good job, the feedback tends to include the comment “that is so much easier to use than x’s”, where “x” is the competitor. I focus on simplicity, I focus on the bare essentials of solving specific problems faced by my customers. This doesn’t mean I deliver under-powered solutions, it means I deliver front-and-center the functionality that will be used 85% of the time, and shift the rest elsewhere in the experience.

What is my guiding principle? Pretend I’m building a game.

Why can my 8 year old create armies and buildings that have specific build orders and interrelationships with each other, create multi-step workflows and battle plans, but most adults struggle with adding an order in SAP? Why can my 10 year old manage the intricacies of building up the economy of a city that she created, but a veteran subject matter expert has difficulty creating a customized bar chart in leading BI tools?

There are deep usability flaws in many enterprise and niche software solutions. Many developers confuse a complex information hierarchy with a positive marketing image — they think, “the more I put on this screen, the more robust the app will look.” By throwing everything on the screen, it looks like it has twice the functionality of a cleaner-looking competitor. I’ve been a victim of this myself — I’ve bought backup software that looks like it belongs at NASA Mission Control, only to ultimately replace it with one that essentially says “Click Here to Back Up”.

Where games succeed at creating simple interfaces to processes that are often far more complicated than a typical business process is in the presentation of an appropriate information hierarchy. The graphic design — the use of colors, images, shadows, placement, text — draws the users attention to where it needs to be.  Navigational elements such as menus and buttons will clearly identify where users can go deeper into other functionality based on where they’ve navigated, sensitive to the context that the user has placed themselves in, and with a clear path back. Targets for physical interactions such as mouse-overs, clicks, swipes and taps are obvious. Feedback is constantly provided — if something is going to be less than instantaneous, there will be some indication that you are being asked to wait, whether it is a busy cursor, a semi-opaque screen overlay or a well-placed but non-obtrusive message, so the user can continue viewing the screen while they wait. Games take advantage of asynchronous processes, so that the user’s time is not completely wasted while they wait for something to happen. Features that are not usable based on the user’s context are minimized, if not outright hidden in the information hierarchy.

Game IT

Build your apps as if you were building a game —  games succeed in delivering complex functionality in packages consumed by children.

Rip apart the functional requirements, and assign each one a relative factor of frequency of use and of detail granularity — and build your solution based on those frequencies. Build relationships between those functions — one-to-one, one-to-many, many-to-one, many-to-many — and put together an appropriate information hierarchy that will let users move seamlessly from higher frequency, front-and-center features to related but less-used (or more detailed) functions.

If you start thinking about apps as games, you are on the path to creating compelling and inviting user experiences that will differentiate you from your competition in the most significant of ways — making the end user feel comfortable with your software, and confident that they will be productive by using it.

Nice New JQuery Playthings

Leave a comment

Good article I found late at night while perusing Zite showcases some JQuery plug-ins.

Here are my favorites from the full article on splashnology.

JQuery Transit

This plug-in rocks. Not only do I plan to use it in the future, I plan to use it in the past. This provides a simple JQuery syntax for cross-browser CSS3 transformations, taking advantage of hardware/browser accelerators when possible. Supports JQuery chaining in a very simple way, so you can string multiple transforms together that will run synchronously. No need to worry about -webkit- or -moz- or -blahblah-.

JQuery Collapse

Absolutely critical to my UX design is the shifting of less-essential controls and data off to the nether regions of the main screen, but keeping them close enough to allow the user to get at them without navigating through a hierarchy of drop-down menus. In fact, I do not use hierarchical drop-down menus. Ever. Collapse gives you a real easy way to hide and then show content, and does it with persistence through the use of cookies. Cool.

Sisyphus

Now this is super-cool. Sisyphus, when applied to a form, will use the local storage features of HTML5 to store (er, locally) all of the values you are entering into the form. So, if you time out, or close the browser accidentally, the power goes out, etc., all you do is come back to the page and — presto — all of your form entries are back. Includes support for all form elements, too.

Fear

1 Comment

You know there’s this one guy at Facebook who’s got the juice to make a one-line addition to a little piece of code.


private boolean userCanSeeThisPersonsStuff(Facebooker person1, Facebooker targetPerson) throws SecurityException {
boolean canView = crazilyComplexRecursiveSecurityFriendCheck(person1,targetPerson);
   canView = true;
return canView;
}

Scary.

Older Entries

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: