Is Responsive Web Design a Lie?

I’ve previously written about the importance of keeping a focus on users when thinking about responsive Web design. I’ve also written about ways to think about responsive Web design in the context of doing interaction prototyping. I’ve personally had some experience designing responsive interfaces. I’ve spent time with my colleagues thinking about how to support responsive Web design in Indigo Studio, and I’ve talked to other designers about their experiences with RWD, including their experience with other tools.

Here’s the thing, so far, it seems to me that responsive Web design is a lie. It is snake oil. To be clear, I’m not saying that the actual technique of using CSS media queries to set breakpoints is a lie. That is a fact. You can do that. What I am saying is that what most people seem to take away from RWD after learning about it is this:

Hey lookie, I can design/code one thing instead of three (or more) and have it just work on all those things equally well.

Smoking SomethingThat. That is a lie. It’s a pipe dream. You’re smoking something. It’s just not that simple. It’s not that simple from a design perspective, nor is it that simple from a code/dev perspective, except in the rarest, simplest cases. Even if you can simply use media queries, it can get pretty convoluted pretty easily. Even something as conceptually simple as an image is troublesome in RWD.

The reality is that most folks, even big RWD advocates, usually advocate for more than media queries–like RESS–sometimes this is strictly to help with performance (especially on mobile), but it can also be to deal with complexities and/or to simply make the desired designs feasible.

And RWD is sneaky. You start out thinking, hey, I’ll just add this breakpoint, then I just move this here, this there, and so on. Then you realize, hey, that’s actually not that great for <the phone | the tablet | the desktop | the TV> and you change this little bit here, that little bit there, and before you know it, you’ve got this huge jumbled mess that actually makes it harder to improve and maintain than if, for instance, you had just created different, cleanly separated apps in the first place.

OR (even worse from a UX/Design perspective), you start making design concessions in order to keep the thing manageable from a technical perspective. Oh, it’s not that bad, really. Or you might think, if I do that better design, it’ll be hard to implement and hard to maintain, so we’ll stick with this half-ass solution–just for the sake of the principle of RWD. This is bad for prototyping and bad for design.

So let’s zoom out a bit. What are we actually trying to achieve? I’ve heard basically three goals:

  1. One URL. When you give people a URL (e.g., in an ad) or they find one (e.g., in something shared on social media), you don’t want to land them on a solution that was designed for the wrong device class. You don’t want to offer (normally) a “view this in our standard/full site” or vice versa. It should just work and just be optimized for their device class (see my article describing device classes).
  2. One set of code/design. Across device classes, there is a lot of stuff that can be shared. The benefits are less implementation time and when you update it in one, it is updated in others. The underlying benefit is simply that it is theoretically more feasible to target multiple device classes if you leverage this one-solution-for-all sharing.
  3. “Fluid” resizing. When orientation changes on a device or a browser window is resized, it fluidly rearranges.

RWD is promoted as the current/best solution to these. But the devil is in the details. Sure, it solves #1 hands down. But #2 is where things get hairy, as noted above. I would suggest that #3, in most cases, is really just not that important. If there were interactions in your solution that made resizing/changing orientation an integral activity, and you wanted that fluidity to enhance those interactions, maybe it is valuable. But in most cases, how fluidly it resizes is far less important than the fact that it does. Most people don’t sit there and resize just to observe the beauty of the fluidity of the layout system.

Where do we go from here, then?
One way forward is to keep holding onto the RWD dream and try to beat it into submission. Make it work, no matter how hairy things get. This is an ideological solution–you value the RWD pattern more than actually crafting solutions that are best for your users/business. The other reason to move ahead with RWD is that you are naive and believe that RWD will deliver everything it promises. In both cases, it’s not a great premise.

So should we be asking ourselves, are there better solutions to achieve these goals?

Some observations:

  1. There are no silver bullets. If you want a great experience for people on each device class, you have to design for each device class. This is work. It may or may not imply that you can leverage RWD as an implementation technique, but there is no free design here. If you want things to fluidly and intelligently reflow and rearrange, you have to define the rules for your context. And beyond very basic layouts/nav, you are going to need to reimagine how some things work depending on the device class–what works well from an interaction perspective on a phone is different from a tablet is different from a desktop is different from a TV is different from a kiosk is different from wearable devices… No tool, whether you hand-code RWD or use a WYSIWYG tool like Indigo can protect you from having to think about and design for these different device classes and their related contexts of use.
  2. The more complex your solution is (on one platform) the more complex it will be to make it work across platforms, and that complexity increase is non-linear, especially when you try to make one set of code work for all of them.
  3. What we have here is essentially another incarnation of separation of concerns. The same reasons you should keep your behavior separate from your structure separate from your styling are fundamentally the same reasons you don’t want to bunch up trying to serve multiple device classes in one solution.

So I think if we consider the problem from a view to separation of concerns, the solution is clearer.

One App, One Platform
One solution is of course the independent, per-platform app solution. Most people will agree, as a rule, that this is the best approach to maximally optimize the experience for each platform (much less device class). What will feel best on Windows Phone is an app that was designed for Windows Phone, and the same applies for the other major platforms.

This implies the least amount of reuse across platforms and the highest cost of implementation and maintenance. The problem is that this is not feasible for a very large segment of people who need to make software run on many devices.

One App, All Platforms
This is essentially the RWD solution. In theory, it sounds great. In reality, it’s a lot more complicated than it sounds and often can result in suboptimal experiences on each device class. Further, there are hidden design, implementation, and maintenance costs.

There’s also a lot of talk about “future proofing,” but that too is only a half truth. At a minimum, it presumes similar input/interaction modalities for new devices, which are almost certainly not going to be there in many cases. And if the new interaction modalities can be mapped to existing ones (think, for example, touch gestures to mouse/keyboard), it again could easily result in suboptimal experiences for these new device classes. So it may or may not work on new devices/interfaces–that’s the best we could claim. Hardly a compelling reason to adopt an approach.

One App, One Device Class
This is the path that seems most viable to me. The basic premise is both your designs and your implementations are cleanly separated across device classes (i.e., you have a phone solution, a tablet solution, a desktop solution, etc.). You can even map device classes together if they are close enough–you could have a tablet/desktop solution and a phone solution, or a desktop/TV solution. If the similarities are close enough/good enough, you can still make those trade-offs and combine classes, without (as with RWD) assume all in one.

  1. It is honest about the complexities involved, both from a design and (potentially) implementation perspective. It treats the experience with a particular device class as something that should be considered on its own.
  2. It makes it easiest to optimize for each class. Through separation of concerns, the design effort is cleaner and, even more so, the code is cleaner. You don’t have elements and their styles stomping on each other.
  3. It strikes a good balance between optimization and reusability. You don’t have to make an app per platform, nor do you have to contort your mind and code and (often) the experience to suit all possible interaction modalities and layouts in one solution.
  4. It is honestly future proofed. Probably the underlying technology will still be Web. And as new devices emerge, you can see if the device can be assigned to an existing class or not (based on more than simple width of viewport). If so, it’s simple enough to “turn it on” for that device and have it share an existing device class solution. If not, then at least you’re being honest about it and not serving up some half-baked solution for it. You can choose if the new device class is worth investing in a specialized solution. If it is, probably there will be multiple vendors with that class of device, so you still can target cross platform that way within the class.
  5. You can be more strategic about what is shared or not shared. Often your data services can be shared across most classes. Your content can be shared. Your styling, to an extent, can be shared. Even individual pieces of the UI can be shared. Plus, you can encapsulate what is shared more cleanly. Instead of starting from a base that makes everything shared by default (RWD), you select the things that make sense and share them. This makes the sharing and the per-device-class code cleaner.
  6. You can avoid improvement paralysis. If every change you make has to be simultaneously made to every device class, it makes you that much more hesitant to make changes–you have to be ready to deal with them all at once. This equally applies to changes that make sense for all device classes as well as optimizations that make sense for one device class. It doesn’t matter. When everything is mixed in together, you always have to worry about unintended consequences to everything that is sharing it. With a per-device-class approach, you can feel much more confident that your design changes are safe. You can tackle each class at a time, which is ironically more manageable than all at once, and you can make sure the change is optimized for that class.
  7. You can still achieve fluid resizing per device class (whether that is resizing windows or changing orientation), if you feel that’s important enough to invest in. If it is Web, you can still leverage its built-in reflowing capabilities and even use some RWD techniques.
  8. You can still manage URLs and loading the appropriate experience for a device class, in most cases. Again, if it is Web, there are plenty of techniques you could use based on user agent information and serving up the appropriate device class solution based on that, with a good default.

None of this means that RWD is never a solution (it could even still be part of the solution). The problem is that it has become the proverbial hammer that makes all apps look like a nail. People are assuming it is the way to approach both prototyping and implementation. The hype around it causes expectations to be very disproportionate to the reality–which ends up sending people down the wrong road and causing all sorts of unexpected pain for them. It ties them to that approach, which is like a spiral of doom that it is hard to break out of if you need to.

If all you have is a basic informational Web site with basic navigation, you can probably get away with just RWD without it being too painful. There may be enough things in its favor to warrant that approach. Even so, you risk writing checks that will bounce if, for instance, you think this means that all this responsiveness is “for free” or that it means you are future proofed. On the other hand, it seems to me that assuming a baseline of per-device-class designs and solutions, strategically sharing across them, is a much more realistic, honest, and optimal approach in most cases. What do you think?

Advertisements

It Feels Good to Know and Do Things

He-Man says I have the Power!

Every so often another article appears somewhere advocating creating prototypes by coding. There are many drawbacks in doing that, not the least of which is simply wasted time–time spent dorking around with code that would be better spent evaluating, iterating, and synthesizing design ideas. In response to one such article, I penned “Yes, Ditch Traditional Wireframes, But Not for Code” that goes over the various drawbacks.

Prototyping is Hard
I suspect part of the reason people want to jump into code is potentially a misunderstanding about what a prototype needs to be. Many people, when you say “prototype” think something like a near full-on app simulation, they worry about whether or not it is responsive, or at least, there is some latent idea that it is time consuming and involved. This does not have to be the case, and in fact, I would suggest that it is not good if that is the case, for the most common prototyping needs–the ones that enable you to explore interaction designs and find the best.

Prototyping Tools Are Hard
Another part of the problem, related to the weighty idea, is that most prototyping tools are themselves time consuming to learn and use, even if you don’t want to build a particularly deep, complex prototype. That is a core problem we have tried to address with Indigo Studio; we focused on the idea of sketching prototypes, that is, to make creating a prototype as easy and simple as sketching out ideas on paper/whiteboard (and even faster than that).

You’re Just Biased
Now, some have said, “Ambrose, you only advocate code-free prototyping because you have a vested interest in hawking Indigo Studio.” Well, leaving aside that this would be an ad hominem fallacy, I will first point out that Indigo Studio v1 is totally free of charge, and that you can keep it forever–you never have to upgrade. Everything I advocate for is essentially contained in the free version, so I have little to gain. I am also not saying Indigo Studio is your only code-free option; I just happen to think it is the best. 😉

Second, I invite anyone to spend the amount of time it takes to become effectively familiar with any code-based prototyping framework. Then spend the same amount of time familiarizing yourself with Indigo Studio. I kid! You need spend nowhere near that much time to become effective with Indigo!  

And once you are passingly capable with both tools, do a head-to-head challenge, starting from zero. I guarantee that in the time it takes you to just get a project environment set up with your favorite prototyping framework, you will already have created a working prototype in Indigo. It’s just that fast and easy.

Nope. It Really is More Efficient and Effective for Design Exploration
What I’m saying is that, essentially, by any objective measure, it will be faster to create prototypes that are good enough for evaluation in a tool like Indigo. Not only that, Indigo helps keep you from being unnecessarily distracted with unimportant details, while coding does the opposite. Indigo also helps you stay focused on users and their concerns, while coding does the opposite. 

Now granted, there are exceptional circumstances, but I’m talking about a general rule here. If nothing else, one doesn’t need to invest a lot to sketch prototypes with Indigo, so you don’t lose much if you find that for whatever reason, Indigo is not sufficing for your evaluation/design exploration. The inverse is absolutely not true with coding frameworks.

It Feels Good to Know and Do Things
Given all this, I have been thinking about why people would still cling to the idea that jumping right into a coded prototype is the best way to go, as a rule, for designing. I think at least part of it, if not a large part of it, has to do with simply feeling more knowledgeable and competent.

There is a certain satisfaction that comes with knowing arcane knowledge (like how to code)–one joins the ranks of the elite designers who can code. There is also a certain sense of accomplishment in using that knowledge, struggling with code, and coming out on top in the end (assuming you do come out on top and don’t walk away defeated). It’s like He-Man–by the power of code school, I have the powerrrr! 

As someone who first learned to code and worked for years as a professional developer, and then learned to design as a professional interaction designer, I can relate. (I can also, thereby, speak from experience and not ignorance that coding prototypes is as a rule a less effective starting point for design exploration.) The challenge for those who can code is to ensure that we are making choices for what is best for the design problem at hand, and not what is best to stimulate our own sense of empowerment and accomplishment.

It can be fun to code–especially when you are new to it. It’s similar to making cookies from scratch, the way grandmama use to make them, instead of just buying the pre-made dough you just break apart. That’s fine when it’s for our own entertainment and enrichment, but when we’re being paid as professionals to be as effective and efficient as possible to design the best thing we can, we probably should think twice about taking the slow prototyping approach because we enjoy it more.

There Is Satisfaction in a Job Well Done
And that’s not to say that there is no enjoyment in using code-free tools. It’s just a different kind of enjoyment and satisfaction, one that comes from feeling more efficient and effective in solving design problems rather than coding problems.

I am not saying definitively that one should never code a prototype–far from it. But in their enthusiasm for their skills, I am concerned about this trend in the software design community to advocate coding as somehow better, more superior, or more effective in doing design work. Most of the reasons given for doing so are missing the mark for design/human concerns, all the while ignoring the many hidden drawbacks.

The rule should be to avoid coding except when you are fairly sure it is the only or most effective way to prototype your design ideas.

 

Yes, Ditch Traditional Wireframes, But Not for Code

Just Say No To CodeI just ran across Ditch Traditional Wireframes in UX Mag. I agree with the basic premise–that static, especially high fidelity, wireframes should be eschewed, but the conclusion I draw about what to do instead is a bit different.

The author of that article, Sergio Nouvel, propounds the wonders of just jumping right into code by doing HTML-based prototyping after nailing down initial concepts with other low fidelity options. The problem is that Nouvel does not identify the drawbacks from such an approach:

1) Despite the relative ease that frameworks like Bootstrap and Foundation provide, jumping into code has the immediate effect of warping the designer’s mind. I don’t care how disciplined you are, when you start dealing with code, your brain is forced to start thinking from the code perspective. It is not acceptable to switch at the interaction prototyping phase from a human-centric focus to a code-centric focus.

2) Especially in non-WYSIWYG environments, you are forced into imagining what tweaking this bit of markup, CSS, or JavaScript will have, then you do it, and then you verify it. And you often find it’s not quite what you had in mind, and repeat. With that, you end up wasting a little time here, a little time there, a little time everywhere fighting with the technologies just to do the simplest things.

3) It forces the designer to learn to code. That is a double-edged sword, as I discussed not long ago in To Code or Not to Code.

4) To be truly easy to maintain and change takes a LOT of planning up front. Even developers struggle with this, and they’re all about reuse and minimizing effort for changes. To pretend that just using code means things are automatically easy to maintain is just wishful thinking. Sure, maybe changing a font color, but changing shared navigation, layouts, etc.–things that are far more pertinent to rapid design iteration–are not easy changes in code. At all.

5) Interaction prototyping is not the same thing as production coding. To pretend that the code a designer writes in a prototype is going to be good for the real product misses several key considerations:

  • Devs are notorious for being picky, and rightly so, about their code (see the last point about code reuse). The chances they’ll just run with prototype code are quite slim, especially if that code relies on prototyping frameworks.
  • The focus of a good interaction prototype should be the interactions, not to have clean, well-layered/encapsulated/maintainable production code. If you use code for prototyping to have “build the real thing,” you’re missing the point of interaction prototyping.
  • Using HTML prototype code as production code only applies, and only sometimes, for Web apps, and simple ones at that.
  • What about statefulness and data? Are you really going to spend time on that in your prototype?  Anything beyond a basic informational Web site needs this sort of thing.

6) Worrying about responsive design at the interaction prototyping phase is premature. We’re in the higher point of the hype cycle for responsive design. Yes, it is nifty for some design needs. But it is hardly a panacea, and more importantly, it (like code or tech) should not be the big thing you’re worried about when doing interaction prototyping.  Why? Because from a user experience point of view, it’s just not that important.  Many of your users will never know if your site is responsive, and very few will care, as long as they get what they want from you.

7) How are you going to share your prototypes? Using HTML means you’re going to need to secure a hosting place, deploy it, and ensure it is accessible for people. And you have to keep updating that. One more thing you have to learn to jack with just to get some design ideas fleshed out and tested, one more thing in your way when you should be simply focused on exploring and evaluating design concepts from a human perspective.

So what should you do instead of static wireframing? Why interactive prototyping, of course! 🙂 Before you shake your head and say it is too hard or too cumbersome, I suggest you try Indigo Studio. Full disclosure: I had a hand in making it, but the reason we made it is because we think it addresses some real needs, such as:

  • The need for rapid exploration of design ideas from a user-centric perspective.
  • Being able to do rich interactions and animations without worrying about code or learning to code.
  • Integrating stories and human contexts into your digital design.

And guess what, Version 1 is totally free, forever.  There is no obligation, no time bomb.  So yes, definitely, ditch traditional wireframing, but not for code. It is good for some needs, but when you’re doing interaction prototyping and design exploration, that’s not the time to saddle yourself with all those ancillary concerns.

Give Indigo Studio a Try!  I recommend watching the videos–they give a good idea about how Indigo Studio is different and tries to address these needs.