A difficult aspect of interface design is making complex tasks feel simple and easy to do.
Often a task is conceptually simple, but the complexity comes from the implementation and edge cases. In this post I’m going to explore the process involved in adding more functionality to our filtering UI without compromising usability and the product decisions we had made before.
To give you some context, at GoSquared we offer the ability to see your users on a per-person level, and intelligently automate actions based on things they do throughout your site or app. The actions are linked up to people entering and exiting Smart Groups — a set of properties or events you filter your users by. When someone enters (matches) that filter, or when someone leaves (stops matching), an action is triggered. You can set up Smart Groups to do pretty powerful things like encouraging loyal and active users to upgrade their subscription.
Previously, you could only construct filters using the AND operator (e.g. find all the people who are paying customers AND have logged in within the last 30 days AND have product emails enabled), however as we and our customers started using People more and more, we started feeling the need for building more advanced filters.
When filtering users, we found that often you’ll want to target different values for a property (e.g. users with their “location” set as “London”, “Paris” or “Berlin”), or want to target multiple behaviours at the same time (e.g. having multiple definitions of what an “active user” is). Only being able to build filters with AND operators became limiting, so we decided to add the ability to build filters with OR operators as well.
When talking to our customers, the reoccurring frustration with services offering similar functionality was being limited to the use of just one operator (either only AND operators or only OR operators). From a technical standpoint it’s not hard to filter with multiple operators; the difficulty is in creating a user interface that is easy to understand and use.
Design with real examples from the start
The first step in tackling the problem was to put together a list of filters that we and our customers wanted but were unable to use. Using real examples from the start of the design process is incredibly important as it forces you to design for the reality and not just what looks or works well. I often come across beautiful mockups of user interfaces that end up failing in the real world because they’ve used idealistic examples.
Josh Puckett wrote a fantastic article with his thoughts on bringing real data into your design tools, which I highly recommend reading: Modern Design Tools: Using Real Data
Getting your ideas onto paper quickly
The next stage in the process for us was getting as many ideas out of our heads without worrying too much about constraints or limitations. The goal here was to go through as many ideas as possible without getting attached to any single design. I personally like to sketch out variations quickly and get as much of what’s in my head on paper as soon as possible and then develop them later. This is a process to get lots of ideas you can develop and refer back to later, but done in a way that doesn’t require you to spend more than a few minutes on each variation — the longer you spend developing a single idea, the less likely you are to explore others.
When deciding which variations are worthy of testing and developing, its often useful to reflect on what your current designs do well. When adding new functionality, it’s often difficult to maintain the simplicity and ease of use of what already exists. Think about how frustrating it is when a service you use adds a new feature but at the same time breaks something that previously worked well — it sucks. In our case, although the filters you could put together were limited, building them was an incredibly easy thing to do — it was just one button to add a new parameter to the filter. Another incredibly useful aspect was the results updating as you built your filter — you’re able to see how each piece of your filter affects the results, allowing you to spot mistakes in your logic sooner. Those were two really important features we knew we wanted to have continue through to our updated design.
Building prototypes for rapid iteration
Prototyping has always been an important stage in the design process and it often feels theres a new tool for creating prototypes every day. When deciding which tool to use, it’s important to know what you’re trying to prototype — is it the whole flow? Just the interaction? Something else? Different tools are better at different things. A good question to ask when evaluating tools is: which tool will help me iterate most quickly for what im trying to test? You want to choose a tool where you’ll be able to make changes easily, and quickly.
We went with simple HTML + jQuery + CSS instead of anything fancy. It’s quick to work with, doesn’t require learning any new tools, and by moving options into variables, is easily changeable. Additionally, we were only focused on interactions and less so about visuals — any visual cues we really needed were applied roughly in CSS, but otherwise just left as the browser default styles. For each prototype iteration we’d duplicate it before we make a change to give us an old copy to refer back to. Sometimes you’ll explore an idea and realise that wasn’t the right way to think about it; you can then go and take another direction from a previous version.
User testing internally and externally
Throughout the prototyping stage we’d ask other members of the GoSquared team to have a play around with the prototype and try to perform the real world tasks we collected at the start. During this, we’d observe how quickly they understood how to get started with the tasks, where they got stuck, and how they resolved any issues they came across. Interestingly when you have multiple tasks to perform, you can watch to see how the user goes about moving from one test to another. In this case, asking to build one filter and then another, provided the opportunity to see how people naturally go about editing and resetting their filters.
In this prototype, parameters were added with the + button, which would AND it to the other parameters. When clicking on an “AND” it would switch to OR and create an OR group with the parameters either side. In practice this was not obvious and quite complicated on a conceptual level. From the user testing, we found that’s just not how people think about building their filters, but it was interesting to experiment with something quite different early on.
A later prototype replaced the + button with an “AND” button and an “OR” button. Conceptually this was a lot easier to understand and matched up closely with how people went about trying to build filters. In this iteration, operators would be fixed for each group, so inside a group, all parameters must be ANDed together or ORed together. This fixed edge cases when trying to build more complicated filters, but at the expense of a more complicated and potentially confusing UI.
A later prototype restricted ANDs to the root level, and ORs would be applied to groups. This restriction stopped some filters being able to be built, but improved the mental model of how the UI worked removing all the confusion we’d seen in our previous internal user tests.
After the bulk of the prototyped design was built, we tested with people outside the company to again gauge people’s understanding of the interface. You can share a few variants of the prototypes you’ve been working on and see if anything works better in one than another. If you’ve built your prototype to be easily modified, you’re also able to make quick changes and see how those perform. It’s important to remember though, that those changes should also then be tested with many other people; what works for one person might not make sense to everyone else.
After we were happy with the interaction design and confident that the metaphors used made sense, we finished up by tidying the visual design. This stage is all about making it fit in visually with everything that surrounds it, make it look polished and make sure the metaphors are visually communicated effectively. One of our challenges was communicating grouped sections effectively. The way you think about grouped sections in mathematics is to use brackets, so we decided to build on that idea. Every new parameter added is either added to an existing group, or its own group, and that’s indicated by a darker blue bubble.
Keep it simple
The new filtering interface in GoSquared has been available for our users for a few weeks now, and so far the feedback has been great.
We methodically followed a design process that used real examples from the start through to the end and explored as many ideas as possible, from as early as possible to ensure we didn’t become falsely attached to one single approach.
When building and testing prototypes, focus on the core user interaction first and visuals after. Good visual design highlights actionable areas in the design and is an important aspect in the design process, however is secondary to good user interaction and conveying a solid mental model of how the interface works.
This is just a brief look at process behind one of the many ways we focus on making complex tasks feel simple at GoSquared. If you have any thoughts on the design process or the final outcome, let me know in the comments below!