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.
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.
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:
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.
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.
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.
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.
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.
Back to the story.
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.
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.
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!