How to Build a Universal App
February 25, 2020
Frightening fact: Modern mobile apps have only been around for just over a decade. In 2008, we saw the introduction of Apple’s App Store and Google’s Play Store resulting in the birth of a new global industry: app development.
For the first few years, apps on these stores were built for the standard display size of a measly 320 x 480 pixels. However, after awhile phone screen sizes began varying in size and tablets entered the market. During this phase, phone app developers only had to make minor adjustments to handle the changes and tablet apps were considered an entirely different entity altogether. Then came high-resolution displays, phablets, mini phones, tablet split-screen multitasking, and folding phones.
Today the sheer variety of boxes that an app is expected to fit (and work well) in is astonishing. As the industry has evolved, app developers and designers have had to adapt how they think about and build apps. Tools and methodologies that were developed during the single-screen-size years have either had to evolve with developers or find themselves left behind.
As a result, it quickly became infeasible to expect design and development efforts to individually support these variations due to the cost of time, redundancy, and susceptibility to errors. Instead, app design and development focused on finding a singular approach. The theory of this is that if an interface can be defined generally, then the effort only needs to be done once, with the occasional opt-in exception where sensible/necessary.
This means that for designers and developers, there is a focus on ensuring that collaboration between the two practices results in a universal app. Which is why we—Hala, Senior Product Designer, and Reinier Lakhan, Senior Software Engineer—have teamed up to write a guide to making this collaboration work, focusing on designing and building responsively and the importance of communicating design intent.
Communicating Design Intent
If you’ve worked on building a product, you will know that keeping the team in sync during development is critical. Particularly speaking at the point of design handoff and implementation, between designer and developer. When translating design specs into code, there is usually room for interpretation from the developer in the way design requirements are communicated. Therefore, if there is any ambiguity, unexpected issues can appear in the interface when implemented, especially when tested on various mobile and tablet sizes.
When building a universal app, communicating design intent is important. To avoid redundancy and save time, annotating the designs to communicate the constraints and guidelines will come in handy. A lot of the time, it is the designer and engineer who verbally land on the logic for implementing a specific component. It’s a good rule of thumb to document it and keep it as a source of truth to reference back to, as well for the rest of the team to use (e.g. other developers, QA, and your PM).
Annotations can come in a variety of forms. At times, the tools you are using have a few built-in features to accomplish that—like the commenting feature on Zeplin. However, that’s sometimes not enough, mainly when your design vision is not as conventional. What you can do is create your own additional material to visually illustrate the logic behind implementing. You might be thinking that this is extra work, but it’s worth it as it streamlines communication. It is also useful for creating a template that can apply to many screens, especially when a chunk of the app’s screen inventory shares the same layout. This will take you a few steps closer to creating a universal app.
We’ll be touching on a few design examples and our approach for applying them to a variety of sizes. For each example, we’ll include the challenge we faced, the solution we arrived on, and the way it was communicated.
In this article, we’re going to show you how we built a beautifully designed tea reference app. Our goal was to build a single implementation responsively that considers the intent of the design. Let’s start with this page that shows a profile of a particular tea.
#1: Scaling with proportions
Our first design shows us exactly how the page is meant to look within its particular size. It is common that a design like this is shared in a tool such as Zeplin. These tools will typically give you the ability to see the size and placement of any object relative to another one, either in absolute measurements or in relation to one another. However when implementing these interfaces, developers are focused on determining the rules for constraining an object.
Given the ability to see an object’s relation to everything else in both relative and absolute terms, there is a lot of room for interpretation. Developers now have to choose which rule to use. Looking at our tea profile design, let’s make some assumptions on how it should be implemented. Of course these can be different from developer to developer, but that’s the problem, ambiguity can lead to incorrect assumptions.
Firstly, our title and description looks like it’s fixed to the top and left of the screen. Same for the image with the top and right of the screen. The buttons are centered and have a width we can fix to.
Now that we’ve implemented our tea profile page using our assumptions let’s see how this works on a different screen size, for example a tablet.
This doesn’t seem well optimized to use the space we now have. The text looks small and high up, same for the image. The space at the center seems wasted and our buttons look as if they are shrunk to the center of the screen.
We clearly need to capture more detail here, our assumptions have led us to an implementation that does not respond as expected on different screens. Here’s where communicating design intent becomes important.
So what can we do given our particular choice of tools to get this across? One approach we’ve used successfully has been annotations. Here’s where designers and developers should work together to determine these rules and capture them, in this case, in the form of design annotations.
Now this seems a lot clearer, we know that the text should be centered vertically in that space and that the image should also align with it that way. Also the four detail buttons should not be fixed, but have a proportional margin, and finally, the back button’s width is proportional to the screen’s width.
Let’s take a stab at revising our implementation given our disambiguated design. Since our rules are clear, transferring to logic should be a straightforward task.
This looks a lot better, our new rules captured how design intends to use and share the space provided. As a result, we get better layouts.
#2: Implementing a dynamic image
Keeping the subject of the image the center of attention
Sometimes, a simple layout and sizing proportion or fixed value isn’t enough to achieve what we really want. In these circumstances, it’s best to speak in terms of what we do and do not want, and then translate those into rules.
Let’s take a look at our implementation of the tea profile so far, we’d like to have more of the image shown if possible, but it should still play well with the other elements. We always want to show enough of the image so that the user can know what it looks like. This can become a rule such as show at least 54% of the image, maybe more but no less. We don’t want it growing behind our buttons which means we need to limit the height from the top of the screen to the top of the first button. We want the picture to start next to the text, so we need to pin those edges together.
Now this should mostly help but there is a nuance we’d like to capture for some extra UI goodness. On screens with relatively smaller widths, we want to give the text 60% of the screen, but on wider screens it’s okay if it shares it 50% with the image.
Here we can take advantage of size classes, also known as visual breakpoints. It’s a concept in web design, and more recently mobile, where the developer can add a variation based on a threshold of screen size. So if we’re on a compact screen, we use different rules than a regular screen or even a wide screen.
Now that we have our updated rules, let’s see how it looks.
#3: Implementing a list of cards
Avoid having a card hidden outside the screen canvas
Next in our tea companion app, we have a screen that shows us the list of teas that we’ve favorited so that we can get details on them.
This sort of UI is fairly simple to implement and typically works well on many display sizes out of the box. We also have clarity on how margins will work with the size classes, the ideal aspect ratio of the cells and how elements of the cell are going to work with each other thanks to our annotations. Now let’s go ahead and see how this looks on tablet.
Everything looks pretty good! However we’ve lost a little detail that we had for free on the phone-sized UI. Notice that the last card we can see is only partially visible, while on the tablet UI the last displayed card is completely visible. On the tablet UI we actually have more cards under the last visible one; however, we currently don’t have a way to prompt our user that there’s more to scroll to. On the phone the peeking card served as this hint, but was lost on the tablet UI. Let’s see if we can formulate a general set of rules that always let us have this effect.
We now have an approach to size our cards perfectly for every design. First, we see how the cards will work using the ideal aspect ratio. Then we see if the last visible card shows enough to be peeking, but not enough to seem as if it’s completely displayed—that is, the percentage displayed needs to be within the specified range. Finally, if we’re out of range, we solve for a new height that satisfies the proper height to be peaking in the direction that deviates the least from the ideal aspect ratio. Now that we have our peeking rules, let’s try it out.
Perfect! Our cards still use the space appropriately but now we’re also guaranteed to have a peeking card so that the user will be hinted that there’s more to scroll to.
We’ve made it! We’ve implemented a piece of a universal app. The two screens we walked you through can now adapt to a variety of screen sizes, tablet split-screen multitasking, and folding phones. Now that we’ve taken a universal approach for implementation, making a design change to one area will effortlessly propagate the updated UI across all platforms.
Next time you’re building an app, remember what we’ve outlined and make sure to have a chat with your team on how to arrive at the best universal approach. Collaborating together and sharing the designs before implementation will make sure you’re all on the same page. Now taking a step further, and clearly documenting the design intent and approach you all agreed on will streamline development and fill any room of ambiguity. Good luck!
Subscribe to Our Newsletter
Join the Thoughtworks newsletter list to receive curated content that exemplifies our Product thinking approach.
Thu Mar 2
Scenario Building for Future-Ready Retail
The retail industry has been evolving at an accelerated pace in recent years, largely due to the advent of digital technology and e-commerce. The rise of online shopping has changed the way consumers make purchases, and retailers have had to adapt to remain relevant. However, the pace of technological change is not slowing down, and the retail industry needs to take an active role in shaping its future.
Thu Feb 23
Desirability Across the Product Development Lifecycle
Truly successful products are revelled in as much as they are relied upon, sometimes making them feel like they're woven into the fabric of the user's life. But accomplishing this requires more than just building a product that people can use - it's about building a product that people WANT to use. If you're in the business of building things, you've probably asked yourself, "do people want or need what I'm building?" And this is a good question to ask - but desirability is more than just a box to be checked and forgotten.