How I created custom highlighting for my app
Goodbye, blue toggles
Last week, I launched Leder, an iOS app that I’ve been designing and developing for the better part of a year. Leder is a highlighting and outlining tool that helps writers organize and edit text.
One of its main features is custom highlighting, designed make selecting text on your phone easier and more effective. Plainly speaking, I wanted to make highlighting super simple for users — no blue toggles necessary, akin to marking up print paper.
As all designers know, reaching “super simple” actually takes a ton of work behind the scenes. But for Leder, I knew it would be worth the effort. Text selection is a core part of my app, and getting the mechanic right could bring it from working to wonderful.
This post goes over how I designed and developed the highlighting mechanic for Leder. Hopefully it will give you some insight into my process (or better yet, try it for yourself).
Selecting text on my iPhone is one of my biggest pet peeves. I hate adjusting those tiny blue toggles, and having to start over because I accidentally tapped out of the selection.
Based on my experience, I had a hunch that native text selection could use some reworking, but I knew that I needed to conduct user interviews to validate this assumption.
I spoke with a dozen users about mobile highlighting, trying to determine whether or not it needed improvement, and how I could go about doing so.
I heard the same complaint across the board: selecting text on mobile devices is a frustrating, finicky process. It’s easy to make a mistake, and it’s not suitable for large amounts of text.
When dealing with anything longer than a few hundred words, users who outline told me that they resort to printing and highlighting content by hand, or copying and pasting selected text into a new document. Needless to say, there was room for improvement.
Next I examined the text selection mechanics on various tools, platforms, and apps. While some offered better functionality than others (the Amazon Kindle stood out as a favorite), most fell short of users’ ideal.
At this point, I had determined that there was a need for a better way of selecting text on mobile.
Over the next week or so, I conducted usability testing with 12 people to figure out just how to accomplish that. I showed users the screenshot below and gave them two tasks:
Select the text from “Hopefully” on line three through “Starbucks” on line seven.
Let’s say you overshot your selection to the word “been.” How would you adjust the selection?
Most users touched or tapped the first word, and then dragged their finger to the final word. They said they expected markers to appear on either side of the selection for adjustments — in line with the present mechanics offered on their device.
I then asked for their ideal way of selecting that text, whether it matched their device’s current mechanics or not. Everyone was quick to offer suggestions.
The top two contenders were:
- Tap first word, tap last word; selection in middle is highlighted.
- Long-press first word, then drag finger to last word; markers appear on either end of the selection to make adjustments.
I needed to figure out which highlighting process I should incorporate into the app moving forward, and I couldn’t rely on verbal suggestions alone. Tapping a static photo is much different than interacting with a functioning tool. In order to properly test these interactions and observe actual behavior, I knew I needed to develop working prototypes.
The results were overwhelmingly in favor of the first mechanic: “Tap first word, tap last word; selection in middle is highlighted.” Users found it to be easy, quick, and intuitive. With that, I felt that I had enough support to move forward.
DESIGN, DEVELOP, TEST, REPEAT
I continued to test and refine the mechanic over the next five months as I built out the rest of Leder. The insights from testing helped me make informed design decisions about aspects around highlighting like text size, placement, colors, and padding.
Here are some of the most significant design decisions:
Make the process as easy as possible.
I increased the font size and spacing, compared to the text in the rest of the app, to make it easier for users to select individual words. I also expanded the touch area of each word.
Finally, the text size is adjustable, so users can change it to their liking.
Originally, the yellow markup only appeared once the user finished highlighting a selection. That meant there was no initial feedback, and consequently users could not tell that they were in the process of highlighting.
So, I decided to apply a faint yellow highlight to the first word to indicate to users that they are successfully in the midst of highlighting. The full yellow highlight appears once users complete the selection.
Don’t disorient the user.
The reasoning behind this next decision is a perfect example of why designers should assess what people do, not just what they say. Early on, users said they would like to see the highlighted selections “bubble out” or “pop” on their device’s screen. Thus, in my original design, highlighted selections appeared larger than the rest of the text.
Later testing with working prototypes, though, showed that moving text is disorienting and distracting to users. In the final design, the size and position of the text is consistent regardless of highlighting.
Introduce non-standard mechanics.
Since Leder’s mechanic differs from native iOS highlighting, I knew that I needed to orient new users in some way. To do that, I created a thorough, immersive onboarding experience that explains the value of Leder’s highlighting, and then invites the user to actively participate in marking up a note.
THE FINAL DESIGN
Leder users can highlight text by touching the first and last words of a quote, bypassing the native long-press method of selecting text. Plus, Leder provides more than simply markup; it actually separates and extracts selections so you can work with them later. The mechanics are designed to be easy to learn, quick to do, and more in line with how users ideally prefer to highlight.
This concludes how I designed Leder’s highlighting mechanic. The rest of this post goes through how I actually coded it.
This next section is not meant to be a step-by-step walkthrough of the actual code, but rather a high-level overview of the basic premise.
I developed Leder in AngularJS and Ionic. Basically, the highlighting system consisted of three parts: display, highlight, and save.
Generally, the text you see on screen — whether it’s a sentence, paragraph, or even article — is displayed in a single HTML tag. For instance, take this line of text: “The quick brown fox jumps over the lazy dog.”
In HTML, it might look something like this:
In Leder, the HTML would look like this:
Before displaying the text to the user, Leder splits the text (stored as a string) into an array of substrings, where each substring contains the text of a single word. Leder displays each word in individual <span> elements. While this makes no visible difference to the user, separating each word into individual units makes it possible to distinctly interact with each one.
Each word is tied to a touch event. When the user touches a word, Leder launches into “highlight mode,” and turns on a CSS class that applies a yellow background to the word.
When the user touches a second word to close the quote, Leder — recognizing that it is still in “highlight mode” — loops through every word in the array of substrings. It applies the yellow-background CSS class to all words that occur after the first highlighted word and before the last highlighted word. Then the highlight mode is turned off to make room for another selection.
At this point, all of the highlighting that the user sees is merely markup done via CSS. The words in each quote may seem connected to the user, but they are actually unrelated, separate elements! In order to present them as complete quotes in the outline view, I needed to string them back together.
Once users finish highlighting all of their selections and hit save, Leder loops through the array of substrings once more.
Once the loop reaches a word with the yellow-background class, that word is pushed to a new array. The loop continues pushing words to that new array until it reaches a word without the yellow-background class. Then, all the previously pushed words are strung together and saved as a full, unobstructed string of text. The process is repeated until every word is accounted for.
Now, these lines of text can be viewed as full quotes in the outline view.