emGee Software Solutions Custom Database Applications

Share this

Smashing Magazine

Recent content in Articles on Smashing Magazine — For Web Designers And Developers
Updated: 6 hours 32 min ago

Getting Started With Machine Learning

Fri, 09/07/2018 - 05:00
Getting Started With Machine Learning Getting Started With Machine Learning Alvin Wan 2018-09-07T14:00:26+02:00 2018-09-15T11:11:14+00:00

The goal of machine learning is to find patterns in data and use those patterns to make predictions. It can also give us a framework to discuss machine learning problems and solutions — as you’ll see in this article.

First, we will start with definitions and applications for machine learning. Then, we will discuss abstractions in machine learning and use that to frame our discussion: data, models, optimization models, and optimization algorithms. Later on in the article, we will discuss fundamental topics that underlie all machine learning methods and conclude with practical guidance for getting started with using machine learning. By the end, you should have an understanding of how to advance your practice and study of machine learning.

Let’s begin.

So, What Exactly Is Machine Learning?

Machine learning is generically a set of techniques to find patterns in data. Applications range from self-driving cars to personal AI assistants, from translating between French and Taiwanese to translating between voice and text. There are a few common applications of machine learning that already or could potentially permeate your day-to-day.

  1. Detecting anomalies
    Recognize spikes in website traffic or highlight abnormal bank activity.
  2. Recommend similar content
    Find products you may be looking for or even Smashing Magazine articles that are relevant.
  3. Predict the future
    Plan the path of neighboring vehicles or identify and extrapolate market trends for stocks.

The above are few of many applications of machine learning, but most applications tie back to learning the underlying distribution of data. A distribution specifies events and probability of each event. For example:

  • With 50% probability, you buy an item $5 or less.
  • With 25% probability, you buy an item $5-$10.
  • With 24% probability, you buy an item $10-100.
  • With 1% probability, you buy an item > $100.

Designing static pages has become untenable, so many of us started to approach design in a more systematic way. In her new book, Alla Kholmatova explors how to create effective, maintainable design systems to create great digital products. Meet Design Systems, with common traps, gotchas and the lessons Alla has learned.

Table of Contents →

Using this distribution, we can accomplish all of our tasks above:

  1. Detecting anomalies
    With a $100 purchase, we can confidently call this an anomaly.
  2. Recommend similar content
    A purchase of $3 means we should recommend more items $5 or less.
  3. Predict the future
    Without any prior information, we can predict that the next purchase will be $5 or less.

With a distribution of data, we can accomplish a myriad of tasks. In sum, one goal in machine learning is to learn this distribution.

Even more generically, our goal is to learn a specific function with particular inputs and outputs. We call this function our model. Our input is denoted x. Say our model, which accepts input x, is

f(x) = ax

Here, a is a parameter of our model. Each parameter corresponds to a different instance of our model. In other words, the model where a=2 is different from the model where a=3. In machine learning, our goal is to learn this parameter, changing it until we do “well.” How do we determine which values of a do “well”?

We need to define a way to evaluate our model, for each parameter a. To start, the output of f(x) is our prediction. We will refer to y as our label, meaning the true and desired output. With our predictions and our labels, we can define a loss function. One such loss function is simply the difference between our prediction and our label, |f(x) - y|. Using this loss function, we can then evaluate different parameters for our model. Picking the best parameter for our model is known as training. If we have a few possible parameters, we can simply try each parameter and pick the one with the smallest loss!

However, most problems are not as simple. What happens if there are an infinite number of different parameters? Let’s say all decimal values between 0 and 1? Between 0 and infinity? This brings us to our next topic: abstractions in machine learning. We will discuss different facets of machine learning, to compartmentalize your knowledge into data, models, objectives, and methods of solving objectives. Beyond learning the right parameter, there are plenty of other challenges: how do we break down a problem as complex as controlling a robot? How do we control a self-driving car? What does it mean to train a model that identifies faces? The section below will help you organize answers to these questions.

Abstractions

There are countless topics in machine learning — at various levels of specificity. To better understand where each piece fits in the larger picture, consider the following abstractions for machine learning. These abstractions compartmentalize our discussion of machine learning topics, and knowing them will make it easier for you to frame topics. The following classifications are taken from Professor Jonathan Shewchuck at UC Berkeley:

  1. Application and Data
    Consider the possible inputs and the desired output for the problem.
    Questions: What is your goal? How is your data structured? Are there labels? Is it reasonable for us to extract output from the provided inputs?

    Example: The goal is to classify pictures of handwritten digits. The input is an image of a handwritten number. The output is a number.
  2. Model
    Determine the class of functions under consideration.
    Questions: Are linear functions sufficient? Quadratic functions? Polynomials? What types of patterns are we interested in? Are neural networks appropriate? Logistic regression?

    Example: Linear regression
  3. Optimization Problem
    Formulate a concrete objective in mathematics.
    Questions: How do we define loss? How do we define success? Should we apply additionally penalties to bias our algorithm? Are there imbalances in the data our objective needs to consider?

    Example: Find `x` that minimizes |Ax-b|^2
  4. Optimization Algorithm
    Determine how you will solve the optimization problem.
    Questions: Can we compute a solution by hand? Do we need an iterative algorithm? Can we convert this problem to an equivalent but easier-to-solve objective, and solve that one?

    Example: Take derivative of the function. Set it to zero. Solve for our optimal parameter.
Abstraction 1: Data

In practice, collecting, managing, and packaging data is 90% of the battle. The data contains samples in which each sample is a specific realization of our input. For example, our input may generically be images of dogs. The first sample is specifically a picture of Maxie, my Bernese Mountain dog-chow chow mix at home. The second sample is specifically a picture of Charlie, a young corgi.

While training your model, it is important to handle your data properly. This means separating our data accordingly and not peeking prematurely at any set of data. In general, our data is split into three portions:

  1. Training set
    This is the dataset you train your model on. The model may see this set hundreds of times.
  2. Validation set
    This is the dataset you evaluate your model on, to assess accuracy and tune your model or method accordingly.
  3. Test set
    This is the dataset you evaluate on to assess accuracy, once at the very end. Running on the test set prematurely could mean your model overfits to the test set as well, so run only once. We will discuss the notion of “overfitting” in more detail below.
Abstraction 2: Models

Machine learning methods are split into the following two:

Supervised Learning

In supervised learning, our algorithm has access to labeled data. Still, we explore the following two classes of problems:

  • Classification
    Determine which of k classes {C_1, C_2, ... C_k} to which each sample belongs, e.g. “Which breed of dog is this?” The dog could be one of {"corgi", "bernese mountain dog", "chow chow"...}
  • Regression
    Determine a real-valued output (which are often probabilities), e.g. “What is the probability this patient has neuroblastoma (eye cancer)?”
Unsupervised Learning

In unsupervised learning, our algorithm does not have access to labels, and we explore the following classes of problems:

  • Clustering
    Cluster samples into k clusters. We do not have a label for the resulting clusters. “Which DNA sequences are most similar?”
  • Dimensionality reduction
    Reduce the number of “unique” (linearly independent) features we consider. “What are common features of faces?”
Abstraction 3: Optimization Objective

Before discussing optimization objectives and algorithms, we’ll need an example to discuss. Least squares are the canonical example. We will restrict our attention to a specific form of least squares: Let us return to our grade-school problem of fitting a line to some points.

Let’s recall the equation of a line:

y = m * x + b

Assume we have such a line. This is the true underlying model.

True model. The line that generates our data. (Large preview)

Now, sample points from this line.

True data. Data that is sampled from the true model. (Large preview)

For each point, jiggle it a little bit. In other words, add noise, which is random perturbations. This noise is due to real-world processes.

Noise. Real-world perturbations that affect our data. This may be due to imprecision in measurements, lossy compression, and so on. (Large preview)

This gives us our observed data. We will call these points (x_1, y_1), (x_2, y_2), (x_3, y_3).... This is the training data we are given to train a model on. We do not have access to the underlying line that generated this data (the original green line).

Observations. Our true data with noise and ultimately what we will use to train a model. (Large preview)

Say we have an estimate for the parameters of a line. In this case, the parameters are m and b. This gives us a predicted line, drawn in blue below.

Proposed model. The result of training a model on our observations. (Large preview)

We wish to evaluate our blue line, to see how accurate it is. To start, we use m and b to estimate y. We compute a set of ŷ values.

ŷ_i = m * x_i + b

The error for a single predicted ŷ_i and true y_i is simply

(ŷ_i−y_i)^2

Our total error is then the sum of squared differences, across all samples. This yields our loss.

∑(ŷ_i−y_i)^2

Presented visually, this is the vertical distance between our observed points and our predicted line.

Observed error. The distance between our observed data and our proposed model. (Large preview)

Plugging in ŷ_i from above, we then have the total error in terms of m and b.

∑(m * x_i + b − y_i)^2

Finally, we want to minimize this quantity. This yields our objective function, abstraction 3 from our list of abstractions above.

min_{m, b} ∑(m * x_i + b−y_i)^2

The above states in mathematics that the goal is to minimize the loss by changing values of m and b. The purpose of this section was to motivate fitting a line of best of fit, a special case of least squares. Additionally, we showed examined the least squares objective. Next, we need to solve this objective.

Abstraction 4: Optimization Algorithm

How do we minimize this? We take the derivative with respect to m`, set to 0 and solve. After solving, we obtain the analytical solution. Solving for an analytical solution was our optimization algorithm, the fourth and final abstraction in our list of abstractions.

Note: The important portion of this section is to inform you that least squares have a closed form solution, meaning that the optimal solution for our problem can be computed, explicitly. To understand why this is significant, we need to examine a problem without a closed-form solution. For example, we could never solve x=logx for a standard base-10 logarithm. Try graphing these two lines, and we see that they never intersect. In which case, we have no closed-form solution. On the other hand, ordinary least squares have a closed-form — which is good news. For any problem reduced to least squares, we can then compute the optimal solution, given our data and assumptions.

Fundamental Topics

Before studying more methods, it is necessary to understand the undercurrents of machine learning. These will govern the initial study of machine learning:

Bias-Variance Tradeoffs

One of machine learning’s most dreaded evils is overfitting in which a model is too closely tailored to the training data. In the limit, the most overfit model will memorize the data. This might mean that if one does well on exam A, one repeats every detail for exam B — down to the duration of an inter-exam restroom trip and whether or not one used the urinal.

A related but less common evil is underfitting, where the model is not sufficiently expressive to capture important information in the data. This could mean that one looks only at homework scores to predict exam scores, ignoring the effects of reading notes, completing practice exams, and more. Our goal is to build a model that generalizes to new examples while making the appropriate distinctions.

Given these two evils, there are a variety of approaches to fighting both. One is modifying your optimization objective to include a term that penalizes model complexity. Another is tuning hyperparameters that govern either your objective or your algorithm, which may correspond to notions such as “training speed” or “momentum.” The bias-variance tradeoff gives us a precise way of defining and handling both overfitting and underfitting.

Maximum Likelihood Estimation (MLE) + Maximum A Posteriori (MAP)

Say we have ice cream flavors A, B, and C. We observe different recipes. Our goal is to predict which flavor each recipe produces.

One way to predict flavors based on recipes is to first estimate the following probability:

P(flavor|recipe)

Given this probability and a new recipe, how can we predict the flavor? Given a recipe, simply consider the probability of each of the flavors A, B, C.

P(flavor=A|recipe) = 0.4 P(flavor=B|recipe) = 0.5 P(flavor=C|recipe) = 0.1

Then, pick the flavor that has the highest probability. Above, flavor B has the highest probability, given our recipe. Thus, we predict flavor B. Restating the above rule in mathematics, we have:

argmax_{flavor} P(flavor|recipe) # argmax means take the flavor that corresponds to the max value

However, the only information at our disposal is the reverse: the probability of some recipe given the flavor.

P(recipe|flavor)

For Maximum Likelihood Estimates, we make assumptions and find that the two values are proportional.

P(recipe|flavor) ~ P(flavor|recipe)

Since we’re only interested in the class with maximum probability P(flavor|recipe), we can simply find the class with maximum probability, for a proportional value P(recipe|flavor).

argmax_{flavor} P(recipe|flavor)

MLE offers the above objective as one way to predict, using the probability of data given the labels.

However, allow me to convince you that it’s reasonable to assume we have (x|y). We can estimate this from observed, real-world data. For example, say we wish to estimate the number of marbles each student in your class carries, based on the number of rubber ducks the student carries.

Each student’s number of rubber ducks is the data x, and the number of marbles she or he has is y. We will use this sample data below.

| x | y | |---|---| | 1 | 2 | | 1 | 1 | | 1 | 2 | | 2 | 1 | | 2 | 2 | | 1 | 2 |

For every y, we can compute the number of x, given us P(x|y). For the first one, P(x=1|y=1), consider all of the rows where y=1. There are 2, and only one of them has x=1. Therefore, P(x=1|y=1) = 1⁄2. We can repeat this for all values of x and y.

P(x=1|y=1) = 1/2 P(x=2|y=1) = 1/2 P(x=1|y=2) = 3/4 P(x=2|y=2) = 1/4 Featurizations, Regularization

Least squares draw lines of best fit for us. Note that least squares can fit the model anytime the model is linear in its inputs x and outputs y.

Say m=1. We have the following equation:

y = x + b

However, what if we had data that doesn’t generally follow a line? Specifically, consider a set of data sampled along a circle. Recall that the equation for a circle is:

x^2 + y^2 = r^2

Can least squares fit this well? As it stands, no. The model is not linear in its inputs x and outputs y. Instead, the model above is quadratic in x and y. However, it turns out that we can use still use least squares, just with a modification. To accomplish this, we featurize our samples.

Consider the following: what if the input to our model was x_ = x^2 and y_ = y^2? Then, our model is trying to learn the following model.

x_ + y_ = r^2

Is this linear in the model’s input x_ and output y_? Yes. Note the subtlety. The current model is still quadratic in x,y but it is linear in x_,y_. This means that least squares can fit the data if we square x^2 and y^2 before training least squares.

More generally, we can take any non-linear featurization to apply least squares to labels that are non-linear in the features. This is a fairly powerful tool, known as featurization.

However, featurizations lead to more complex models. Regularization allows us to penalize model complexity, ensuring that we do not overfit the training data.

Conclusion

In this article, you’ve touched on major topics in the fundamentals of machine learning. Using the abstractions above, you now have a framework to discuss machine learning problems and solutions. Using the fundamental topics above, you now also have quintessential concepts to learn more about, giving you the necessary tools to evaluate risk and other concerns in a machine learning application.

Further Reading

We will continue to explore these topics in depth, both the undercurrents of machine learning and specific methods. In the interim, here are resources to further your study and exploration of machine learning:

(ra, il)
Categories: Web Design

Designing A Textbox, Unabridged

Thu, 09/06/2018 - 04:30
Designing A Textbox, Unabridged Designing A Textbox, Unabridged Shane Hudson 2018-09-06T13:30:16+02:00 2018-09-15T11:11:14+00:00

Ever spent an hour (or even a day) working on something just to throw the whole lot away and redo it in five minutes? That isn’t just a beginner’s code mistake; it is a real-world situation that you can easily find yourself in especially if the problem you’re trying to solve isn’t well understood to begin with.

This is why I’m such a big proponent of upfront design, user research, and creating often multiple prototypes — also known as the old adage of “You don’t know what you don’t know.” At the same time, it is very easy to look at something someone else has made, which may have taken them quite a lot of time, and think it is extremely easy because you have the benefit of hindsight by seeing a finished product.

This idea that simple is easy was summed up nicely by Jen Simmons while speaking about CSS Grid and Piet Mondrian’s paintings:

“I feel like these paintings, you know, if you look at them with the sense of like ‘Why’s that important? I could have done that.’ It's like, well yeah, you could paint that today because we’re so used to this kind of thinking, but would you have painted this when everything around you was Victorian — when everything around you was this other style?”

I feel this sums up the feeling I have about seeing websites and design systems that make complete sense; it’s almost as if the fact they make sense means they were easy to make. Of course, it is usually the opposite; writing the code is the simple bit, but it’s the thinking and process that goes into it that takes the most effort.

With that in mind, I’m going to explore building a text box, in an exaggeration of situations many of us often find ourselves in. Hopefully, by the end of this article, we can all feel more emphatic to how the journey from start to finish is rarely linear.

A Comprehensive Guide To User Testing

So you think you’ve designed something that’s perfect, but your test tells you otherwise. Let’s explore the importance of user testing. Read more →

Getting workflow just right ain’t an easy task. So are proper estimates. Or alignment among different departments. That’s why we’ve set up “this-is-how-I-work”-sessions — with smart cookies sharing what works well for them. A part of the Smashing Membership, of course.

Explore features → Brief

We all know that careful planning and understanding of the user need is important to a successful project of any size. We also all know that all too often we feel to need to rush to quickly design and develop new features. That can often mean our common sense and best practices are forgotten as we slog away to quickly get onto the next task on the everlasting to-do list. Rinse and repeat.

Today our task is to build a text box. Simple enough, it needs to allow a user to type in some text. In fact, it is so simple that we leave the task to last because there is so much other important stuff to do. Then, just before we pack up to go home, we smirk and write:

<input type="text">

There we go!

Oh wait, we probably need to hook that up to send data to the backend when the form is submitted, like so:

<input type="text" name="our_textbox">

That’s better. Done. Time to go home.

How Do You Add A New Line?

The issue with using a simple text box is it is pretty useless if you want to type a lot of text. For a name or title it works fine, but quite often a user will type more text than you expect. Trust me when I say if you leave a textbox for long enough without strict validation, someone will paste the entire of War and Peace. In many cases, this can be prevented by having a maximum amount of characters.

In this situation though, we have found out that our laziness (or bad prioritization) of leaving it to the last minute meant we didn’t consider the real requirements. We just wanted to do another task on that everlasting to-do list and get home. This text box needs to be reusable; examples of its usage include as a content entry box, a Twitter-style note box, and a user feedback box. In all of those cases, the user is likely to type a lot of text, and a basic text box would just scroll sideways. Sometimes that may be okay, but generally, that’s an awful experience.

Thankfully for us, that simple mistake doesn’t take long to fix:

<textarea name="our_textbox"></textarea>

Now, let’s take a moment to consider that line. A <textarea>: as simple as it can get without removing the name. Isn’t it interesting, or is it just my pedantic mind that we need to use a completely different element to add a new line? It isn’t a type of input, or an attribute used to add multi-line to an input. Also, the <textarea> element is not self-closing but an input is? Strange.

This “moment to consider” sent me time traveling back to October 1993, trawling through the depths of the www-talk mailing list. There was clearly much discussion about the future of the web and what “HTML+” should contain. This was 1993 and they were discussing ideas such as <input type="range"> which wasn’t available until HTML5, and Jim Davis said:

“Well, it's far-fetched I suppose, but you might use HTML forms as part of a game playing interface.”

This really does show that the web wasn’t just intended to be about documents as is widely believed. Marc Andreessen suggested to have <input type="textarea"> instead of allowing new lines in the single-line text type, [saying]: (http://1997.webhistory.org/www.lists/www-talk.1993q4/0200.html)

“Makes the browser code cleaner — they have to be handled differently internally.”

That’s a fair reason to have <textarea> separate to text, but that’s still not what we ended up with. So why is <textarea> its own element?

I didn’t find any decision in the mailing list archives, but by the following month, the HTML+ Discussion Document had the <textarea> element and a note saying:

“In the initial design for forms, multi-line text fields were supported by the INPUT element with TYPE=TEXT. Unfortunately, this causes problems for fields with long text values as SGML limits the length of attributea literals. The HTML+ DTD allows for up to 1024 characters (the SGML default is only 240 characters!)”

Ah, so that’s why the text goes within the element and cannot be self-closing; they were not able to use an attribute for long text. In 1994, the <textarea> element was included, along with many others from HTML+ such as <option> in the HTML 2 spec.

Okay, that’s enough. I could easily explore the archives further but back to the task.

Styling A <textarea>

So we’ve got a default <textarea>. If you rarely use them or haven’t seen the browser defaults in a long time, then you may be surprised. A <textarea> (made almost purely for multi-line text) looks very similar to a normal text input except most browser defaults style the border darker, the box slightly larger, and there are lines in the bottom right. Those lines are the resize handle; they aren’t actually part of the spec so browsers all handle (pun absolutely intended) it in their own way. That generally means that the resize handle cannot be restyled, though you can disable resizing by setting resize: none to the <textarea>. It is possible to create a custom handle or use browser specific pseudo elements such as ::-webkit-resizer.

A default textarea with no styling (Large preview)

It’s important to understand the defaults, especially because of the resizing ability. It’s a very unique behavior; the user is able to drag to change the size of the element by default. If you don’t override the minimum and maximum sizes then the size could be as small as 9px × 9px (when I checked Chrome) or as large as they have patience to drag it. That’s something that could cause mayhem with the rest of the site’s layout if it’s not considered. Imagine a grid where <textarea> is in one column and a blue box is in another; the size of the blue box is purely decided by the size of the <textarea>.

Other than that, we can approach styling a <textarea> much the same as any other input. Want to change the grey around the edge into thick green dashes? Sure here you go: border: 5px dashed green;. Want to restyle the focus in which a lot of browsers have a slightly blurred box shadow? Change the outline — responsibly though, you know, that’s important for accessibility. You can even add a background image to your <textarea> if that interests you (I can think of a few ideas that would have been popular when skeuomorphic design was more celebrated).

Scope Creep

We’ve all experienced scope creep in our work, whether it is a client that doesn’t think the final version matches their idea or you just try to squeeze in a tiny tweak and end up taking forever to finish it. So I ( enjoying creating the persona of an exaggerated project manager telling us what we need to build) have decided that our <textarea> just is not good enough. Yes, it is now multi-line, and that’s great, and yes it even ‘pops’ a bit more with its new styling. Yet, it just doesn’t fit the very vague user need that I’ve pretty much just thought of now after we thought we were almost done.

What happens if the user puts in thousands of words? Or drags the resize handle so far it breaks the layout? It needs to be reusable, as we have already mentioned, but in some of the situations (such as a ‘Twittereqsue’ note taking box), we will need a limit. So the next task is to add a character limit. The user needs to be able to see how many characters they have left.

In the same way we started with <input> instead of <textarea>, it is very easy to think that adding the maxlength attribute would solve our issue. That is one way to limit the amount of characters the user types, it uses the browser’s built-in validation, but it is not able to display how many characters are left.

We started with the HTML, then added the CSS, now it is time for some JavaScript. As we’ve seen, charging along like a bull in a china shop without stopping to consider the right approaches can really slow us down in the long run. Especially in situations where there is a large refactor required to change it. So let’s think about this counter; it needs to update as the user types, so we need to trigger an event when the user types. It then needs to check if the amount of text is already at the maximum length.

So which event handler should we choose?

  • change
    Intuitively, it may make sense to choose the change event. It works on <textarea> and does what it says on the tin. Except, it only triggers when the element loses focus so it wouldn’t update while typing.
  • keypress
    The keypress event is triggered when typing any character, which is a good start. But it does not trigger when characters are deleted, so the counter wouldn’t update after pressing backspace. It also doesn’t trigger after a copy/paste.
  • keyup
    This one gets quite close, it is triggered whenever a key has been pressed (including the backspace button). So it does trigger when deleting characters, but still not after a copy/paste.
  • input
    This is the one we want. This triggers whenever a character is added, deleted or pasted.

This is another good example of how using our intuition just isn’t enough sometimes. There are so many quirks (especially in JavaScript!) that are all important to consider before getting started. So the code to add a counter that updates needs to update a counter (which we’ve done with a span that has a class called counter) by adding an input event handler to the <textarea>. The maximum amount of characters is set in a variable called maxLength and added to the HTML, so if the value is changed it is changed in only one place.

var textEl = document.querySelector('textarea') var counterEl = document.querySelector('.counter') var maxLength = 200 textEl.setAttribute('maxlength', maxLength) textEl.addEventListener('input', (val) => { var count = textEl.value.length counterEl.innerHTML = ${count}/${maxLength} }) Browser Compatibility And Progressive Enhancement

Progressive enhancement is a mindset in which we understand that we have no control over what the user exactly sees on their screen, and instead, we try to guide the browser. Responsive Web Design is a good example, where we build a website that adjusts to suit the content on the particular size viewport without manually setting what each size would look like. It means that on the one hand, we strongly care that a website works across all browsers and devices, but on the other hand, we don’t care that they look exactly the same.

Currently, we are missing a trick. We haven’t set a sensible default for the counter. The default is currently “0/200” if 200 were the maximum length; this kind of makes sense but has two downsides. The first, it doesn’t really make sense at first glance. You need to start typing before it is obvious the 0 updates as you type. The other downside is that the 0 updates as you type, meaning if the JavaScript event doesn’t trigger properly (maybe the script did not download correctly or uses JavaScript that an old browser doesn’t support such as the double arrow in the code above) then it won’t do anything. A better way would be to think carefully beforehand. How would we go about making it useful when it is both working and when it isn’t?

In this case, we could make the default text be “200 character limit.” This would mean that without any JavaScript at all, the user would always see the character limit but it just wouldn’t feedback about how close they are to the limit. However, when the JavaScript is working, it would update as they type and could say “200 characters remaining” instead. It is a very subtle change but means that although two users could get different experiences, neither are getting an experience that feels broken.

Another default that we could set is the maxlength on the element itself rather than afterwards with JavaScript. Without doing this, the baseline version (the one without JS) would be able to type past the limit.

User Testing

It’s all very well testing on various browsers and thinking about the various permutations of how devices could serve the website in a different way, but are users able to use it?

Generally speaking, no. I’m consistently shocked by user testing; people never use a site how you expect them to. This means that user testing is crucial.

It’s quite hard to simulate a user test session in an article, so for the purposes of this article, I’m going to just focus on one point that I’ve seen users struggle with on various projects.

The user is happily writing away, gets to 0 characters remaining, and then gets stuck. They forget what they were writing, or they don’t notice that it had stopped typing.

This happens because there is nothing telling the user that something has changed; if they are typing away without paying much attention, then they can hit the maximum length without noticing. This is a frustrating experience.

One way to solve this issue is to allow overtyping, so the maximum length still counts for it to be valid when submitted but it allows the user to type as much as they want and then edit it before submission. This is a good solution as it gives the control back to the user.

Okay, so how do we implement overtyping? Instead of jumping into the code, let’s step through in theory. maxlength doesn’t allow overtyping, it just stops allowing input once it hits the limit. So we need to remove maxlength and write a JS equivalent. We can use the input event handler as we did before, as we know that works on paste, etc. So in that event, the handler would check if the user has typed more than the limit, and if so, the counter text could change to say “10 characters too many.” The baseline version (without the JS) would no longer have a limit at all, so a useful middle ground could be to add the maxlength to the element in the HTML and remove the attribute using JavaScript.

That way, the user would see that they are over the limit without being cut off while typing. There would still need to be validation to make sure it isn’t submitted, but that is worth the extra small bit of work to make the user experience far better.

Allowing the user to overtype (Large preview) Designing The Overtype

This gets us to quite a solid position: the user is now able to use any device and get a decent experience. If they type too much it is not going to cut them off; instead, it will just allow it and encourage them to edit it down.

There’s a variety of ways this could be designed differently, so let’s look at how Twitter handles it:

Twitter's <textarea> (Large preview)

Twitter has been iterating its main tweet <textarea> since they started the company. The current version uses a lot of techniques that we could consider using.

As you type on Twitter, there is a circle that completes once you get to the character limit of 280. Interestingly, it doesn’t say how many characters are available until you are 20 characters away from the limit. At that point, the incomplete circle turns orange. Once you have 0 characters remaining, it turns red. After the 0 characters, the countdown goes negative; it doesn’t appear to have a limit on how far you can overtype (I tried as far as 4,000 characters remaining) but the tweet button is disabled while overtyping.

So this works the same way as our <textarea> does, with the main difference being the characters represented by a circle that updates and shows the number of characters remaining after 260 characters. We could implement this by removing the text and replacing it with an SVG circle.

The other thing that Twitter does is add a red background behind the overtyped text. This makes it completely obvious that the user is going to need to edit or remove some of the text to publish the tweet. It is a really nice part of the design. So how would we implement that? We would start again from the beginning.

You remember the part where we realized that a basic input text box would not give us multiline? And that a maxlength attribute would not give us the ability to overtype? This is one of those cases. As far as I know, there is nothing in CSS that gives us the ability to style parts of the text inside a <textarea>. This is the point where some people would suggest web components, as what we would need is a pretend <textarea>. We would need some kind of element — probably a div — with contenteditable on it and in JS we would need to wrap the overtyped text in a span that is styled with CSS.

What would the baseline non-JS version look like then? Well, it wouldn’t work at all because while contenteditable will work without JS, we would have no way to actually do anything with it. So we would need to have a <textarea> by default and remove that if JS is available. We would also need to do a lot of accessibility testing because while we can trust a <textarea> to be accessible relying on browser features is a much safer bet than building your own components. How does Twitter handle it? You may have seen it; if you are on a train and your JavaScript doesn’t load while going into a tunnel then you get chucked into a decade-old legacy version of Twitter where there is no character limit at all.

What happens then if you tweet over the character limit? Twitter reloads the page with an error message saying “Your Tweet was over the character limit. You’ll have to be more clever.” No, Twitter. You need to be more clever.

Retro

The only way to conclude this dramatization is a retrospective. What went well? What did we learn? What would we do differently next time or what would we change completely?

We started very simple with a basic textbox; in some ways, this is good because it can be all too easy to overcomplicate things from the beginning and an MVP approach is good. However, as time went on, we realized how important it is to have some critical thinking and to consider what we are doing. We should have known a basic textbox wouldn’t be enough and that a way of setting a maximum length would be useful. It is even possible that if we have conducted or sat in on user research sessions in the past that we could have anticipated the need to allow overtyping. As for the browser compatibility and user experiences across devices, considering progressive enhancement from the beginning would have caught most of those potential issues.

So one change we could make is to be much more proactive about the thinking process instead of jumping straight into the task, thinking that the code is easy when actually the code is the least important part.

On a similar vein to that, we had the “scope creep” of maxlength, and while we could possibly have anticipated that, we would rather not have any scope creep at all. So everybody involved from the beginning would be very useful, as a diverse multidisciplinary approach to even small tasks like this can seriously reduce the time it takes to figure out and fix all the unexpected tweaks.

Back To The Real World

Okay, so I can get quite deep into this made-up project, but I think it demonstrates well how complicated the most seemingly simple tasks can be. Being user-focussed, having a progressive enhancement mindset, and thinking things through from the beginning can have a real impact on both the speed and quality of delivery. And I didn’t even mention testing!

I went into some detail about the history of the <textarea> and which event listeners to use, some of this can seem overkill, but I find it fascinating to gain a real understanding of the subtleties of the web, and it can often help demystify issues we will face in the future.

(ra, il)
Categories: Web Design

Preparing Your App For iOS 12 Notifications

Wed, 09/05/2018 - 04:30
Preparing Your App For iOS 12 Notifications Preparing Your App For iOS 12 Notifications Kaya Thomas 2018-09-05T13:30:35+02:00 2018-09-15T11:11:14+00:00

In 2016, Apple announced a new extension that will allow developers to better customize their push and local notifications called the UNNotificationContentExtension. The extension gets triggered when a user long presses or 3D touches on a notification whenever it is delivered to the phone or from the lock/home screen. In the content extension, developers can use a view controller to structure the UI of their notification, but there was no user interaction enabled within the view controller — until now. With the release of iOS 12 and XCode 10, the view controller in the content extension now enables user interaction which means notifications will become even more powerful and customizable.

At WWDC 2018, Apple also announced several changes to notification settings and how they appear on the home screen. In an effort to make users more aware of how they are using apps and allowing more user control of their app usage, there is a new notification setting called “Deliver Quietly.” Users can set your app to Delivery Quietly from the Notification Center, which means they will not receive banners or sound notifications from your app, but they will appear in the Notification Center. Apple using an in-house algorithm, which presumably tracks often you interact with notifications, will also ask users if they still want to receive notifications from particular apps and encourage you to turn on Deliver Quietly or turn them off completely.

Notifications are getting a big refresh in iOS 12, and I’ve only scratched the surface. In the rest of this article, we’ll go over the rest of the new notification features coming to iOS 12 and how you can implement them in your own app.

Recommended reading: WWDC 2018 Diary Of An iOS Developer

Remote vs Local Notifications

There are two ways to send push notifications to a device: remotely or locally. To send notifications remotely, you need a server that can send JSON payloads to Apple’s Push Notification Service. Along with a payload, you also need to send the device token and any other authentication certificate or tokens that verify your server is allowed to send the push notification through Apple. For this article, we focus on local notifications which do not need a separate server. Local notifications are requested and sent through the UNUserNotificationCenter. We’ll go over later how specifically to make the request for a local notification.

In order to send a notification, you first need to get permission from the user on whether or not they want you to send them notifications. With the release of iOS 12, there are a lot of changes to notification settings and permissions so let’s break it down. To test out any of the code yourself, make sure you have the Xcode 10 beta installed.

Getting the process just right ain't an easy task. That's why we've set up 'this-is-how-I-work'-sessions — with smart cookies sharing what works really well for them. A part of the Smashing Membership, of course.

Explore features → Notification Settings And Permissions Deliver Quietly

Delivery Quietly is Apple’s attempt to allow users more control over the noise they may receive from notifications. Instead of going into the settings app and looking for the app whose notification settings you want to change, you can now change the setting directly from the notification. This means that a lot more users may turn off notifications for your app or just delivery them quietly which means the app will get badged and notifications only show up in the Notification Center. If your app has its own custom notification settings, Apple is allowing you to link directly to that screen from the settings management view pictured below.

Delivery quietly feature. (Large preview)

In order to link to your custom notification setting screen, you must set providesAppNotificationSettings as a UNAuthorizationOption when you are requesting notification permissions in the app delegate.

In didFinishLaunchingWithOptions, add the following code:

UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound, .providesAppNotificationSettings]) { ... }

When you do this, you’ll now see your custom notification settings in two places:

  • If the user selects Turn Off when they go to manage settings directly from the notification;
  • In the notification settings within the system’s Settings app.
Deep link to to custom notification settings for NotificationTester from notification in the Notification Center. (Large preview) Deep link to custom notification settings for NotificationTester from system’s Settings app. (Large preview)

You also have to make sure to handle the callback for when the user selects on either way to get to your notification settings. Your app delegate or an extension of your app delegate has to conform to the protocol UNUserNotificationCenterDelegate so you can then implement the following callback method:

func userNotificationCenter(_ center: UNUserNotificationCenter, openSettingsFor notification: UNNotification?) { let navController = self.window?.rootViewController as! UINavigationController let notificationSettingsVC = NotificationSettingsViewController() navController.pushViewController(notificationSettingsVC, animated: true) }

Another new UNAuthorizationOption is provisional authorization. If you don’t mind your notifications being delivered quietly, you can set add .provisional to your authorization options as shown below. This means that you don’t have to prompt the user to allow notifications — the notifications will still show up in the Notification Center.

UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .provisional]) { ... }

So now that you’ve determined how to request permission from the user to deliver notifications and how to navigate users to your own customized settings view, let’s go more into more detail about the actual notifications.

Sending Grouped Notifications

Before we get into the customization of the UI of a notification, let’s go over how to make the request for a local notification. First, you have to register any UNNotificationCategory, which are like templates for the notifications you want to send. Any notification set to a particular category will inherit any actions or options that were registered with that category. After you’ve requested permission to send notifications in didFinishLaunchingWithOptions, you can register your categories in the same method.

let hiddenPreviewsPlaceholder = "%u new podcast episodes available" let summaryFormat = "%u more episodes of %@" let podcastCategory = UNNotificationCategory(identifier: "podcast", actions: [], intentIdentifiers: [], hiddenPreviewsBodyPlaceholder: hiddenPreviewsPlaceholder, categorySummaryFormat: summaryFormat, options: []) UNUserNotificationCenter.current().setNotificationCategories([podcastCategory])

In the above code, I start by initiating two variables:

  • hiddenPreviewsPlaceholder
    This placeholder is used in case the user has “Show Previews” off for your app; if we don’t have a placeholder there, your notification will show with only “Notification” also the text.
  • summaryFormat
    This string is new for iOS 12 and coincides with the new feature called “Group Notifications” that will help the Notification Center look a lot cleaner. All notifications will show up in stacks which will be either representing all notifications from the app or specific groups that the developer has set for there app.

The code below shows how we associate a notification with a group.

@objc func sendPodcastNotification(for podcastName: String) { let content = UNMutableNotificationContent() content.body = "Introducing Season 7" content.title = "New episode of \(podcastName):" content.threadIdentifier = podcastName.lowercased() content.summaryArgument = podcastName content.categoryIdentifier = NotificationCategoryType.podcast.rawValue sendNotification(with: content) }

For now, I’ve hardcoded the text of the notification just for the example. The threadIdentifier is what creates the groups that we show as stacks in the Notification Center. In this example, I want the notifications grouped by podcast so each notification you get is separated by what podcast it’s associated with. The summaryArgument matches back to our categorySummaryFormat we set in the app delegate. In this case, we want the string for the format: "%u more episodes of %@" to be the podcast name. Lastly, we have to set the category identifier to ensure the notification has the template we set in the app delegate.

func sendNotification(for category: String, with content: UNNotificationContent) { let uuid = UUID().uuidString let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false) let request = UNNotificationRequest(identifier: uuid, content: content, trigger: trigger) UNUserNotificationCenter.current().add(request, withCompletionHandler: nil) }

The above method is how we request the notification to be sent to the device. The identifier for the request is just a random unique string; the content is passed in and we create the content in our sendPodcastNotification method, and lastly, the trigger is when you want the notification to send. If you want the notification to send immediately, you can set that parameter to nil.

Grouped notifications for NotificationTester. (Large preview) Notification grouped with previews turned off. (Large preview)

Using the methods we’ve described above, here’s the result on the simulator. I have a button that has the sendPodcastNotification method as a target. I tapped the button three times to have the notifications sent to the device. In the first photo, I have “Show Previews” set to “Always” so I see the podcast and the name of the new episodes along with the summary that shows I have two more new episodes to check out. When “Show Previews” is set to “Never,” the result is the second image above. The user won’t see which podcast it is to respect the “No Preview” setting, but they can still see that I have three new episodes to check out.

Notification Content Extension

Now that we understand how to set our notification categories and make the request for them to be sent, we can go over how to customize the look of the notification using the Notification Service and Notification Content extensions. The Notification Service extension allows you to edit the notification content and download any attachments in your notification like images, audio or video files. The Notification Content extension contains a view controller and storyboard that allows you to customize the look of your notification as well as handle any user interaction within the view controller or taps on notification actions.

To add these extensions to your app go File →  New →  Target.

Adding new target to app for the Notification Content Extension. (Large preview)

You can only add them one at a time, so name your extension and repeat the process to add the other. If a pop-up appears asking you to activate your new scheme, click the “Activate” button to set it up for debugging.

For the purpose of this tutorial, we will be focusing on the Notification Content Extension. For local notifications, we can include the attachments in the request, which we’ll go over later.

First, go to the Info.plist file in the Notification Content Extension target.

Info.plist for the Notification Content Extension. (Large preview)

The following attributes are required:

  • UNNotificationExtensionCategory
    A string value equal to the notification category which we created and set in the app delegate. This will let the content extension know which notification you want to have custom UI for.
  • UNNotificationExtensionInitialContentSizeRatio
    A number between 0 and 1 which determines the aspect ratio of your UI. The default value is 1 which will allow your interface to have its total height equal to its width.

I’ve also set UNNotificationExtensionDefaultContentHidden to “YES” so that the default notification does not show when the content extension is running.

You can use the storyboard to set up your view or create the UI programmatically in the view controller. For this example I’ve set up my storyboard with an image view which will show the podcast logo, two labels for the title and body of the notification content, and a “Like” button which will show a heart image.

Now, in order to get the image showing for the podcast logo and the button, we need to go back to our notification request:

guard let pathUrlForPodcastImg = Bundle.main.url(forResource: "startup", withExtension: "jpg") else { return } let imgAttachment = try! UNNotificationAttachment(identifier: "image", url: pathUrlForPodcastImg, options: nil) guard let pathUrlForButtonNormal = Bundle.main.url(forResource: "heart-outline", withExtension: "png") else { return } let buttonNormalStateImgAtt = try! UNNotificationAttachment(identifier: "button-normal-image", url: pathUrlForButtonNormal, options: nil) guard let pathUrlForButtonHighlighted = Bundle.main.url(forResource: "heart-filled", withExtension: "png") else { return } let buttonHighlightStateImgAtt = try! UNNotificationAttachment(identifier: "button-highlight-image", url: pathUrlForButtonHighlighted, options: nil) content.attachments = [imgAttachment, buttonNormalStateImgAtt, buttonHighlightStateImgAtt]

I added a folder in my project that contains all the images we need for the notification so we can access them through the main bundle.

Xcode project navigator. (Large preview)

For each image, we get the file path and use that to create a UNNotificationAttachment. Added that to our notification content allows us to access the images in the Notification Content Extension in the didReceive method shown below.

func didReceive(_ notification: UNNotification) { self.newEpisodeLabel.text = notification.request.content.title self.episodeNameLabel.text = notification.request.content.body let imgAttachment = notification.request.content.attachments[0] let buttonNormalStateAtt = notification.request.content.attachments[1] let buttonHighlightStateAtt = notification.request.content.attachments[2] guard let imageData = NSData(contentsOf: imgAttachment.url), let buttonNormalStateImgData = NSData(contentsOf: buttonNormalStateAtt.url), let buttonHighlightStateImgData = NSData(contentsOf: buttonHighlightStateAtt.url) else { return } let image = UIImage(data: imageData as Data) let buttonNormalStateImg = UIImage(data: buttonNormalStateImgData as Data)?.withRenderingMode(.alwaysOriginal) let buttonHighlightStateImg = UIImage(data: buttonHighlightStateImgData as Data)?.withRenderingMode(.alwaysOriginal) imageView.image = image likeButton.setImage(buttonNormalStateImg, for: .normal) likeButton.setImage(buttonHighlightStateImg, for: .selected) }

Now we can use the file path URLs we set in the request to grab the data for the URL and turn them into images. Notice that I have two different images for the different button states which will allow us to update the UI for user interaction. When I run the app and send the request, here’s what the notification looks like:

Content extension loaded for NotificationTester app. (Large preview)

Everything I’ve mentioned so far in relation to the content extension isn’t new in iOS 12, so let’s dig into the two new features: User Interaction and Dynamic Actions. When the content extension was first added in iOS 10, there was no ability to capture user touch within a notification, but now we can register UIControl events and respond when the user interacts with a UI element.

For this example, we want to show the user that the “Like” button has been selected or unselected. We already set the images for the .normal and .selected states, so now we just need to add a target for the UIButton so we can update the selected state.

override func viewDidLoad() { super.viewDidLoad() // Do any required interface initialization here. likeButton.addTarget(self, action: #selector(likeButtonTapped(sender:)), for: .touchUpInside) } @objc func likeButtonTapped(sender: UIButton) { likeButton.isSelected = !sender.isSelected }

Now with the above code we get the following behavior:

Selecting like button within notification. (Large preview)

In the selector method likeButtonTapped, we could also add any logic for saving the liked state in User Defaults or the Keychain, so we have access to it in our main application.

Notification actions have existed since iOS 10, but once you click on them, usually the user will be rerouted to the main application or the content extension is dismissed. Now in iOS 12, we can update the list of notification actions that are shown in response to which action the user selects.

First, let’s go back to our app delegate where we create our notification categories so we can add some actions to our podcast category.

let playAction = UNNotificationAction(identifier: "play-action", title: "Play", options: []) let queueAction = UNNotificationAction(identifier: "queue-action", title: "Queue Next", options: []) let podcastCategory = UNNotificationCategory(identifier: "podcast", actions: [playAction, queueAction], intentIdentifiers: [], hiddenPreviewsBodyPlaceholder: hiddenPreviewsPlaceholder, categorySummaryFormat: summaryFormat, options: [])

Now when we run the app and send a notification, we see the following actions shown below:

Notification quick actions. (Large preview)

When the user selects “Play,” we want the action to be updated to “Pause.” If they select “Queue Next,” we want that action to be updated to “Remove from Queue.” We can do this in our didReceive method in the Notification Content Extension’s view controller.

func didReceive(_ response: UNNotificationResponse, completionHandler completion: (UNNotificationContentExtensionResponseOption) -> Void) { guard let currentActions = extensionContext?.notificationActions else { return } if response.actionIdentifier == "play-action" { let pauseAction = UNNotificationAction(identifier: "pause-action", title: "Pause", options: []) let otherAction = currentActions[1] let newActions = [pauseAction, otherAction] extensionContext?.notificationActions = newActions } else if response.actionIdentifier == "queue-action" { let removeAction = UNNotificationAction(identifier: "remove-action", title: "Remove from Queue", options: []) let otherAction = currentActions[0] let newActions = [otherAction, removeAction] extensionContext?.notificationActions = newActions } else if response.actionIdentifier == "pause-action" { let playAction = UNNotificationAction(identifier: "play-action", title: "Play", options: []) let otherAction = currentActions[1] let newActions = [playAction, otherAction] extensionContext?.notificationActions = newActions } else if response.actionIdentifier == "remove-action" { let queueAction = UNNotificationAction(identifier: "queue-action", title: "Queue Next", options: []) let otherAction = currentActions[0] let newActions = [otherAction, queueAction] extensionContext?.notificationActions = newActions } completion(.doNotDismiss) }

By resetting the extensionContext?.notificationActions list to contain the updated actions, it allows us to change the actions every time the user selects one. The behavior is shown below:

Dynamic notification quick actions. (Large preview) Summary

There’s a lot to do before iOS 12 launches to make sure your notifications are ready. The steps vary in complexity and you don’t have to implement them all. Make sure to first download XCode 10 beta so you can try out the features we’ve gone over. If you want to play around with the demo app I’ve referenced throughout the article, check it out on Github.

For Your Notification Permissions Request And Settings, You’ll Need To:
  • Determine whether or not you want to enable provisional authorization and add it to your authorization options.
  • If you have already have a customized notification settings view in your app, add providesAppNotificationSettings to your authorization options as well as implement the call back in your app delegate or whichever class conforms to UNUserNotificationCenterDelegate.
For Notification Grouping:
  • Add a thread identifier to your remote and local notifications so your notifications are correctly grouped in the Notification Center.
  • When registering your notification categories, add the category summary parameter if you want your grouped notification to be more descriptive than “more notifications.”
  • If you want to customize the summary text even more, then add a summary identifier to match whichever formatting you added for the category summary.
For Customized Rich Notifications:
  • Add the Notification Content extension target to your app to create rich notifications.
  • Design and implement the view controller to contain whichever elements you want in your notification.
  • Consider which interactive elements would be useful to you, i.e. buttons, table view, switches, etc.
  • Update the didReceive method in the view controller to respond to selected actions and update the list of actions if necessary.
Further Reading (ra, yk, il)
Categories: Web Design

Take A New Look At CSS Shapes

Tue, 09/04/2018 - 04:30
Take A New Look At CSS Shapes Take A New Look At CSS Shapes Rachel Andrew 2018-09-04T13:30:57+02:00 2018-09-15T11:11:14+00:00

CSS Shapes Level 1 has been available in Chrome and Safari for a number of years, however, this week it ships in a production version of Firefox with the release of Firefox 62 — along with a very nice addition to the Firefox DevTools to help us work with Shapes. In this article, I’ll take a look at some of the things you can do with CSS Shapes. Perhaps it’s time to consider adding some curves to your designs?

What Are CSS Shapes?

The CSS Shapes specification Level 1 defines three new properties:

  • shape-outside
  • shape-image-threshold
  • shape-margin

The purpose of this specification is to allow content to flow around a non-rectangular shape, something which is quite unusual on our boxy web. There are a few different ways to create shapes, which we will have a look at in this tutorial. We will also have a look at the Shape Path Editor, available in Firefox, as it can help you to easily understand the shapes on your page and work with them.

In the current specification, shapes can only be applied to a float, so any shapes example needs to start with a floated element. In the example below, I have a PNG image with a transparent background in which I have floated the image left. The text that follows the image now flows around the right and bottom of my image.

What I would like to happen is for my content to follow the shape of the opaque part of the image, rather than follow the line of the physical image file. To do this, I use the shape-outside property, with the value being the URL of my image. I’m using the actual image file to create a path for the content to flow around.

See the Pen Smashing Shapes: image by Rachel Andrew (@rachelandrew) on CodePen.

Note that your image needs to be CORS compatible, so hosted on the same server as the rest of your content or sending the correct headers if hosted on a CDN. Browser DevTools will usually tell you if your image is being blocked due to CORS.

This method of creating shapes uses the alpha channel of the image to create the shape, as we have a shape with a fully transparent area, then all we need do is pass the URL of the image to shape-outside and the shape path follows the line of the fully opaque area.

Sometimes we are a bit slow, and sometimes too fast, but we try our best with articles, printed books and webinars featuring techniques we all can use to improve our work. Smashing Members have a seasoned selection of front-end & UX techniques. No chit-chat or theory. Things that worked, in actual projects. Just sayin'! ;-)

Explore Smashing Membership ↬ Creating A Margin

To push the line of the text away from the image we can use the shape-margin property. This creates a margin between the line of the shape and the content running alongside it.

See the Pen Smashing Shapes: shape-margin by Rachel Andrew (@rachelandrew) on CodePen.

Using Generated Content For Our Shape

In the case above, we have the image displayed on the page and then the text curved around it. However, you could also use an image as the path for the shape in order to create a curved text effect without also including the image on the page. You still need something to float, however, and so for this, we can use Generated Content.

See the Pen Smashing Shapes: generated content by Rachel Andrew (@rachelandrew) on CodePen.

In this example, we have inserted some generated content, floated it left, given it a width and a height and then used shape-outside with our image just as before. We then get a curved line against the whitespace, but no visible image.

Using A Gradient For Our Shape

A CSS gradient is just like an image, which means we can use a gradient to create a shape, which can make for some interesting effects. In this next example, I have created a gradient which goes from blue to transparent; your gradient will need to have a transparent or semi-transparent area in order to use shapes. Once again, I have used generated content to add the gradient and am then using the gradient in the value for shape-outside.

Once the gradient becomes fully transparent, then the shape comes into play, and the content runs along the edge of the gradient.

See the Pen Smashing Shapes: gradients by Rachel Andrew (@rachelandrew) on CodePen.

Using shape-image-threshold To Position Text Over A Semi-Opaque Image

So far we have looked at using a completely transparent part of an image or of a gradient in order to create our shape, however, the third property defined in the CSS Shapes specification means that we can use images or gradients with semi-opaque areas by setting a threshold. A value for shape-image-threshold of 1 means fully opaque while 0 means fully transparent.

A gradient like our example above is a great way to see this in action as we can change the shape-image-threshold value and move the line along which the text falls to more opaque areas or more transparent areas. This property works in exactly the same way with an image that has an alpha channel yet is not fully transparent.

See the Pen Smashing Shapes: shape-image-threshold by Rachel Andrew (@rachelandrew) on CodePen.

This method of creating shapes from images and gradients is — I think — the most straightforward way of creating a shape. You can create a shape as complex as you need it to be, in the comfort of a graphics application and then use that to define the shape on your page. That said, there is another way to create our shapes, and that’s by using Basic Shapes.

CSS Shapes With Basic Shapes

The Basic Shapes are a set of predefined shapes which cover a lot of different types of shapes you might want to create. To use a basic shape, you use the basic shape type as a value for shape-outside. This type uses functional notation, so we have the name of the shape followed by brackets (inside which are some values for our shape).

The options that you have are the following:

  • inset()
  • circle()
  • ellipse()
  • polygon()

We will take a look at the circle() type first as we can use this to understand some useful things which apply to all shapes which use the basic shape type. We will also have a look at the new tools in Firefox for inspecting these shapes.

In the example below, I am creating the most simple of shapes: a circle using shape-outside: circle(50%). I’m using generated content again, and I have given the box a background color, and also added a margin, border, and padding to help highlight some of the concepts of using CSS Shapes. You can see in the example that the circle is created centered on the box; this is because I have given the circle a value of 50%. That value is the <shape-radius> which can be a length or a percentage. I’ve used a percentage so that the radius is half of the size of my box.

See the Pen Smashing Shapes: shape-outside: circle() by Rachel Andrew (@rachelandrew) on CodePen.

This is a really good to time have a look at the shape that has been created using the Firefox Shape Path Editor. You can inspect the shape by clicking on the generated content and then clicking the little shape icon next to the property shape-outside; your shape will now highlight.

The Shape Path Editor highlights the circle shape (Large preview)

You can see how the circle extends to the edge of the margin on our box. This is because the initial reference box used by our shape is margin-box. You already know something of reference boxes if you have ever added box-sizing: border-box to your CSS. When you do this, you are asking CSS to use the border-box and not the default content-box as the size of elements. In Shapes, we can also change which reference box is used. After any basic shape, add border-box to use the border to define the shape or content-box to use the edge of the content (inside the padding). For example:

.content::before { content: ""; width: 150px; height: 150px; margin: 20px; padding: 20px; border: 10px solid #FC466B; background: linear-gradient(90deg, #FC466B 0%, #3F5EFB 100%); float: left; circle(50%) content-box; }

You will see the circle appear to become much smaller. It is now using the width of the content — in this case the width of the box at 150px — rather than the margin box which includes the padding, border, and margin.

The content-box is the edge of the content of the square we created with our generated content (Large preview)

Inspecting your element in Firefox DevTools will also show you the reference boxes so you can choose which might give you the best result with your particular shape.

Reference boxes highlighted in Firefox (Large preview) The Position Value

A second value can be passed to circle() which is a position; if you do not pass this value, it defaults to center. However, you can use this value to pull your circle around. In the next example, I have positioned the circle by using shape-outside(50% at 30%); this changes where the center of the circle is positioned.

See the Pen Smashing Shapes: circle() with position by Rachel Andrew (@rachelandrew) on CodePen.

clip-path

Something useful to know is that the same <basic-shape> values can be used as a value for clip-path. This means that after creating a shape, you can clip away the image or background color that extends outside of the shape. In the example below, I am going to do this with our example gradient background, so that we end up with a circle that has text curved around from our square box.

See the Pen Smashing SHapes: circle() with clip-path by Rachel Andrew (@rachelandrew) on CodePen.

All of the above concepts can be applied to our other basic shapes. Now let’s have a quick look at how they work.

inset()

The inset() value defines a rectangle. This might not seem very useful as a float is a rectangle, however, this value means that you can inset the content wrapping your shape. It takes four values for top, right, bottom, and left plus a final value which defines a border radius.

In the example below, I am using the values to inset the content on the right and bottom of the floated image, plus adding a border radius around which my content will wrap using shape-outside: inset(0 30px 100px 0 round 40px). You can see how the content is now over the background color of the box:

See the Pen Smashing Shapes: inset() by Rachel Andrew (@rachelandrew) on CodePen.

ellipse()

An ellipse is a squashed circle and as such needs two radii for x and y (in that order). You can then push the ellipse around just as with circle using the position value. In the example below, I am creating an ellipse and then using clip-path with the same values to remove the content outside of my shape.

See the Pen Smashing Shapes: ellipse() by Rachel Andrew (@rachelandrew) on CodePen.

In the above example, I also used shape-margin to demonstrate how we can use this property as with our image generated shapes to push the content away.

polygon()

Creating polygon shapes gives us the most flexibility, as our shapes can be created with three or more points. The value passed to the polygon needs to be three or more pairs of values which represent coordinates.

It is here where the Firefox tools become really useful as we can use them to help create our polygon. In the below example, I have created a polygon with four points. In the Firefox DevTools, you can double-click on any line to create a new point, and double-click again to remove it. Once you have created a polygon that you are happy with, you can then copy the value out of DevTools for your CSS.

See the Pen Smashing Shapes: polygon() by Rachel Andrew (@rachelandrew) on CodePen.

Fallbacks

As CSS Shapes are applied to a float, in many cases the fallback is that instead of seeing the content wrap around a shape, the content will wrap around a floated element (in the way that content has always wrapped around floats). Browsers ignore properties they do not understand, so if they don’t understand Shapes, it doesn’t matter that the shape-outside property is there.

Where you should take care would be in any situation where not having shapes could mean that content overlaid an area which made it difficult to read. Perhaps you are using Shapes to push content away from a busy area of a background image, for example. In that case, you should first make sure that your content is usable for the non-Shapes people, then use Feature Queries to check for support of shape-outside and overwrite that CSS and apply the shape. For example, you could use a margin to push the content away for non-Shapes visitors and remove the margin inside your feature query.

.content { margin-left: 120px; } @supports (shape-outside: circle()) { .content { margin-left: 0; /* add the rest of your shapes CSS here */ } }

With Firefox releasing their support we now only have one main browser without support for Shapes — Edge. If you want to see Shapes support across the board you could go and vote for the feature here, and see if we can encourage the implementation of the feature in Edge.

Find Out More About CSS Shapes

In this article, I’ve tried to give a quick overview of some of the interesting things that are possible with CSS Shapes. For a more in-depth look at each feature, check out the Guides to CSS Shapes over at MDN. You can also read a guide to the Shape Path Editor in Firefox.

(il)
Categories: Web Design

Get Your Mobile Site Ready For The 2018 Holiday Season

Mon, 09/03/2018 - 05:30
Get Your Mobile Site Ready For The 2018 Holiday Season Get Your Mobile Site Ready For The 2018 Holiday Season Suzanne Scacca 2018-09-03T14:30:43+02:00 2018-09-15T11:11:14+00:00

After reading the title of this article, it might seem like it’s jumping the gun, but with retailers turning on holiday music and putting out holiday-related displays earlier and earlier every year, your consumers are primed to start thinking about the holidays earlier, too. In fact, a study done by the Tampa Bay Times revealed that in-store shoppers were exposed to holiday music as early as October 22 in 2017.

Results from TBT’s survey on when holiday music starts (Source: Tampa Bay Times) (Large preview)

Of course, e-commerce handles the holiday season a bit differently than brick-and-mortar. It’s not really necessary to announce promotions or run sales in late October or early November. However, that doesn’t mean you should wait until the last minute to prepare your mobile website for the holidays.

In this article, I’m going to give you a quick rundown of what happened during the 2017 holiday sales season and, in particular, what role mobile played in it. Then, we’re going to dig into holiday design and marketing tactics you can use to boost sales through your mobile website for the 2018 holiday season.

Recommended reading: How Mobile Web Design Affects Local Search (And What To Do About It)

A Recap Of The 2017 Holiday Sales Season

Before we get started, I want to quickly add a disclaimer:

This particular section focuses on e-commerce statistics because this kind of data is readily available. Something like the total number of page visits, subscribed readers, and leads generated... well, it’s not.

So, although I only use data to express how important mobile was to 2017 holiday sales, keep in mind that the tips that follow pertain to all websites. Even if your site doesn’t expressly sell goods or services, blogs and other content-driven sites can take advantage of this, too!

Sometimes we are a bit slow, and sometimes too fast, but we try our best with articles, printed books and webinars featuring techniques we all can use to improve our work. Smashing Members have a seasoned selection of front-end & UX techniques. No chit-chat or theory. Things that worked, in actual projects. Just sayin'! ;-)

Explore Smashing Membership ↬

Now, let’s take a look at the numbers:

Total Retail Sales

The National Retail Federation calculated the total amount of retail sales--online and in-store--to be $691.9 billion between November and December, a 5.5% bump from 2016.

Total e-Commerce Sales

Adobe put the total amount of e-commerce sales during that same timeframe at $108.15 billion in 2017.

Adobe’s stats on 2016 and 2017 holiday e-commerce revenue (Source: Adobe) (Large preview) e-Commerce Sales By Device

Adobe takes it even further and breaks down the share of revenue by device:

Breakdown of desktop, smartphone and tablet sales for 2017 holiday season (Source: Adobe) (Large preview) e-Commerce Sales vs. Traffic

While smartphone and tablet sales still trail those on desktop, there are a couple interesting things to note here. For starters, desktop revenue has mostly flatlined year-over-year whereas mobile continues to grow. In addition, there’s an interesting disparity between how much traffic comes from each device and what percentage of revenue it generates:

Traffic vs. revenue for desktop, smartphone, tablet (Source: Adobe) (Large preview)

Pay close attention to desktop and smartphone. As you can see, more visits stem from smartphones than any other device and, yet, desktop leads the way in conversions:

Statista shows the breakdown between desktop, smartphone, and tablet conversions in Q1 2018 (Source: Statista) (Large preview)

Is this indicative of a lack of trust in smart devices to handle purchases?

In all likelihood, it probably isn’t. Data from other sources indicates that on holidays, in particular, mobile reigns supreme in terms of visits and conversions:

  • Thanksgiving Day: 62% of traffic / 46% of purchases.
  • Christmas Day: 68% of traffic / 50% of purchases.

Also, let’s not forget to take into account the strengths of mobile devices within the shopper’s experience. According to the four micro-moments as defined by Google, a large number of mobile users commonly search for the following:

  • “I want to know.”
  • “I want to go.”
  • “I want to do.”
  • “I want to buy.”

The second and third are clearly indicative of a searcher’s desire to find something outside their devices (and their homes) to spend money on. That might even be so for the fourth, though it could also be an indication that they want to do their research on mobile and complete the purchase on desktop.

Either way, we know that smartphones tend to be a primary facilitator in the customer’s journey and not something that’s putting an end to the shopping experience as a whole.

Recommended reading: Designing For Micro-Moments

5 Tips To Prepare Your Mobile Site For The 2018 Holiday Season

While the overall numbers indicate that desktop is the leading platform for holiday sales, it’s not a universal rule that can be applied to each and every day in November and December. This is why your own data will have to play a big role in the design choices you make for your mobile site this season.

You have to admit, no matter how stressed or unhappy you might feel around the holidays, there is something nice about encountering just the right hint of holiday “cheer”. And that’s one of the keys to doing this right: finding the right amount of holiday flavor to infuse into your website.

Before we get into what you can do to spruce up your mobile web design, I want to remind you that security and speed are critical elements to check off your list before November gets here. These might not be in your realm of responsibilities, but that doesn’t mean you shouldn’t keep an eye on them.

If you’re doing all this design work in anticipation of boosting conversions over the holidays, don’t let it all be for nothing by forgetting about performance and security essentials. To protect your site from potentially harmful traffic surges, start with this front-end performance checklist. With regards to security, you can use these security improvement tips.

Now, let’s talk about the five ways in which you can prepare your mobile website for the 2018 holiday season:

1. Study Last Year’s Data

If your website has been live and actively doing business for more than a year, you need to start with the data from 2017. Using Google Analytics and your CRM platform, locate answers to the following questions:

What was the prominent device that generated traffic? Sales?

Google Analytics allows you to divvy up traffic based on technology in a number of ways:

Under Browser & OS, you can sort visitors by browser:

Google Analytics shows which browsers users visited from (Source: Google Analytics) (Large preview)

There is a small tab at the top of the table for “Operating System”. Click that to reveal which OS were used:

Google Analytics breaks down traffic by operating system (Source: Google Analytics) (Large preview)

You can use the Mobile → Overview tab to look at the simple breakdown between desktop, mobile, and tablet users.

Google Analytics division between device traffic (Source: Google Analytics) (Large preview)

Really, your goal here is to weed out desktop users so you can focus strictly on mobile traffic as you assess the following data points.

When did your site experience an increase in traffic in November or December?

Every website’s holiday traffic history will look a little different. Take mine, for example:

An example of holiday traffic up and downs in Google Analytics (Source: Google Analytics) (Large preview)

My business really isn’t affected by the holidays at all... except that I know things are going to be super quiet on and around Thanksgiving and the major holidays in December. This is still important information for me to have.

For businesses that directly sell products or services through their site or content-based sites that plan publication schedules based on traffic, you’ll likely see a different trajectory in terms of highs and lows.

When did sales start to increase (if they don’t coincide with traffic)?

Again, for some of you, the matter of sales is irrelevant if you don’t offer any through your site. For everyone else, however, use the Google Analytics Conversions tab along with sales logged through your payment gateway or CRM to check this number.

Just remember that you have to activate the Conversions module in Google Analytics if you want it to track that data. If you didn’t remember last year, put it in place for this year.

Did the holiday uptick remain consistent until the end of the season or were there temporary dropoffs?

Much of this has to do with how you promote holiday-related events, promotional offers or content through your website. If you consistently market around the holidays from November 1 to the end of the year, you should see relatively steady traffic and sales.

Some days, of course, may be slower than others (like during workdays or earlier in the season), so it’s good to get a sense for the ebb and flow of your site’s holiday traffic. On the other hand, your website might be a major draw only on special sales days and the holidays themselves, so you can use this data to harness your energy for a big push on the days when it’ll have the greatest impact.

Try to identify patterns, so you can plan your design and marketing strategy accordingly.

When did traffic and sales return to their usual amount?

At some point, your site is going to see a dip in activity. There are some businesses that embrace this.

Let’s use Xfinity as an example. Around mid-November of last year, this is the holiday-centric message the top of the home page was pushing:

Xfinity promotes ways to make your home holiday ready (Source: Xfinity) (Large preview)

A month later, on December 9, any mention of the holidays was gone and replaced by a promotion of the upcoming Olympic Winter Games.

Xfinity stops promoting holidays in December (Source: Xfinity) (Large preview)

One can only assume that a major sporting event like the Olympics helps Xfinity sign more subscribers than trying to capture last-minute sales for the holidays.

Logically, this makes sense. December is a busy time for families. They’re planning travel, purchasing gifts and running around town in preparation for the upcoming celebrations. Most people probably don’t have time to set up a new cable or Internet package and wait around for Xfinity to configure it then.

Bottom line: it’s okay if your holiday-related traffic and sales drop off earlier than December 31. Study your data and let your user behavior guide you in your mobile design and promotion strategy.

What were the most popular sources for mobile traffic?

It’s actually not enough to identify the most popular sources of mobile traffic for your site. Sure, you want to know if organic SEO and social media promotional efforts worked to bring traffic to it… but it won’t really matter if those visitors abandoned the site without taking action.

When you start digging through the ways in which you acquired mobile visitors, make sure to review the sources and keywords used against other telling metrics, like:

  • Bounce rate
  • Time on site
  • Pages visited

This will give you a good sense for what sources — e.g. keywords, PPC ads, social media content, promotional backlinks from other sites — that attracted high-quality leads to it during the holiday season.

What were the most/least successful promotions?

One more thing to look at is what exactly performed the best between November and December with mobile visitors.

Did you run a pop-up promoting free shipping that was dismissed by most mobile visitors, but greatly taken advantage of by those on desktop? Did your custom home page banner touting an upcoming Black Friday sale get more clicks than the home page banner otherwise does at other times of the year? And what pathway resulted in the most conversions?

Dig into what exactly it was that appealed to your mobile visitors. Then, as you work on this year’s plan, focus on reproducing that success.

2. Assess The Navigation

The navigation plays two important roles on a website:

  1. High-level tabs inform visitors on what they’ll find on the site; essentially answering the question, “Is this of relevance to me?”
  2. The navigation itself provides visitors with shortcuts to parts of the site that matter most to them, simplifying their pathway to conversion.

When reviewing your navigation in the context of holiday traffic, you must ensure that it fulfills both of these roles.

Let’s look at two websites that provide relevant links during the holidays while also streamlining the visitors’ journey from entry to holiday-related pages.

Food52 is an online hub for people who enjoy cooking. You can buy kitchen gadgets from the site and peruse a whole bunch of content related to food and cooking.

I want to call out a number of things Food52 does especially well in terms of navigation:

The Food52 home page includes Thanksgiving-related categories (Source: Food52) (Large preview)
  1. The hamburger menu is prominently displayed in the top-left, which is exactly where visitors’ eyes will go as they follow the Z-shaped pattern for reading.
  2. The shopping cart, search bar shortcut and profile link are also displayed in the top header, making it easy to navigate to elements that support the shopping experience.
  3. If you scroll down on the home page (as I’ve done in the screenshot above), Food52 includes a good mix of Thanksgiving-related content along with its standard fare. In addition, it includes categories that help users filter through content that’s most relevant to them.

One other thing I’d like to point out is the navigation itself:

Simplified and customized navigation from Food52 for Thanksgiving (Source: Food52) (Large preview)

There are a number of things you’ll notice:

  • The mobile navigation is quite simplified. Despite how many categories and types of pages the site has, the navigation keeps this from being an overwhelming choice.
  • There are special tabs for Thanksgiving and Holiday. This will get users directly to content related to the holiday they’re cooking for.
  • The Hotline — which is its customer service forum — is also featured in the mobile navigation. This element is especially important around the holidays when visitors have questions they need answered quickly.

L.L.Bean is another website that handles mobile navigation well.

L.L.Bean puts the essentials in the navigation (Source: L.L.Bean) (Large preview)

As you can see, there are four buttons located within the mobile header:

  • Hamburger navigation icon: bolded and well-placed;
  • L.L.Bean logo for easy backtracking to the home page;
  • A shopping cart icon which will keep stored items top-of-mind with mobile users;
  • An ever-present search bar to speed up navigation even further.

Once a mobile user expands the hamburger navigation, they encounter this:

L.L.Bean prioritizes customer service and gifts around the holidays (Source: L.L.Bean) (Large preview)

As you can see, “Call Us” is the first option available within the mobile navigation. Again, with people in a rush and trying to get purchases done right over the holidays, having a direct line of communication to the company is important. The account link and “Ship To” personalization are also nice touches as these icons keep conversion top-of-mind.

Now, looking down the navigation, you’ll see this is a pretty standard mega menu. However, take note that at the very top of this category (as is the case for all others) appears a page for “Gifts”. This is not something you see the rest of the year, so that’s another holiday-related touch meant to streamline searches and sales.

3. Use Add-ons At Checkout

Here is everything you need to know to optimize conversions at mobile checkout. If I can add an additional two cents to this matter, though, I’d like to briefly talk about add-ons at checkout… but only around the holidays.

Typically, I believe that a fully streamlined checkout process is essential to capturing as many conversions as possible on mobile devices. It’s hard enough typing out all that information (if it doesn’t auto-populate) and trusting that devices and websites will keep payment information secure.

However…

When it comes to designing the checkout for holiday shoppers, I think it’s at least worth experimenting with add-ons. For example:

  • Promo codes
  • Free delivery options
  • Shorter, but more premium delivery or pick up in store options
  • Gift wrapping.

Nordstrom doesn’t even wait for visitors to get to the checkout to promote this.

Nordstrom promotes free shipping and returns right away (Source: Nordstrom) (Large preview)

The very top of the site has a sticky bar promoting the free shipping and returns offer. This way, visitors are already in the mindset that they can get their Black Friday purchases or holiday gifts for even cheaper than planned.

Fitbit has another example of this I really like:

Fitbit promotes sales and free expedited shipping (Source: Fitbit) (Large preview)

The top-half of the Fitbit homepage gets visitors into the mindset that there are cost savings galore here. Not only are items on sale, but certain orders come with free and expedited shipping. And the site clearly states when the sale ends, which will keep customers from getting upset if gifts don’t arrive on time. (It will also probably motivate them to get their shopping done sooner if they want to cash in on the sale.)

So all appropriate expectations regarding pricing and shipping are set right from the very get-go, making checkout go more smoothly.

I know that some may argue these will be bad for UX (and normally I’d join them), but I don’t see them as distractions during the holidays. This is an expensive and busy time of year.

Anything you can add to checkout that says, “Hey, we’re thinking about you and want to make this holiday season go just a little more smoothly” would go over well with your users.

4. Give Images A Seasonal Touch

Images are a tricky thing this time of year. You want to use them to appeal to holiday-minded visitors, but you don’t want to overdo it because images add a lot of pressure to your server. You need your site running fast, so be smart about what you do with them.

  1. Resize them before you ever add them to your site. There’s no need to use oversized images if they’re going to appear smaller online.
  2. Optimize your images with compression tools before and after they’re added to the design. This will free up some space they would otherwise take.
  3. If your users’ journey starts above-the-fold, you might want to consider lazy-loading images.

That said, images can go a long way in communicating to visitors that your site and business are ready to spread some holiday cheer without having to ever explicitly say it. This might be the ideal choice for those of you who design websites for global audiences. Perhaps you’d rather use an image that evokes a festive feeling because you don’t want to unintentionally offend anyone who doesn’t celebrate the holiday your copy calls express attention to.

Here is a great example from Uncommon Goods:

Uncommon Goods holiday home page (Source: Uncommon Goods) (Large preview)

I wouldn’t necessarily say the images used here are festive, but there are unique elements that evoke a certain association with the holidays. Like the color green used within the photos. Or the partial glances of what appear to be snow globes. They’re seasonal elements, but not necessarily relegated to Christmas, Hanukkah or Kwanzaa.

Then, there’s the United States Postal Service (USPS) website. Granted, this website targets visitors within the United States, but it remains mindful of the differences in religions practiced and holidays celebrated.

USPS uses a non-denominational image to promote the holidays (Source: USPS) (Large preview)

The message remains neutral as does the image itself. The USPS is simply trying to help people quickly and festively send holiday cards, gifts and other items to distant relatives and friends.

5. Review The Customer Journey

The factor of speed is a big one when it comes to designing the customer journey. While the navigation cuts down on any unnecessary steps that might be taken when visitors can afford a more leisurely pace, your design should expedite the rest.

In other words:

  • Start talking about holiday-related content, products, pages and links right on the home page.
  • Make sure you have at least one mention above-the-fold, whether it’s in the navigation, in a blog link or in a seasonal promo.
  • Use the data from last year to streamline the ideal pathway from the home page to conversion.
  • Walk through that pathway as a visitor on both desktop and mobile. Is it as clear, concise and direct as possible?
  • Check the responsiveness of the pathway. Your site, in general, needs to be responsive, but if you’re optimizing a certain journey for visitors and you want them to convert on mobile, then extra care needs to be taken.

Below is another example from the Food52 website from the holidays. As you can see in this snippet, two kinds of holiday-related content are promoted. What’s cool about them, though, is that it’s not necessarily in-your-face.

Food52 adds a holiday touch to its home page design and copy (Source: Food52) (Large preview)

The relish recipe could easily be used any time of the year. However, because pomegranates are often considered a winter food, this falls into the category of holiday-related content. The second post is more blatant about attracting holiday readers.

The final element in this screenshot is also worth taking note of. To start, it appears they’ve customized the copy specifically for this time of year. All it takes is one addition of the word “joyfully” to let visitors know that Food52 took time to make its site just a little more festive.

I also want to give them kudos for including a newsletter subscription box here and in other key areas of the site.

If the research from Adobe is right and only about half of mobile visitors convert, then this is a smart design choice. This way, Food52 can collect visitor information on mobile and contact them later. When interested visitors receive the reminder at a more convenient time and place, they can hop onto their desktop or other preferred device and finish the conversion process.

Another site which I think handles the customer journey optimization well is Cracker Barrel.

Cracker Barrel home page design (Source: Cracker Barrel) (Large preview)

Cracker Barrel doesn’t overdo it when it comes to designing for the holidays. Instead, it’s developed a series of calls-to-action that set certain types of visitors on the right path.

The first one features an image of what looks like a holiday feast with the CTA “Order Heat N’ Serve”. That’s brilliant. If people are taking the time to visit this site right before Thanksgiving, it’s probably to see if they can get help preparing their major feast… which it appears they can.

The second section sort of looks festive, though I’d still say they play it safe with choice of color, texture and gift card image. With a CTA of “Buy Gift Cards”, they’re now appealing to holiday shoppers. Not only can you get a whole feast conveniently prepared by Cracker Barrel, but you can buy gifts here, too.

Sometimes designing for the holidays isn’t about the blatant use of snowflake imagery or promoting recipes for cooking a turkey. Sometimes it’s about understanding what your users’ particular needs are at that time and helping setting them on that exact journey right away.

Wrap-Up

I understand that there are ways to add a dancing Santa to a site or to spruce up pop-ups with animated text and images, but I think subtler is better.

It’s kind of like the whole holiday music and decorations thing. How many times have you gone to your local drug store at the end of October for the purposes of getting Halloween candy, only to be met by an entire aisle full of holiday decorations? Or maybe you entered a department store like Macy’s in November, thinking you’ll beat the crazy holiday crowds. And, yet, holiday music is already playing. It’s overkill.

If you want to impress mobile visitors with your website around the holidays, focus on making this a worthwhile experience. Optimize your server for high volumes of traffic, put extra security in place, reorganize the navigation and add some small festive touches to your design that call attention to the most relevant parts of your site at this time of year.

(ra, yk, il)
Categories: Web Design

Come Rain Or Come Shine: Inspiring Wallpapers For September 2018

Fri, 08/31/2018 - 03:45
Come Rain Or Come Shine: Inspiring Wallpapers For September 2018 Come Rain Or Come Shine: Inspiring Wallpapers For September 2018 Cosima Mielke 2018-08-31T12:45:54+02:00 2018-09-15T11:11:14+00:00

September is a time of transition. While some are trying to conserve the summer feeling just a bit longer, others are eager for fall to come with its colorful leaves and rainy days. But no matter how you feel about September or what the new month might be bringing along, this wallpaper collection sure has something to inspire you.

Just like every month since more than nine years already, artists and designers from across the globe once again challenged their creative skills and designed wallpapers to help you break out of your routine and give your desktop a fresh makeover. Each one of them comes in versions with and without a calendar for September 2018 and can be downloaded for free.

As a little extra goodie, we also went through our archives on the look for some timeless September wallpaper treasures which you’ll find assembled at the end of this post. Please note that these oldies, thus, don’t come with a calendar. Happy September!

Please note that:

  • All images can be clicked on and lead to the preview of the wallpaper,
  • You can feature your work in our magazine by taking part in our Desktop Wallpaper Calendar series. We are regularly looking for creative designers and artists to be featured on Smashing Magazine. Are you one of them?
Further Reading on SmashingMag:

Meet Smashing Book 6 with everything from design systems and accessible single-page apps to CSS Custom Properties, Grid, Service Workers, performance, AR/VR and responsive art direction. New frontiers in front-end and UX with Marcy Sutton, Harry Roberts, Laura Elizabeth and many others.

Table of Contents → Cacti Everywhere

“Seasons come and go, but our brave cactuses still stand. Summer is almost over, and autumn is coming, but the beloved plants don’t care.” — Designed by Lívia Lénárt from Hungary.

Batmom

Designed by Ricardo Gimenes from Sweden.

Summer Is Not Over Yet

“This is our way of asking the summer not to go away. We were inspired by travel and exotic islands. In fact, it seems that September was the seventh month in the Roman calendar, dedicated to Vulcan, a god of fire. The legend has it that he was the son of Jupiter and Juno, and being an ugly baby with a limp, his mother tried to push him off a cliff into a volcano. Not really a nice story, but that’s where the tale took us. Anyway, enjoy September — because summer’s not over yet!” — Designed by PopArt Studio from Novi Sad, Serbia.

Summer Collapsed Into Fall

“The lands are painted gold lit with autumn blaze. And all at once the leaves of the trees started falling, but none of them are worried. Since, everyone falls in love with fall.” — Designed by Mindster from India.

Fresh Breeze

“I’m already looking forward to the fresh breezes of autumn, summer’s too hot for me!” — Designed by Bryan Van Mechelen from Belgium.

No More Inflatable Flamingos!

“Summer is officially over and we will no longer need our inflatable flamingos. Now, we’ll need umbrellas. And some flamingos will need an umbrella too!” — Designed by Marina Bošnjak from Croatia.

New Beginnings

“In September the kids and students go back to school.” — Designed by Melissa Bogemans from Belgium.

New Destination

“September is the beginning of the course. We see it as a never ending road because we are going to enjoy the journey.” — Designed by Veronica Valenzuela from Spain.

Good Things Come To Those Who Wait

“They say ‘patience is a virtue’, and so great opportunities and opulence in life come to those who are patient. Here we depicted a snail in the visual, one which longs to seize the shine that comes its way. It goes by the same watchword, shows no impulsiveness and waits for the right chances.” — Designed by Sweans from London.

Back To School

Designed by Ilse van den Boogaart from The Netherlands.

From The Archives

Some things are too good to be forgotten and our wallpaper archives are full of timeless treasures. So here’s a small selection of favorites from past September editions. Please note that these don’t come with a calendar.

Autumn Rains

“This autumn, we expect to see a lot of rainy days and blues, so we wanted to change the paradigm and wish a warm welcome to the new season. After all, if you come to think of it: rain is not so bad if you have an umbrella and a raincoat. Come autumn, we welcome you!” — Designed by PopArt Studio from Serbia.

Maryland Pride

“As summer comes to a close, so does the end of blue crab season in Maryland. Blue crabs have been a regional delicacy since the 1700s and have become Maryland’s most valuable fishing industry, adding millions of dollars to the Maryland economy each year. With more than 455 million blue crabs swimming in the Chesapeake Bay, these tasty critters can be prepared in a variety of ways and have become a summer staple in many homes and restaurants across the state. The blue crab has contributed so much to the state’s regional culture and economy, in 1989 it was named the State Crustacean, cementing its importance in Maryland history.” — Designed by The Hannon Group from Washington DC.

Summer Is Leaving

“It is inevitable. Summer is leaving silently. Let us think of ways to make the most of what is left of the beloved season.” — Designed by Bootstrap Dashboards from India.

Early Autumn

“September is usually considered as early autumn so I decided to draw some trees and leaves. However, nobody likes that summer is coming to an end, that’s why I kept summerish colours and style.” — Designed by Kat Gluszek from Germany.

Long Live Summer

“While September’s Autumnal Equinox technically signifies the end of the summer season, this wallpaper is for all those summer lovers, like me, who don’t want the sunshine, warm weather and lazy days to end.” — Designed by Vicki Grunewald from Washington.

Listen Closer… The Mushrooms Are Growing…

“It’s this time of the year when children go to school and grown-ups go to collect mushrooms.” — Designed by Igor Izhik from Canada.

Autumn Leaves

“Summer is coming to an end in the northern hemisphere, and that means Autumn is on the way!” — Designed by James Mitchell from the United Kingdom.

Festivities And Ganesh Puja

“The month of September starts with the arrival of festivals, mainly Ganesh Puja.” — Designed by Sayali Sandeep Harde from India.

Hungry

Designed by Elise Vanoorbeek from Belgium.

Sugar Cube

Designed by Luc Versleijen from the Netherlands.

Miss, My Dragon Burnt My Homework!

“We all know the saying ‘Miss, my dog ate my homework!’ Well, not everyone has a dog, so here’s a wallpaper to inspire your next excuse at school ;)” — Designed by Ricardo Gimenes from Sweden.

Meet The Bulbs!

“This summer we have seen lighting come to the forefront of design once again, with the light bulb front and center, no longer being hidden by lampshades or covers. Many different bulbs have been featured by interior designers including vintage bulbs, and oddly shaped energy-saving bulbs. We captured the personality of a variety of different bulbs in this wallpaper featuring the Bulb family.” — Designed by Carla Genovesio from the USA.

World Bat Night

“In the night from September 20th to 21st, the world has one of the most unusual environmental events — Night of the bats. Its main purpose: to draw public attention to the problems of bats and their protection, as well as to debunk the myths surrounding the animals, as many people experience unjustified superstitious fear, considering them vampires.” — Designed by cheloveche.ru from Russia.

Autumn Invaders

“Invaders of autumn are already here. Make sure you are well prepared!” Designed by German Ljutaev from Ukraine.

Hello Spring

“September is the start of spring in Australia so this bright wallpaper could brighten your day and help you feel energized!” — Designed by Tazi Design from Australia.

Join In Next Month!

Please note that we respect and carefully consider the ideas and motivation behind each and every artist’s work. This is why we give all artists the full freedom to explore their creativity and express emotions and experience throughout their works. This is also why the themes of the wallpapers weren’t anyhow influenced by us, but rather designed from scratch by the artists themselves.

Thank you to all designers for their participation. Join in next month!

Categories: Web Design

A Brief Guide About Competitive Analysis

Thu, 08/30/2018 - 05:00
A Brief Guide About Competitive Analysis A Brief Guide About Competitive Analysis Mayur Kshirsagar 2018-08-30T14:00:57+02:00 2018-09-15T11:11:14+00:00

In this article, I will introduce the subject of competitive analysis, which is basically a method to determine how well your competitors are performing. My aim is to introduce the subject to those of you who are new to the concept. It should be useful if you are new to product design, UX, interaction or digital design, or if you have experience in these fields but have not performed a competitive analysis before.

No prior knowledge of the topic is needed because I’ll be explaining what the term means and how to perform a competitive analysis as we go. I am assuming some basic knowledge of the design process and UX research, but I’ll provide plenty of practical examples and reference links to help with any terms and concepts you might be unfamiliar with.

Note: If you are a beginner in UX and interaction design, it would be good to know the basics of the design process and to know what is UX research (and the methods used for UX research) before diving into the article’s main topic. Please read the next section carefully because I’ve added reference links to help you get started.

Recommended reading: Standing Out From The Crowd: Improving Your Mobile App With Competitive Analysis

Competitive Analysis, Service Design Cycle, Five-Stages Design Process

If you are a UX designer, then you might be aware of the service design cycle. This cycle contains four stages: discover, explore, test and listen. Each one of these stages has multiple research methods, and competitive analysis is part of the exploration. Susan Farrell has very helpfully distinguished different UX research methods and activities that can be performed for your project. (You can check this detailed segregation in her “UX Research Cheat Sheet”.)

The image below shows the four steps and the most commonly used methods in these steps.

(Large preview)

If you are new to this concept, you might first ask, “What is service design?” Shahrzad Samadzadeh explains it very well in her article, “So, Like, What Is Service Design?.”

Note: You can also learn more about service design in Sarah Gibbons’s article, “Service Design 101.”

Getting workflow just right ain’t an easy task. So are proper estimates. Or alignment among different departments. That’s why we’ve set up “this-is-how-I-work”-sessions — with smart cookies sharing what works well for them. A part of the Smashing Membership, of course.

Explore features →

Often, UX designers follow the five-stages design process in their projects:

  1. empathize,
  2. define,
  3. ideate,
  4. prototype,
  5. test.
The five-stages design process. (Large preview)

Please don’t confuse the five-stages design process with the service design cycle. Basically, they serve the same purpose in the design thinking process, but are explained in different styles. Here is a brief explanation of what these five stages contain:

  • Empathize
    This stage involves gaining a clear understanding of the problem you are trying to solve from the user’s point of view.
  • Define
    This stage involves defining the correct statement for the problem you are trying to solve, using the knowledge you gained in the first stage.
  • Ideate
    In this stage, you can generate different solution ideas for the problem.
  • Prototype
    Basically, a prototype is an attempt to give your solution some form so that it can be explained to others. For digital products, a prototype could be a wireframe set created using pen and paper or using a tool such as Balsamiq or Sketch, or it could be a visual design prototype created using a tool such as Sketch, Figma, Adobe XD or InVision.
  • Test
    Testing involves validating and evaluating all of your solutions with the users.

You can perform UX research at any stage. Many articles and books are available for you to learn more about this design process. “Five Stages in the Design Thinking Process” by Rikke Dam and Teo Siang is one of my favorite articles on the topic.

The most frequent methods used by UX professionals during the exploration stage of the design life cycle. (Nielsen Norman Group, “User Experience Careers” survey report) (Large preview)

According to Nielsen Norman Group’s “User Experience Careers” survey report, 61% of UX professionals prefer to do the competitive analysis for their projects. But what exactly is competitive analysis? In simple language, competitive analysis is nothing but a method to determine how your competitors are performing, what they are offering and how well they are doing it.

Sometimes, competitive analysis is referred as competitive usability evaluation.

Why Should You Do A Competitive Analysis?

There are many reasons to do a competitive analysis, but I think the most important reason is that it helps us to understand the rights and wrongs of our own product or service.

Using competitive analysis, you can make decisions based on knowledge of what is currently working well for your users, rather than based on guesses or intuition. In doing competitive analysis, you can also identify risks in your product or service and use those insights to add value to it.

Recently, I was working on a project in which I did a competitive analysis of a feature (collaborative meeting note-taking) that a client wanted to introduce in their web app. Note-taking is not exactly a new or highly innovative thing, so the biggest challenge I was facing was to make this functionality simpler and easier to handle, because the product I was working on was in the very early stages of development. The feature, in a nutshell, was to create a simple text document where some interactive action items could be added.

Because a ton of apps are out there that allow you to create simple text documents, I decided to do a competitive analysis for this functionality. (I’ll explain this process in more detail later in the section “Five Easy Steps to Do a Competitive Analysis”.)

How To Find The Right Competitors?

Basically, there are two types of competitors: direct and indirect. As a UX designer, your role is to study the designs of these competitors.

Jaime Levy gives very good definitions of direct and indirect competitors in her book UX Strategy. You can learn more about competitive analysis (and types of competitors) in chapter 4 of the book, “Conducting Competitive Research”.

Types of competitors. (Large preview)

Direct competitors are the ones who offer the same, or a very similar, set of features to your current or future customers, which means they are solving a similar problem to the one you are trying to solve, for a customer base that you are targeting as well.

Indirect competitors are the ones who offers a similar set of features but to a different customer segment; or, they target your exact customer base without offering the exact same set of features, which means indirect competitors are solving the same problem but for a different customer base, or are solving the same problem but offer a different solution.

You can search for these types of competitors online (by doing a simple web search), or you can directly ask your current and potential customers what they are using already. You can also look for your direct and indirect competitors on websites such as Crunchbase and Product Hunt, and you can search for them in the Google Play and the iOS App Store.

Five Easy Steps To Do A Competitive Analysis

You can perform a competitive analysis for your existing or new product using the following five-step process.

5 steps to do a competitive analysis. (Large preview) 1. Define And Understand The Goals

Defining and understanding the goal is an integral part of any UX research process. You must define an accurate goal (or set of goals) for your research; otherwise, there is a chance you’ll get the wrong outcome.

Draft all of your goals right before starting your process. When defining your goals, consider the following questions: Why are you doing this competitive analysis? What kind of outcome do you expect? Will this analysis affect UX decisions?

Remember: When setting up goals for any kind of UX research, be as specific as possible.

I mentioned earlier that I recently performed a competitive analysis for a collaborative meeting note-taking feature, to be introduced in the app that I was developing for a client. The goals for my research were very general because innumerable apps all provide this type of functionality, and the product I was working on was in the very early stages of development.

Even though your research goals might be simple, make them as specific as possible, and write them all down. Writing down your goals will help you stay on the right track.

The goals for my analysis were more like questions for which I was trying to find the answers. Here is the list of goals I set for this research:

  • Which apps do users prefer for note-taking? And why do they prefer them?
    Goal: To find out the user’s behavior with these apps, their preferences and their comfort zone.
  • What is the working mechanism of these apps?
    Goal: To find how out competitors’ apps work, so that we can identify their pros and cons.
  • What are the “star” features of these apps?
    Goal: To identify functionalities that we were trying to introduce as well, to see whether they already exist and, if they exist, how exactly they were implemented.
  • How comfortable does a user feel when using these apps?
    Goal: To identify user loyalty and engagement in the apps of our competitors.
  • How does collaborative editing work in these competitive apps?
    Goal: To identify how collaborative-editing functionality works and to study its technical aspects.
  • What is the visual structure and user interface of these apps?
    Goal: To check the visual look and feel of the apps (user interface and interaction).
2. Find The Right Competitors

After setting the goals, go on a search and make a list of both direct and indirect competitors. It’s not necessary to analyze all of the competitors you find. The number is completely up to you. Some people suggest analyzing at least two to four competitors, while others suggest five to ten or more.

Finding the right competitors for my research wasn’t a hard task because I already knew many apps that provided similar features, but I still did a quick search on Google, and the results were a bit surprising — surprising because most of the apps I knew turned out to be more like indirect competitors to the app I was working on; and later, after a bit more searching, I also found the apps that were our direct competitors.

Putting each competitor in the right list is a very important part of competitive analysis because the features and functionality in your competitors’ apps are based on exactly what users of those apps want. Let’s assume you put one indirect competitor, XYZ, under the “direct competitors” list and start doing your analysis. While doing the research, you might find some impressive feature in XYZ’s app and decide to add a similar feature in your own app; then, later it turns out that the feature you added is not useful for the users you are targeting. You might end up wasting a lot of energy, time and money building something that is not at all useful. So, be careful when sorting your competitors.

For my research, the competitors were as follows:

  • Direct competitors
    Quip, Cisco Spark Meeting Notes, Workboard, Lucid Meeting, Less Meeting, MeetingSense, Minute-it, etc.
    • All of the apps above provide the same type of functionality, which we were trying to introduce for almost the same type of user base.
  • Indirect competitors
    Evernote, Google Keep, Google Docs, Microsoft Word, Microsoft OneNote and other traditional note-taking apps and pen-paper note-taking methods.
    • The user base for all of the above is not exactly different from the user base we were targeting, but most of the users we were targeting were using these apps because they were unaware of the more convenient ways to take meeting notes.
3. Make A Competitive Analysis Matrix

A competitive analysis matrix is not complex, just a simple spreadsheet. You can use Microsoft Excel, Google Sheets, Apple Numbers or any other tool you are comfortable with.

First, divide all competitors you’ve found into two groups (direct and indirect) and put them in a spreadsheet. Jamie Levy suggests making the following columns:

  1. competitor’s name,
  2. URL,
  3. login credentials,
  4. purpose,
  5. year founded.
Example of competitive analysis matrix spreadsheet from UX Strategy, Jaime Levy’s book. (Large preview)

I would recommend digging a bit deeper and adding a few more columns, such as for “unique features”, “pros and cons”, etc. It would help to summarize your analysis. It’s not necessary to set your columns exactly as mentioned above. You can modify the columns to your own research goals and needs.

For my analysis, I created only four columns. My competitive analysis matrix looked as follows:

  • Competitor name
    In this column, I put the names of all of the competitors.
  • URL
    These are website links or app download links for these competitors.
  • Features/comments
    In this column, I put all of my comments, some ”star” features I needed to focus on, and the pros and cons of the competitor. I color-coded the cells so that later I (or anyone viewing the matrix) could easily identify the difference between them. For example, I used light yellow for features, light purple for comments, green for pros and red for cons.
  • Screenshots/video links
    In this column, I put all of the screenshots and videos related to the features and comments mentioned in the third column. This way, it became very easy and quick to understand what a particular comment or feature was all about.
(Large preview) 4. Write A Summary And An Analysis

Once you are done with the analysis matrix spreadsheet, move on and create a summary of your findings. Be as specific as possible, and try to answer all of your questions while setting up a goal or during the overall process.

This will help you and your team members and stakeholders make the right design and UX decisions. This summary will also help you find new design and UX opportunities in the product you’re building.

In writing the summary and the presentation for the competitive analysis that I did for this collaborative note-taking app, the competitive analysis matrix helped me a lot. I drafted a document with all of the high-level takeaways from this analysis and answered all of the questions that were set as goals. For the presentation, I shared the document with the client, which helped both the client and me to finalize the features, the flows and the end requirements for the product.

5. Presentation

The last step of your competitive analysis is the presentation. It’s not a typical slideshow presentation — rather, just share all of the data and information you collected throughout the process with your teammates, stakeholders and/or clients.

Getting feedback from everywhere you can and being open to this feedback is a very important part of the designer’s workflow. So, share all of your finding with your teammates, stakeholders and clients, and ask for their opinion. You might find some missing points in your analysis or discover something new and exciting from someone’s feedback.

Conclusion

We live in a data-driven world, and we should build products, services and apps based on data, rather than our intuition (or guesswork).

As UX designers, we should go out there and collect as much data as possible before building a real product. This data will help us to create a solid product that users will want to use, rather than a product we want or imagine. These kinds of products are more likely to succeed in the market. Competitive analysis is one of the ways to get this data and to create a user-friendly product.

Finally, no matter what kind of product you are building or research you are conducting, always try to put yourself in the users’ shoes every now and then. This way, you will be able to identify the users’ struggles and ultimately deliver a better solution.

I hope this article has helped you plan and make your first competitive analysis for your next project!

Further Reading

If you want to become a better UX, interaction, visual (UI) or product designer, there are a lot of sources from which you can learn — articles, books, online courses. I often check the following few: Smashing Magazine, InVision blog, Interaction Design Foundation, NN Group and UX Mastery. These websites have a very good collection of articles on the topics of UI and UX design and UX research.

Here are some additional resources:

(mb, ra, al, yk, il)
Categories: Web Design

Building A Room Detector For IoT Devices On Mac OS

Wed, 08/29/2018 - 05:20
Building A Room Detector For IoT Devices On Mac OS Building A Room Detector For IoT Devices On Mac OS Alvin Wan 2018-08-29T14:20:53+02:00 2018-09-15T11:11:14+00:00

Knowing which room you’re in enables various IoT applications — from turning on the light to changing TV channels. So, how can we detect the moment you and your phone are in the kitchen, or bedroom, or living room? With today’s commodity hardware, there are a myriad of possibilities:

One solution is to equip each room with a bluetooth device. Once your phone is within range of a bluetooth device, your phone will know which room it is, based on the bluetooth device. However, maintaining an array of Bluetooth devices is significant overhead — from replacing batteries to replacing dysfunctional devices. Additionally, proximity to the Bluetooth device is not always the answer: if you’re in the living room, by the wall shared with the kitchen, your kitchen appliances should not start churning out food.

Another, albeit impractical, solution is to use GPS. However, keep in mind hat GPS works poorly indoors in which the multitude of walls, other signals, and other obstacles wreak havoc on GPS’s precision.

Our approach instead is to leverage all in-range WiFi networks — even the ones your phone is not connected to. Here is how: consider the strength of WiFi A in the kitchen; say it is 5. Since there is a wall between the kitchen and the bedroom, we can reasonably expect the strength of WiFi A in the bedroom to differ; say it is 2. We can exploit this difference to predict which room we’re in. What’s more: WiFi network B from our neighbor can only be detected from the living room but is effectively invisible from the kitchen. That makes prediction even easier. In sum, the list of all in-range WiFi gives us plentiful information.

This method has the distinct advantages of:

  1. not requiring more hardware;
  2. relying on more stable signals like WiFi;
  3. working well where other techniques such as GPS are weak.

The more walls the better, as the more disparate the WiFi network strengths, the easier the rooms are to classify. You will build a simple desktop app that collects data, learns from the data, and predicts which room you’re in at any given time.

Further Reading on SmashingMag: Prerequisites

For this tutorial, you will need a Mac OSX. Whereas the code can apply to any platform, we will only provide dependency installation instructions for Mac.

Sometimes we are a bit slow, and sometimes too fast, but we try our best with articles, printed books and webinars featuring techniques we all can use to improve our work. Smashing Members have a seasoned selection of front-end & UX techniques. No chit-chat or theory. Things that worked, in actual projects. Just sayin'! ;-)

Explore Smashing Membership ↬ Step 0: Setup Work Environment

Your desktop app will be written in NodeJS. However, to leverage more efficient computational libraries like numpy, the training and prediction code will be written in Python. To start, we will setup your environments and install dependencies. Create a new directory to house your project.

mkdir ~/riot

Navigate into the directory.

cd ~/riot

Use pip to install Python’s default virtual environment manager.

sudo pip install virtualenv

Create a Python3.6 virtual environment named riot.

virtualenv riot --python=python3.6

Activate the virtual environment.

source riot/bin/activate

Your prompt is now preceded by (riot). This indicates we have successfully entered the virtual environment. Install the following packages using pip:

  • numpy: An efficient, linear algebra library
  • scipy: A scientific computing library that implements popular machine learning models
pip install numpy==1.14.3 scipy ==1.1.0

With the working directory setup, we will start with a desktop app that records all WiFi networks in-range. These recordings will constitute training data for your machine learning model. Once we have data on hand, you will write a least squares classifier, trained on the WiFi signals collected earlier. Finally, we will use the least squares model to predict the room you’re in, based on the WiFi networks in range.

Step 1: Initial Desktop Application

In this step, we will create a new desktop application using Electron JS. To begin, we will instead the Node package manager npm and a download utility wget.

brew install npm wget

To begin, we will create a new Node project.

npm init

This prompts you for the package name and then the version number. Hit ENTER to accept the default name of riot and default version of 1.0.0.

package name: (riot) version: (1.0.0)

This prompts you for a project description. Add any non-empty description you would like. Below, the description is room detector

description: room detector

This prompts you for the entry point, or the main file to run the project from. Enter app.js.

entry point: (index.js) app.js

This prompts you for the test command and git repository. Hit ENTER to skip these fields for now.

test command: git repository:

This prompts you for keywords and author. Fill in any values you would like. Below, we use iot, wifi for keywords and use John Doe for the author.

keywords: iot,wifi author: John Doe

This prompts you for the license. Hit ENTER to accept the default value of ISC.

license: (ISC)

At this point, npm will prompt you with a summary of information so far. Your output should be similar to the following.

{ "name": "riot", "version": "1.0.0", "description": "room detector", "main": "app.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [ "iot", "wifi" ], "author": "John Doe", "license": "ISC" }

Hit ENTER to accept. npm then produces a package.json. List all files to double-check.

ls

This will output the only file in this directory, along with the virtual environment folder.

package.json riot

Install NodeJS dependencies for our project.

npm install electron --global # makes electron binary accessible globally npm install node-wifi --save

Start with main.js from Electron Quick Start, by downloading the file, using the below. The following -O argument renames main.js to app.js.

wget https://raw.githubusercontent.com/electron/electron-quick-start/master/main.js -O app.js

Open app.js in nano or your favorite text editor.

nano app.js

On line 12, change index.html to static/index.html, as we will create a directory static to contain all HTML templates.

function createWindow () { // Create the browser window. win = new BrowserWindow({width: 1200, height: 800}) // and load the index.html of the app. win.loadFile('static/index.html') // Open the DevTools.

Save your changes and exit the editor. Your file should match the source code of the app.js file. Now create a new directory to house our HTML templates.

mkdir static

Download a stylesheet created for this project.

wget https://raw.githubusercontent.com/alvinwan/riot/master/static/style.css?token=AB-ObfDtD46ANlqrObDanckTQJ2Q1Pyuks5bf79PwA%3D%3D -O static/style.css

Open static/index.html in nano or your favorite text editor. Start with the standard HTML structure.

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Riot | Room Detector</title> </head> <body> <main> </main> </body> </html>

Right after the title, link the Montserrat font linked by Google Fonts and stylesheet.

<title>Riot | Room Detector</title> <!-- start new code --> <link href="https://fonts.googleapis.com/css?family=Montserrat:400,700" rel="stylesheet"> <link href="style.css" rel="stylesheet"> <!-- end new code --> </head>

Between the main tags, add a slot for the predicted room name.

<main> <!-- start new code --> <p class="text">I believe you’re in the</p> <h1 class="title" id="predicted-room-name">(I dunno)</h1> <!-- end new code --> </main>

Your script should now match the following exactly. Exit the editor.

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Riot | Room Detector</title> <link href="https://fonts.googleapis.com/css?family=Montserrat:400,700" rel="stylesheet"> <link href="style.css" rel="stylesheet"> </head> <body> <main> <p class="text">I believe you’re in the</p> <h1 class="title" id="predicted-room-name">(I dunno)</h1> </main> </body> </html>

Now, amend the package file to contain a start command.

nano package.json

Right after line 7, add a start command that’s aliased to electron .. Make sure to add a comma to the end of the previous line.

"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "electron ." },

Save and exit. You are now ready to launch your desktop app in Electron JS. Use npm to launch your application.

npm start

Your desktop application should match the following.

Home page with “Add New Room” button available (Large preview)

This completes your starting desktop app. To exit, navigate back to your terminal and CTRL+C. In the next step, we will record wifi networks, and make the recording utility accessible through the desktop application UI.

Step 2: Record WiFi Networks

In this step, you will write a NodeJS script that records the strength and frequency of all in-range wifi networks. Create a directory for your scripts.

mkdir scripts

Open scripts/observe.js in nano or your favorite text editor.

nano scripts/observe.js

Import a NodeJS wifi utility and the filesystem object.

var wifi = require('node-wifi'); var fs = require('fs');

Define a record function that accepts a completion handler.

/** * Uses a recursive function for repeated scans, since scans are asynchronous. */ function record(n, completion, hook) { }

Inside the new function, initialize the wifi utility. Set iface to null to initialize to a random wifi interface, as this value is currently irrelevant.

function record(n, completion, hook) { wifi.init({ iface : null }); }

Define an array to contain your samples. Samples are training data we will use for our model. The samples in this particular tutorial are lists of in-range wifi networks and their associated strengths, frequencies, names etc.

function record(n, completion, hook) { ... samples = [] }

Define a recursive function startScan, which will asynchronously initiate wifi scans. Upon completion, the asynchronous wifi scan will then recursively invoke startScan.

function record(n, completion, hook) { ... function startScan(i) { wifi.scan(function(err, networks) { }); } startScan(n); }

In the wifi.scan callback, check for errors or empty lists of networks and restart the scan if so.

wifi.scan(function(err, networks) { if (err || networks.length == 0) { startScan(i); return } });

Add the recursive function’s base case, which invokes the completion handler.

wifi.scan(function(err, networks) { ... if (i <= 0) { return completion({samples: samples}); } });

Output a progress update, append to the list of samples, and make the recursive call.

wifi.scan(function(err, networks) { ... hook(n-i+1, networks); samples.push(networks); startScan(i-1); });

At the end of your file, invoke the record function with a callback that saves samples to a file on disk.

function record(completion) { ... } function cli() { record(1, function(data) { fs.writeFile('samples.json', JSON.stringify(data), 'utf8', function() {}); }, function(i, networks) { console.log(" * [INFO] Collected sample " + (21-i) + " with " + networks.length + " networks"); }) } cli();

Double check that your file matches the following:

var wifi = require('node-wifi'); var fs = require('fs'); /** * Uses a recursive function for repeated scans, since scans are asynchronous. */ function record(n, completion, hook) { wifi.init({ iface : null // network interface, choose a random wifi interface if set to null }); samples = [] function startScan(i) { wifi.scan(function(err, networks) { if (err || networks.length == 0) { startScan(i); return } if (i <= 0) { return completion({samples: samples}); } hook(n-i+1, networks); samples.push(networks); startScan(i-1); }); } startScan(n); } function cli() { record(1, function(data) { fs.writeFile('samples.json', JSON.stringify(data), 'utf8', function() {}); }, function(i, networks) { console.log(" * [INFO] Collected sample " + i + " with " + networks.length + " networks"); }) } cli();

Save and exit. Run the script.

node scripts/observe.js

Your output will match the following, with variable numbers of networks.

* [INFO] Collected sample 1 with 39 networks

Examine the samples that were just collected. Pipe to json_pp to pretty print the JSON and pipe to head to view the first 16 lines.

cat samples.json | json_pp | head -16

The below is example output for a 2.4 GHz network.

{ "samples": [ [ { "mac": "64:0f:28:79:9a:29", "bssid": "64:0f:28:79:9a:29", "ssid": "SMASHINGMAGAZINEROCKS", "channel": 4, "frequency": 2427, "signal_level": "-91", "security": "WPA WPA2", "security_flags": [ "(PSK/AES,TKIP/TKIP)", "(PSK/AES,TKIP/TKIP)" ] },

This concludes your NodeJS wifi-scanning script. This allows us to view all in-range WiFi networks. In the next step, you will make this script accessible from the desktop app.

Step 3: Connect Scan Script To Desktop App

In this step, you will first add a button to the desktop app to trigger the script with. Then, you will update the desktop app UI with the script’s progress.

Open static/index.html.

nano static/index.html

Insert the “Add” button, as shown below.

<h1 class="title" id="predicted-room-name">(I dunno)</h1> <!-- start new code --> <div class="buttons"> <a href="add.html" class="button">Add new room</a> </div> <!-- end new code --> </main>

Save and exit. Open static/add.html.

nano static/add.html

Paste the following content.

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Riot | Add New Room</title> <link href="https://fonts.googleapis.com/css?family=Montserrat:400,700" rel="stylesheet"> <link href="style.css" rel="stylesheet"> </head> <body> <main> <h1 class="title" id="add-title">0</h1> <p class="subtitle">of <span>20</span> samples needed. Feel free to move around the room.</p> <input type="text" id="add-room-name" class="text-field" placeholder="(room name)"> <div class="buttons"> <a href="#" id="start-recording" class="button">Start recording</a> <a href="index.html" class="button light">Cancel</a> </div> <p class="text" id="add-status" style="display:none"></p> </main> <script> require('../scripts/observe.js') </script> </body> </html>

Save and exit. Reopen scripts/observe.js.

nano scripts/observe.js

Beneath the cli function, define a new ui function.

function cli() { ... } // start new code function ui() { } // end new code cli();

Update the desktop app status to indicate the function has started running.

function ui() { var room_name = document.querySelector('#add-room-name').value; var status = document.querySelector('#add-status'); var number = document.querySelector('#add-title'); status.style.display = "block" status.innerHTML = "Listening for wifi..." }

Partition the data into training and validation data sets.

function ui() { ... function completion(data) { train_data = {samples: data['samples'].slice(0, 15)} test_data = {samples: data['samples'].slice(15)} var train_json = JSON.stringify(train_data); var test_json = JSON.stringify(test_data); } }

Still within the completion callback, write both datasets to disk.

function ui() { ... function completion(data) { ... fs.writeFile('data/' + room_name + '_train.json', train_json, 'utf8', function() {}); fs.writeFile('data/' + room_name + '_test.json', test_json, 'utf8', function() {}); console.log(" * [INFO] Done") status.innerHTML = "Done." } }

Invoke record with the appropriate callbacks to record 20 samples and save the samples to disk.

function ui() { ... function completion(data) { ... } record(20, completion, function(i, networks) { number.innerHTML = i console.log(" * [INFO] Collected sample " + i + " with " + networks.length + " networks") }) }

Finally, invoke the cli and ui functions where appropriate. Start by deleting the cli(); call at the bottom of the file.

function ui() { ... } cli(); // remove me

Check if the document object is globally accessible. If not, the script is being run from the command line. In this case, invoke the cli function. If it is, the script is loaded from within the desktop app. In this case, bind the click listener to the ui function.

if (typeof document == 'undefined') { cli(); } else { document.querySelector('#start-recording').addEventListener('click', ui) }

Save and exit. Create a directory to hold our data.

mkdir data

Launch the desktop app.

npm start

You will see the following homepage. Click on “Add room”.

(Large preview)

You will see the following form. Type in a name for the room. Remember this name, as we will use this later on. Our example will be bedroom.

“Add New Room” page on load (Large preview)

Click “Start recording,” and you will see the following status “Listening for wifi…”.

“Add New Room” starting recording (Large Preview)

Once all 20 samples are recorded, your app will match the following. The status will read “Done.”

“Add New Room” page after recording is complete (Large preview)

Click on the misnamed “Cancel” to return to the homepage, which matches the following.

“Add New Room” page after recording is complete (Large preview)

We can now scan wifi networks from the desktop UI, which will save all recorded samples to files on disk. Next, we will train an out-of-box machine learning algorithm-least squares on the data you have collected.

Step 4: Write Python Training Script

In this step, we will write a training script in Python. Create a directory for your training utilities.

mkdir model

Open model/train.py

nano model/train.py

At the top of your file, import the numpy computational library and scipy for its least squares model.

import numpy as np from scipy.linalg import lstsq import json import sys

The next three utilities will handle loading and setting up data from the files on disk. Start by adding a utility function that flattens nested lists. You will use this to flatten a list of list of samples.

import sys def flatten(list_of_lists): """Flatten a list of lists to make a list. >>> flatten([[1], [2], [3, 4]]) [1, 2, 3, 4] """ return sum(list_of_lists, [])

Add a second utility that loads samples from the specified files. This method abstracts away the fact that samples are spread out across multiple files, returning just a single generator for all samples. For each of the samples, the label is the index of the file. e.g., If you call get_all_samples('a.json', 'b.json'), all samples in a.json will have label 0 and all samples in b.json will have label 1.

def get_all_samples(paths): """Load all samples from JSON files.""" for label, path in enumerate(paths): with open(path) as f: for sample in json.load(f)['samples']: signal_levels = [ network['signal_level'].replace('RSSI', '') or 0 for network in sample] yield [network['mac'] for network in sample], signal_levels, label

Next, add a utility that encodes the samples using a bag-of-words-esque model. Here is an example: Assume we collect two samples.

  1. wifi network A at strength 10 and wifi network B at strength 15
  2. wifi network B at strength 20 and wifi network C at strength 25.

This function will produce a list of three numbers for each of the samples: the first value is the strength of wifi network A, the second for network B, and the third for C. In effect, the format is [A, B, C].

  1. [10, 15, 0]
  2. [0, 20, 25]
def bag_of_words(all_networks, all_strengths, ordering): """Apply bag-of-words encoding to categorical variables. >>> samples = bag_of_words( ... [['a', 'b'], ['b', 'c'], ['a', 'c']], ... [[1, 2], [2, 3], [1, 3]], ... ['a', 'b', 'c']) >>> next(samples) [1, 2, 0] >>> next(samples) [0, 2, 3] """ for networks, strengths in zip(all_networks, all_strengths): yield [strengths[networks.index(network)] if network in networks else 0 for network in ordering]

Using all three utilities above, we synthesize a collection of samples and their labels. Gather all samples and labels using get_all_samples. Define a consistent format ordering to one-hot encode all samples, then apply one_hot encoding to samples. Finally, construct the data and label matrices X and Y respectively.

def create_dataset(classpaths, ordering=None): """Create dataset from a list of paths to JSON files.""" networks, strengths, labels = zip(*get_all_samples(classpaths)) if ordering is None: ordering = list(sorted(set(flatten(networks)))) X = np.array(list(bag_of_words(networks, strengths, ordering))).astype(np.float64) Y = np.array(list(labels)).astype(np.int) return X, Y, ordering

These functions complete the data pipeline. Next, we abstract away model prediction and evaluation. Start by defining the prediction method. The first function normalizes our model outputs, so that the sum of all values totals to 1 and that all values are non-negative; this ensures that the output is a valid probability distribution. The second evaluates the model.

def softmax(x): """Convert one-hotted outputs into probability distribution""" x = np.exp(x) return x / np.sum(x) def predict(X, w): """Predict using model parameters""" return np.argmax(softmax(X.dot(w)), axis=1)

Next, evaluate the model’s accuracy. The first line runs prediction using the model. The second counts the numbers of times both predicted and true values agree, then normalizes by the total number of samples.

def evaluate(X, Y, w): """Evaluate model w on samples X and labels Y.""" Y_pred = predict(X, w) accuracy = (Y == Y_pred).sum() / X.shape[0] return accuracy

This concludes our prediction and evaluation utilities. After these utilities, define a main function that will collect the dataset, train, and evaluate. Start by reading the list of arguments from the command line sys.argv; these are the rooms to include in training. Then create a large dataset from all of the specified rooms.

def main(): classes = sys.argv[1:] train_paths = sorted(['data/{}_train.json'.format(name) for name in classes]) test_paths = sorted(['data/{}_test.json'.format(name) for name in classes]) X_train, Y_train, ordering = create_dataset(train_paths) X_test, Y_test, _ = create_dataset(test_paths, ordering=ordering)

Apply one-hot encoding to the labels. A one-hot encoding is similar to the bag-of-words model above; we use this encoding to handle categorical variables. Say we have 3 possible labels. Instead of labelling 1, 2, or 3, we label the data with [1, 0, 0], [0, 1, 0], or [0, 0, 1]. For this tutorial, we will spare the explanation for why one-hot encoding is important. Train the model, and evaluate on both the train and validation sets.

def main(): ... X_test, Y_test, _ = create_dataset(test_paths, ordering=ordering) Y_train_oh = np.eye(len(classes))[Y_train] w, _, _, _ = lstsq(X_train, Y_train_oh) train_accuracy = evaluate(X_train, Y_train, w) test_accuracy = evaluate(X_test, Y_test, w)

Print both accuracies, and save the model to disk.

def main(): ... print('Train accuracy ({}%), Validation accuracy ({}%)'.format(train_accuracy*100, test_accuracy*100)) np.save('w.npy', w) np.save('ordering.npy', np.array(ordering)) sys.stdout.flush()

At the end of the file, run the main function.

if __name__ == '__main__': main()

Save and exit. Double check that your file matches the following:

import numpy as np from scipy.linalg import lstsq import json import sys def flatten(list_of_lists): """Flatten a list of lists to make a list. >>> flatten([[1], [2], [3, 4]]) [1, 2, 3, 4] """ return sum(list_of_lists, []) def get_all_samples(paths): """Load all samples from JSON files.""" for label, path in enumerate(paths): with open(path) as f: for sample in json.load(f)['samples']: signal_levels = [ network['signal_level'].replace('RSSI', '') or 0 for network in sample] yield [network['mac'] for network in sample], signal_levels, label def bag_of_words(all_networks, all_strengths, ordering): """Apply bag-of-words encoding to categorical variables. >>> samples = bag_of_words( ... [['a', 'b'], ['b', 'c'], ['a', 'c']], ... [[1, 2], [2, 3], [1, 3]], ... ['a', 'b', 'c']) >>> next(samples) [1, 2, 0] >>> next(samples) [0, 2, 3] """ for networks, strengths in zip(all_networks, all_strengths): yield [int(strengths[networks.index(network)]) if network in networks else 0 for network in ordering] def create_dataset(classpaths, ordering=None): """Create dataset from a list of paths to JSON files.""" networks, strengths, labels = zip(*get_all_samples(classpaths)) if ordering is None: ordering = list(sorted(set(flatten(networks)))) X = np.array(list(bag_of_words(networks, strengths, ordering))).astype(np.float64) Y = np.array(list(labels)).astype(np.int) return X, Y, ordering def softmax(x): """Convert one-hotted outputs into probability distribution""" x = np.exp(x) return x / np.sum(x) def predict(X, w): """Predict using model parameters""" return np.argmax(softmax(X.dot(w)), axis=1) def evaluate(X, Y, w): """Evaluate model w on samples X and labels Y.""" Y_pred = predict(X, w) accuracy = (Y == Y_pred).sum() / X.shape[0] return accuracy def main(): classes = sys.argv[1:] train_paths = sorted(['data/{}_train.json'.format(name) for name in classes]) test_paths = sorted(['data/{}_test.json'.format(name) for name in classes]) X_train, Y_train, ordering = create_dataset(train_paths) X_test, Y_test, _ = create_dataset(test_paths, ordering=ordering) Y_train_oh = np.eye(len(classes))[Y_train] w, _, _, _ = lstsq(X_train, Y_train_oh) train_accuracy = evaluate(X_train, Y_train, w) validation_accuracy = evaluate(X_test, Y_test, w) print('Train accuracy ({}%), Validation accuracy ({}%)'.format(train_accuracy*100, validation_accuracy*100)) np.save('w.npy', w) np.save('ordering.npy', np.array(ordering)) sys.stdout.flush() if __name__ == '__main__': main()

Save and exit. Recall the room name used above when recording the 20 samples. Use that name instead of bedroom below. Our example is bedroom. We use -W ignore to ignore warnings from a LAPACK bug.

python -W ignore model/train.py bedroom

Since we’ve only collected training samples for one room, you should see 100% training and validation accuracies.

Train accuracy (100.0%), Validation accuracy (100.0%)

Next, we will link this training script to the desktop app.

Step 5: Link Train Script

In this step, we will automatically retrain the model whenever the user collects a new batch of samples. Open scripts/observe.js.

nano scripts/observe.js

Right after the fs import, import the child process spawner and utilities.

var fs = require('fs'); // start new code const spawn = require("child_process").spawn; var utils = require('./utils.js');

In the ui function, add the following call to retrain at the end of the completion handler.

function ui() { ... function completion() { ... retrain((data) => { var status = document.querySelector('#add-status'); accuracies = data.toString().split('\n')[0]; status.innerHTML = "Retraining succeeded: " + accuracies }); } ... }

After the ui function, add the following retrain function. This spawns a child process that will run the python script. Upon completion, the process calls a completion handler. Upon failure, it will log the error message.

function ui() { .. } function retrain(completion) { var filenames = utils.get_filenames() const pythonProcess = spawn('python', ["./model/train.py"].concat(filenames)); pythonProcess.stdout.on('data', completion); pythonProcess.stderr.on('data', (data) => { console.log(" * [ERROR] " + data.toString()) }) }

Save and exit. Open scripts/utils.js.

nano scripts/utils.js

Add the following utility for fetching all datasets in data/.

var fs = require('fs'); module.exports = { get_filenames: get_filenames } function get_filenames() { filenames = new Set([]); fs.readdirSync("data/").forEach(function(filename) { filenames.add(filename.replace('_train', '').replace('_test', '').replace('.json', '' )) }); filenames = Array.from(filenames.values()) filenames.sort(); filenames.splice(filenames.indexOf('.DS_Store'), 1) return filenames }

Save and exit. For the conclusion of this step, physically move to a new location. There ideally should be a wall between your original location and your new location. The more barriers, the better your desktop app will work.

Once again, run your desktop app.

npm start

Just as before, run the training script. Click on “Add room”.

Home page with “Add New Room” button available (Large preview)

Type in a room name that is different from your first room’s. We will use living room.

“Add New Room” page on load (Large preview)

Click “Start recording,” and you will see the following status “Listening for wifi…”.

“Add New Room” starting recording for second room (Large preview)

Once all 20 samples are recorded, your app will match the following. The status will read “Done. Retraining model…”

“Add New Room” page after recording for second room complete (Large preview)

In the next step, we will use this retrained model to predict the room you’re in, on the fly.

Step 6: Write Python Evaluation Script

In this step, we will load the pretrained model parameters, scan for wifi networks, and predict the room based on the scan.

Open model/eval.py.

nano model/eval.py

Import libraries used and defined in our last script.

import numpy as np import sys import json import os import json from train import predict from train import softmax from train import create_dataset from train import evaluate

Define a utility to extract the names of all datasets. This function assumes that all datasets are stored in data/ as <dataset>_train.json and <dataset>_test.json.

from train import evaluate def get_datasets(): """Extract dataset names.""" return sorted(list({path.split('_')[0] for path in os.listdir('./data') if '.DS' not in path}))

Define the main function, and start by loading parameters saved from the training script.

def get_datasets(): ... def main(): w = np.load('w.npy') ordering = np.load('ordering.npy')

Create the dataset and predict.

def main(): ... classpaths = [sys.argv[1]] X, _, _ = create_dataset(classpaths, ordering) y = np.asscalar(predict(X, w))

Compute a confidence score based on the difference between the top two probabilities.

def main(): ... sorted_y = sorted(softmax(X.dot(w)).flatten()) confidence = 1 if len(sorted_y) > 1: confidence = round(sorted_y[-1] - sorted_y[-2], 2)

Finally, extract the category and print the result. To conclude the script, invoke the main function.

def main() ... category = get_datasets()[y] print(json.dumps({"category": category, "confidence": confidence})) if __name__ == '__main__': main()

Save and exit. Double check your code matches the following (source code):

import numpy as np import sys import json import os import json from train import predict from train import softmax from train import create_dataset from train import evaluate def get_datasets(): """Extract dataset names.""" return sorted(list({path.split('_')[0] for path in os.listdir('./data') if '.DS' not in path})) def main(): w = np.load('w.npy') ordering = np.load('ordering.npy') classpaths = [sys.argv[1]] X, _, _ = create_dataset(classpaths, ordering) y = np.asscalar(predict(X, w)) sorted_y = sorted(softmax(X.dot(w)).flatten()) confidence = 1 if len(sorted_y) > 1: confidence = round(sorted_y[-1] - sorted_y[-2], 2) category = get_datasets()[y] print(json.dumps({"category": category, "confidence": confidence})) if __name__ == '__main__': main()

Next, we will connect this evaluation script to the desktop app. The desktop app will continuously run wifi scans and update the UI with the predicted room.

Step 7: Connect Evaluation To Desktop App

In this step, we will update the UI with a “confidence” display. Then, the associated NodeJS script will continuously run scans and predictions, updating the UI accordingly.

Open static/index.html.

nano static/index.html

Add a line for confidence right after the title and before the buttons.

<h1 class="title" id="predicted-room-name">(I dunno)</h1> <!-- start new code --> <p class="subtitle">with <span id="predicted-confidence">0%</span> confidence</p> <!-- end new code --> <div class="buttons">

Right after main but before the end of the body, add a new script predict.js.

</main> <!-- start new code --> <script> require('../scripts/predict.js') </script> <!-- end new code --> </body>

Save and exit. Open scripts/predict.js.

nano scripts/predict.js

Import the needed NodeJS utilities for the filesystem, utilities, and child process spawner.

var fs = require('fs'); var utils = require('./utils'); const spawn = require("child_process").spawn;

Define a predict function which invokes a separate node process to detect wifi networks and a separate Python process to predict the room.

function predict(completion) { const nodeProcess = spawn('node', ["scripts/observe.js"]); const pythonProcess = spawn('python', ["-W", "ignore", "./model/eval.py", "samples.json"]); }

After both processes have spawned, add callbacks to the Python process for both successes and errors. The success callback logs information, invokes the completion callback, and updates the UI with the prediction and confidence. The error callback logs the error.

function predict(completion) { ... pythonProcess.stdout.on('data', (data) => { information = JSON.parse(data.toString()); console.log(" * [INFO] Room '" + information.category + "' with confidence '" + information.confidence + "'") completion() if (typeof document != "undefined") { document.querySelector('#predicted-room-name').innerHTML = information.category document.querySelector('#predicted-confidence').innerHTML = information.confidence } }); pythonProcess.stderr.on('data', (data) => { console.log(data.toString()); }) }

Define a main function to invoke the predict function recursively, forever.

function main() { f = function() { predict(f) } predict(f) } main();

One last time, open the desktop app to see the live prediction.

npm start

Approximately every second, a scan will be completed and the interface will be updated with the latest confidence and predicted room. Congratulations; you have completed a simple room detector based on all in-range WiFi networks.

Recording 20 samples inside the room and another 20 out in the hallway. Upon walking back inside, the script correctly predicts “hallway” then “bedroom.” (Large preview) Conclusion

In this tutorial, we created a solution using only your desktop to detect your location within a building. We built a simple desktop app using Electron JS and applied a simple machine learning method on all in-range WiFi networks. This paves the way for Internet-of-things applications without the need for arrays of devices that are costly to maintain (cost not in terms of money but in terms of time and development).

Note: You can see the source code in its entirety on Github.

With time, you may find that this least squares does not perform spectacularly in fact. Try finding two locations within a single room, or stand in doorways. Least squares will be large unable to distinguish between edge cases. Can we do better? It turns out that we can, and in future lessons, we will leverage other techniques and the fundamentals of machine learning to better performance. This tutorial serves as a quick test bed for experiments to come.

(ra, il)
Categories: Web Design

Best Practices For Mobile Form Design

Tue, 08/28/2018 - 07:00
Best Practices For Mobile Form Design Best Practices For Mobile Form Design Nick Babich 2018-08-28T16:00:09+02:00 2018-09-15T11:11:14+00:00

(This article is kindly sponsored by Adobe.) Forms are the linchpin of all mobile interactions; it stands between the person and what they're looking for. Every day, we use forms for essential online activities. Recall the last time you bought a ticket, booked a hotel room or made a purchase online — most probably those interactions contained a step with filling out a form.

Forms are just a means to an end. Users should be able to complete them quickly and without confusion. In this article, you’ll learn practical techniques that will help you design an effective form.

What Makes For An Effective Form

The primary goal with every form is completion. Two factors have a major impact on completion rate:

  • Perception of complexity
    The first thing users do when they see a new form is estimate how much time is required to complete it. Users do this by scanning the form. Perception plays a crucial role in the process of estimation. The more complex a form looks, the more likely users will abandon the process.
  • Interaction cost
    Interaction cost is the sum of efforts — both cognitive and physical — that the users put into interacting with an interface in order to reach their goal. Interaction cost has a direct connection with form usability. The more effort users have to make to complete a form, the less usable the form is. A high interaction cost could be the result of data that is difficult to input, an inability to understand the meaning of some questions, or confusion about error messages.
The Components Of Forms

A typical form has the following five components:

  • Input fields
    These include text fields, password fields, checkboxes, radio buttons, sliders and any other fields designed for user input.
  • Field labels
    These tell users what the corresponding input fields mean.
  • Structure
    This includes the order of fields, the form’s appearance on the page, and the logical connections between different fields.
  • Action buttons
    The form will have at least one call to action (the button that triggers data submission).
  • Feedback
    Feedback notifies the user about the result of an operation. Feedback can be positive (for example, indicating that the form was submitted successfully) or negative (saying something like, “The number you’ve provided is incorrect”).

This article covers many aspects related to structure, input fields, labels, action buttons and validation. Most points mentioned in this article have visual do and don’t examples; all such examples were created using Adobe XD.

Input Fields

When it comes to form design, the most important thing a designer can do is to minimize the need for typing. Reducing input effort is essential. Designers can achieve this goal by focusing on form field design.

Minimize The Total Number Of Fields

Every field you ask users to fill out requires some effort. The more effort is needed to fill out a form, the less likely users will complete the form. That’s why the foundational rule of form design is shorter is better — get rid of all inessential fields.

Baymard Institute analyzed checkout forms and found that a too long or too complicated checkout process is one of the top reasons for abandonment during checkout. The study found that the average checkout contains almost 15 form fields. Most online services could reduce the number of fields displayed by default by 20 to 60%.

Top reasons for abandonment during checkout. (Image: Baymard Institute) (Large preview)

Many designers are familiar with the “less is more” rule; still, they ask additional questions in an attempt to gather more data about their users. It might be tempting to collect more data about your users during the initial signup, but resist that temptation. Think about it this way: With every additional field you add to your form, you increase the chance of losing a prospective user. Is the information you gain from a field worth losing new users? Remember that, as long as you’ve collected a user’s contact information, you can always follow up with a request for more data.

Clearly Distinguish All Optional Fields

Before optimizing optional fields, ask yourself whether you really need to include them in your form. Think about what information you really need, not what you want. Ideally, the number of optional fields in your form should be zero.

If after a brainstorming session, you still want to include a few optional questions in your form, make it clear for users that those fields are optional:

  • Mark optional fields instead of mandatory ones.
    If you ask as little as possible, then the vast majority of fields in your form will be mandatory. Therefore, mark only those fields in the minority. For instance, if five out of six fields are mandatory, then it makes sense to mark only one field as optional.
  • Use the “Optional” label to denote optional fields.
    Avoid using the asterisk (*) to mean “optional.” Not all users will associate the asterisk with optional information, and some users will be confused by the meaning (an asterisk is often used to denote mandatory fields).
Clearly distinguish all optional fields. (Large preview) Size Fields Accordingly

When possible, use field length as an affordance. The length of an input field should be in proportion to the amount of information expected in the field. The size of the field will act as a visual constraint — the user will know how much text is expected to be entered just by looking at the field. Generally, fields such as ones for area codes and house numbers should be shorter than ones for street addresses.

The size of a field is used as a visual constraint. (Large preview) Offer Field Focus

Auto-focus the first input field in your form. Auto-focusing a field gives the user an indication and a starting point, so that they are able to quickly start filling out the form. By doing that, you reduce the interaction cost — saving the user one unnecessary tap.

Make the active input field prominent and focused. The field focus itself should be crystal clear — users should be able to understand at a glance where the focus is. It could be an accented border color or a fade-in of the box.

Amazon puts strong visual focus on the input field. (Large preview) Don’t Ask Users To Repeat Their Email Address

The reason why an extra field for the email address is so popular among product developers is apparent: Every company wants to minimize the risk of hard bounces (non-deliverables caused by invalid email addresses). Unfortunately, following this approach doesn’t guarantee that you’ll get a valid address. Users often copy and paste their address from one field to another.

Avoid asking users to retype their email address. (Large preview) Provide “Show Password” Option

Duplicating the password input field is another common mistake among product designers. Designers follow this approach because they believe it will prevent users from mistyping a password. In reality, a second field for a password not only increases interaction cost, but also doesn't guarantee that users will proceed without mistakes. Because users don’t see what they’ve entered in the field, they can make the same mistake twice (in both fields) and will face a problem when they try to log in using a password. As Jakob Nielsen summarized:

Usability suffers when users type in passwords and the only feedback they get is a row of bullets. Typically, masking passwords doesn’t even increase security, but it does cost you business due to login failures.

Instead of duplicating the password field, provide an option that allows users to view the password they have chosen to create. Have an icon or checkbox that unmasks the password when clicked. A password preview can be an opportunity for users to check their data before sending.

Not being able to see what you're typing is a huge issue. Providing a 'Show password' option next to the password field will help to solve this problem. (Large preview) Don’t Slice Data Fields

Do not slice fields when asking for a full name, phone number or date of birth. Sliced fields force the user to make additional taps to move to the next field. For fields that require some formatting (such as phone numbers or a date of birth), it’s also better to have a single field paired with clear formatting rules as its placeholder.

Avoid splitting input fields; don’t make people jump between fields. Instead of asking for a first name and last name in two separate fields, have a single 'Full name' field. (Large preview) Avoid Dropdown Menus

Luke Wroblewski famously said that dropdowns should be the UI of last resort. Dropdowns are especially bad for mobile because collapsed elements make the process of data input harder on a small screen: Placing options in a dropdown requires two taps and hides the options.

If you’re using a dropdown for selection of options, consider replacing it with radio buttons. They will make all options glanceable and also reduce the interaction cost — users can tap on the item and select at once.

(Large preview) Use Placeholders And Masked Input

Formatting uncertainty is one of the most significant problems of form design. This problem has a direct connection with form abandonment — when users are uncertain of the format in which they should provide data, they can quickly abandon the form. There are a few things you can do to make the format clear.

Placeholder Text

The text in an input field can tell users what content is expected. Placeholder text is not required for simple fields such as “Full name”, but it can be extremely valuable for fields that require data in a specific format. For example, if you design search functionality for tracking a parcel, it would be good to provide a sample tracking number as a placeholder for the tracking-number field.

(Large preview)

It’s vital that your form should have a clear visual distinction between the placeholder text and the actual value entered by the user. In other words, placeholder text shouldn’t look like a preset value. Without clear visual distinction, users might think that the fields with placeholders already have values.

Masked Input

Field masking is a technique that helps users format inputted text. Many designers confuse field masking with placeholder text — they are not the same thing. Unlike placeholders, which are basically static text, masks automatically format the data provided by the user. In the example below, the parentheses, spaces and dashes appear on the screen automatically as a phone number is entered.

Masked input also makes it easy for users to validate information. When a phone number is displayed in chunks, it makes it easier to find and correct a typo.

Masked input for a phone number. (Image: Josh Morony) Provide Matching Keyboard

Mobile users appreciate apps and websites that provide an appropriate keyboard for the field. This feature prevents them from doing additional actions. For example, when users need to enter a credit card number, your app should only display the dialpad. It’s essential to implement keyboard matching consistently throughout the app (all forms in your app should have this feature).

Set HTML input types to show the correct keypad. Seven input types are relevant to form design:

  • input type="text" displays the mobile device’s normal keyboard.
  • input type="email" displays the normal keyboard and '@' and '.com'.
  • input type="tel" displays the numeric 0 to 9 keypad.
  • input type="number" displays a keyboard with numbers and symbols.
  • input type="date" displays the mobile device’s date selector.
  • input type="datetime" displays the mobile device’s date and time selector.
  • input type="month" displays the mobile device’s month and year selector.
When users tap into a field with credit card number, they should see a numerical dialpad — all numbers, no letters. (Large preview) Use A Slider When Asking For A Specific Range

Many forms ask users to provide a range of values (for example, a price range, distance range, etc.). Instead of using two separate fields, “from” and “to”, for that purpose, use a slider to allow users to specify the range with a thumb interaction.

Sliders are good for touch interfaces because they allow users to specify a range without typing. (Large preview) Clearly Explain Why You’re Asking For Sensitive Information

People are increasingly concerned about privacy and information security. When users see a request for information they consider as private, they might think, “Hm, why do they need this?” If your form asks users for sensitive information, make sure to explain why you need it. You can do that by adding support text below relevant fields. As a rule of thumb, the explanation text shouldn’t exceed 100 characters.

A request for a phone number in a booking form might confuse users. Explain why you are asking for it. (Large preview) Be Careful With Static Defaults

Unlike smart defaults, which are calculated by the system based on the information the system has about users, static defaults are preset values in forms that are the same for all users. Avoid static defaults unless you believe a significant portion of your users (say, 95%) would select those values — particularly for required fields. Why? Because you’re likely to introduce errors — people scan forms quickly, and they won’t spend extra time parsing all of the questions; instead, they’ll simply skip the field, assuming it already has a value.

Protect User Data

Jef Raskin once said, “The system should treat all user input as sacred.” This is absolutely true for forms. It’s great when you start filling in a web form and then accidentally refresh the page but the data remains in the fields. Tools such as Garlic.js help you to persist a form’s values locally until the form is submitted. This way, users won’t lose any precious data if they accidentally close the tab or browser.

Automate Actions

If you want to make the process of data input as smooth as possible, it's not enough to minimize the number of input fields — you should also pay attention to the user effort required for the data input. Typing has a high interaction cost — it’s error-prone and time-consuming, even with a physical keyboard. But when it comes to mobile screens, it becomes even more critical. More typing increases the user’s chance of making errors. Strive to prevent unnecessary typing, because it will improve user satisfaction and decrease error rates.

Here are a few things you can do to achieve this goal:

Autocomplete

Most users experience autocompletion when typing a question in Google’s search box. Google provides users with a list of suggestions related to what the user has typed in the field. The same mechanism can be applied to form design. For example, a form could autocomplete an email address.

This form suggests the email host and saves users from typing a complete address. (Image: GitHub) Autocapitalize

Autocapitalizing makes the first letter a capital automatically. This feature is excellent for fields like names and street addresses, but avoid it for password fields.

Autocorrect

Autocorrection modifies words that appear to be misspelled. Turn this feature off for unique fields, such as names, addresses, etc.

Auto-filling of personal details

Typing an address is often the most cumbersome part of any online signup form. Make this task easier by using the browser function to fill the field based on previously entered values. According to Google’s research, auto-filling helps people fill out forms 30% faster.

Address prefill. Image: Google Use The Mobile Device’s Native Features To Simplify Data Input

Modern mobile devices are sophisticated devices that have a ton of amazing capabilities. Designers can use a device’s native features (such as camera or geolocation) to streamline the task of inputting data.

Below are just a few tips on how to make use of sensors and device hardware.

Location Services

It’s possible to preselect the user’s country based on their geolocation data. But sometimes prefilling a full address can be problematic due to accuracy issues. Google’s Places API can help solve this problem. It uses both geolocation and address prefilling to provide accurate suggestions based on the user’s exact location.

Address lookup using Google Places API. (Image: Chromatic HQ) (Large preview)

Using location services, it’s also possible to provide smart defaults. For example, for a “Find a flight” form, it’s possible to prefill the “From” field with the nearest airport to the user based on the user’s geolocation.

Biometric Authorization

The biggest problem of using a text password today is that most people forget passwords. 82% of people can’t remember their passwords, and 5 to 10% of sessions require users to reset a password. Password recovery is a big deal in e-commerce. 75% of users wouldn't complete a purchase if they had to attempt to recover their password while checking out.

The future of passwords is no passwords. Even today, mobile developers can take advantage of biometric technologies. Users shouldn’t need to type a password; they should be able to use biometric readers for authentication — signing in using a fingerprint or face scanning.

eBay took advantage of the biometrics functionality on smartphones. Users can use their thumbprint to login into their eBay account. (Large preview) Camera

If your form asks users to provide credit card details or information from their driver’s license, it’s possible to simplify the process of data input by using the camera as a scanner. Provide an option to take a photo of the card and fill out all details automatically.

Let users scan their identity card, instead of having to fill out their credit card information manually. (Image: blinkid)

But remember that no matter how good your app fills out the fields, it’s essential to leave them available for editing. Users should be able to modify the fields whenever they want.

Voice

Voice-controlled devices, such as Apple HomePod, Google Home and Amazon Echo, are actively encroaching on the market. The number of people who prefer to use voice for common operations has grown significantly. According to ComScore, 50% of all searches will be voice searches by 2020.

How people in the US use smart speakers (according to comScore) (Large preview)

As users get more comfortable and confident using voice commands, they will become an expected feature of mobile interactions. Voice input provides a lot of advantages for mobile users — it’s especially valuable in situations when users can’t focus on a screen, for example, while driving a car.

When designing a form, you can provide voice input as an alternative method of data input.

Google Translate provides an option to enter the text for translation using voice. (Large preview) Field Labels Write Clear And Concise Labels

The label is the text that tells users what data is expected from them in a particular input field. Writing clear labels is one of the best ways to make a form more accessible. Labels should help the user understand what information is required at a glance.

Avoid using complete sentences to explain. A label is not help text. Write succinct and crisp labels (a word or two), so that users can quickly scan your form.

Place The Label And Input Close Together

Put each label close to the input field, because the eye will visually know they’re tied together.

A label and its field should be visually grouped, so that users can understand which label belongs to which field. (Large preview) Don’t Use Disappearing Placeholder Text As Labels

While inline labels look good and save valuable screen estate, these benefits are far outweighed by the significant usability drawbacks, the most critical of which is the loss of context. When users start entering text in a field, the placeholder text disappears and forces people to recall this information. While it might not be a problem for simple two-field forms, it could be a big deal for forms that have a lot of fields (say, 7 to 10). It would be tough for users to recall all field labels after inputting data. Not surprisingly, user testing continually shows that placeholders in form fields often hurt usability more than help.

Don’t use placeholder text that disappears when the user interacts with the field. (Large preview)

There’s a simple solution to the problem of disappearing placeholders: the floating (or adaptive) label. After the user taps on the field with the label placeholder, the label doesn’t disappear, it moves up to the top of the field and makes room for the user to enter their data.

Floating labels assure the user that they’ve filled out the fields correctly. (Image: Matt D. Smith) Top-Align Labels

Putting field labels above the fields in a form improves the way users scan the form. Using eye-tracking technology for this, Google showed that users need fewer fixations, less fixation time and fewer saccades before submitting a form.

Another important advantage of top-aligned labels is that they provide more space for labels. Long labels and localized versions will fit more easily in the layout. The latter is especially suitable for small mobile screens. You can have form fields extend the full width of the screen, making them large enough to display the user’s entire input.

(Large preview) Sentence Case Vs. Title Case

There are two general ways to capitalize words:

  • Title case: Capitalize every word. “This Is Title Case.”
  • Sentence case: Capitalize the first word. “This is sentence case.”

Using sentence case for labels has one advantage over title case: It is slightly easier (and, thus, faster) to read. While the difference for short labels is negligible (there’s not much difference between “Full Name” and “Full name”), for longer labels, sentence case is better. Now You Know How Difficult It Is to Read Long Text in Title Case.

Avoid Using Caps For Labels

All-caps text  —  meaning text with all of the letters cap­i­tal­ized  —  is OK in contexts that don’t involve substantive reading (such as acronyms and logos), but avoid all caps otherwise. As mentioned by Miles Tinker in his work Legibility of Print, all-capital print dramatically slows the speed of scanning and reading compared to lowercase type.

All-capitalized letters are hard to scan and read. (Large preview) Layout

You know by now that users scan web pages, rather than read them. The same goes for filling out forms. That’s why designers should design a form that is easy to scan. Allowing for efficient, effective scanning is crucial to making the process of the filling out a form as quick as possible.

Use A Single-Column Layout

A study by CXL Institute found that single-column forms are faster to complete than multi-column forms. In that study, test participants were able to complete a single-column form an average of 15.4 seconds faster than a multi-column form.

Multiple columns disrupt a user’s vertical momentum; with multiple columns, the eyes start zigzagging. This dramatically increases the number of eye fixations and, as a result, the completion time. Moreover, multiple-column forms might raise unnecessary questions in the user, like “Where should I begin?” and “Are questions in the right column equal in importance to questions in the left one?”

In a one-column design, the eyes move in a natural direction, from top to bottom, one line at a time. This helps to set a clear path for the user. One column is excellent for mobile because the screens are longer vertically, and vertical scrolling is a natural motion for mobile users.

There are some exceptions to this rule. It’s possible to place short and logically related fields on the same row (such as for the city and area code).

If a form has horizontally adjacent fields, the user has to scan the form following a Z pattern. When the eyes start zigzagging, it slows the speed of comprehension and increases completion time. (Large preview) (Large preview) Create A Flow With Your Questions

The way you ask questions also matters. Questions should be asked logically from the user’s perspective, not according to the application or database’s logic, because it will help to create a sense of conversation with the user. For example, if you design a checkout form and asks for details such as full name, phone number and credit card, the first question should be for the full name. Changing the order (for example, starting with a phone number instead of a name) leads to discomfort. In real-world conversations, it would be unusual to ask for someone’s phone number before asking their name.

Defer In-Depth Questions To The End

When it comes to designing a flow for questions you want to ask, think about prioritization. Follow the rule “easy before difficult” and place in-depth or personal questions last. This eases users into the process; they will be more likely to answer complex and more intrusive questions once they’ve established a rapport. This has a scientific basis: Robert Cialdini’s principle of consistency stipulates that when someone takes a small action or step towards something, they feel more compelled to finish.

Group Related Fields Together

One of the principles of Gestalt psychology, the principle of proximity, states that related elements should be near each other. This principle can be applied to the order of questions in a form. The more related questions are, the closer they should be to each other.

Designers can group related fields into sections. If your form has more than six questions, group related questions into logical sections. Don’t forget to provide a good amount of white space between sections to distinguish them visually.

Generally, if your form has more than six questions, it’s better to group related questions into logical sections. Put things together that make sense together. (Large preview) Make A Long Form Look Simpler

How do you design a form that asks users a lot of questions? Of course, you could put all of the questions on one screen. But this hinder your completion rate. If users don’t have enough motivation to complete a form, the form’s complexity could scare them away. The first impression plays a vital role. Generally, the longer or more complicated a form seems, the less likely users will be to start filling in the blanks.

Minimize the number of fields visible at one time. This creates the perception that the form is shorter than it really is.

There are two techniques to do this.

Progressive Disclosure

Progressive disclosure is all about giving users the right thing at the right time. The goal is to find the right stuff to put on the small screen at the right time:

  • Initially, show users only a few of the most important options.
  • Reveal parts of your form as the user interacts with it.
Using progressive disclosure to reduce cognitive load and keep the user focused on a task. (Image: Ramotion) Chunking

Chunking entails breaking a long form into steps. It’s possible to increase the completion rate by splitting a form into a few steps. Chunking can also help users process, understand and remember information. When designing multi-step forms, always inform users of their progress with a completeness meter.

Progress tracker for e-commerce form. (Image: Murat Mutlu) (Large preview)

Designers can use either a progress tracker (as shown in the example above) or a “Step # out of #” indicator both to tell how many steps there are total and to show how far along the user is at the moment. The latter approach could be great for mobile forms because step indication doesn’t take up much space.

Action Buttons

A button is an interactive element that direct users to take an action.

Make Action Buttons Descriptive

A button’s label should explain what the button does; users should be able to understand what happens after a tap just by looking at the button. Avoid generic labels such as “Submit” and “Send”, using instead labels that describe the action.

Label should help users finish the sentence, 'I want to…' For example, if it’s a form to create an account, the call to action could be 'Create an account'. (Large preview) Don’t Use Clear Or Reset Buttons

Clear or reset buttons allow users to erase their data in a form. These buttons almost never help users and often hurt them. The risk of deleting all of the information a user has entered outweighs the small benefit of having to start again. If a user fills in a form and accidentally hits the wrong button, there’s a good chance they won’t start over.

Use Different Styles For Primary And Secondary Buttons

Avoid secondary actions if possible. But if your form has two calls to action (for example, an e-commerce form that has “Apply discount” and “Submit order”) buttons, ensure a clear visual distinction between the primary and secondary actions. Visually prioritize the primary action by adding more visual weight to the button. This will prevent users from tapping on the wrong button.

Ensure a clear visual distinction between primary and secondary buttons. (Large preview) Design Finger-Friendly Touch Targets

Tiny touch targets create a horrible user experience because they make it challenging for users to interact with interactive objects. It’s vital to design finger-friendly touch targets: bigger input fields and buttons.

The image below shows that the width of the average adult finger is about 11 mm.

People often blame themselves for having “fat fingers”. But even baby fingers are wider than most touch targets. (Image: Microsoft) (Large preview)

According to material design guidelines, touch targets should be at least 48 × 48 DP. A touch target of this size results in a physical size of about 9 mm, regardless of screen size. It might be appropriate to use larger touch targets to accommodate a wider spectrum of users.

Not only is target size important, but sufficient space between touch targets matters, too. The main reason to maintain a safe distance between touch targets is to prevent users from touching the wrong button and invoking the wrong action. The distance between buttons becomes extremely important when binary choices such as “Agree” and “Disagree” are located right next to each other. Material design guidelines recommend separating touch targets with 8 DP of space or more, which will create balanced information density and usability.

(Large preview) Disable Buttons After Tap

Forms actions commonly require some time to be processed. For example, data calculation might be required after a submission. It’s essential not only to provide feedback when an action is in progress, but also to disable the submit button to prevent users from accidentally tapping the button again. This is especially important for e-commerce websites and apps. By disabling the button, you not only prevent duplicate submissions, which can happen by accident, but you also provide a valuable acknowledgment to users (users will know that the system has received their submission).

This form disables the button after submission. (Image: Michaël Villar) Assistance And Support Provide Success State

Upon successful completion of a form, it’s critical to notify users about that. It’s possible to provide this information in the context of an existing form (for example, showing a green checkmark above the refreshed form) or to direct users to a new page that communicates that their submission has been successful.

Example of success state. (Image: João Oliveira Simões) Errors And Validation

Users will make mistakes. It’s inevitable. It’s essential to design a user interface that supports users in those moments of failures.

While the topic of errors and validation deserves its own article, it’s still worth mentioning a few things that should be done to improve the user experience of mobile forms.

Use Input Constraints for Each Field

Prevention is better than a cure. If you’re a seasoned designer, you should be familiar with the most common cases that can lead to an error state (error-prone conditions). For example, it’s usually hard to correctly fill out a form on the first attempt, or to properly sync data when the mobile device has a poor network connection. Take these cases into account to minimize the possibility of errors. In other words, it’s better to prevent users from making errors in the first place by utilizing constraints and offering suggestions.

For instance, if you design a form that allows people to search for a hotel reservation, you should prevent users from selecting check-in dates that are in the past. As shown in the Booking.com example below, you can simply use a date selector that allows users only to choose today’s date or a date in the future. Such a selector would force users to pick a date range that fits.

You can significantly decrease the number of mistakes or incorrectly inputted data by putting constraints on what can be inputted in the field. The date picker in Booking.com’s app displays a full monthly calendar but makes past dates unavailable for selection. (Large preview) Don’t Make Data Validation Rules Too Strict

While there might be cases where it’s essential to use strict validation rules, in most cases, strict validation is a sign of lazy programming. Showing errors on the screen when the user provides data in a slightly different format than expected creates unnecessary friction. And this would have a negative impact on conversions.

It’s very common for a few variations of an answer to a question to be possible; for example, when a form asks users to provide information about their state, and a user responds by typing their state’s abbreviation instead of the full name (for example, CA instead of California). The form should accept both formats, and it’s the developer job to convert the data into a consistent format.

Clear Error Message

When you write error messages, focus on minimizing the frustration users feel when they face a problem in interacting with a form. Here are a few rules on writing effective error messages:

  • Never blame the user.
    The way you deliver an error message can have a tremendous impact on how users perceive it. An error message like, “You’ve entered a wrong number” puts all of the blame on the user; as a result, the user might get frustrated and abandon the app. Write copy that sounds neutral or positive. A neutral message sounds like, “That number is incorrect.”
  • Avoid vague or general error messages.
    Messages like “Something went wrong. Please, try again later” don’t say much to users. Users will wonder what exactly went wrong. Always try to explain the root cause of a problem. Make sure users know how to fix errors.
  • Make error messages human-readable.
    Error messages like “User input error: 0x100999” are cryptic and scary. Write like a human, not like a robot. Use human language, and explain what exactly the user or system did wrong, and what exactly the user should do to fix the problem.
Display Errors Inline

When it comes to displaying error messages, designers opt for one of two locations: at the top of the form or inline. The first option can make for a bad experience. Javier Bargas-Avila and Glenn Oberholzer conducted research on online form validation and discovered that displaying all error messages at the top of the form puts a high cognitive load on user memory. Users need to spend extra time matching error messages with the fields that require attention.

Avoid displaying errors at the top of the form. (Image: John Lewis) (Large preview)

It’s much better to position error messages inline. First, this placement corresponds with the user’s natural top-to-bottom reading flow. Secondly, the errors will appear in the context of the user’s input.

eBay uses inline validation. (Large preview) Use Dynamic Validation

The time at which you choose to display an error message is vital. Seeing an error message only after pressing the submit button might frustrate users. Don’t wait until users finish the form; provide feedback as data is being entered.

Use inline validation with real-time feedback. This validation instantly tells people whether the information they’ve typed is compatible with the form’s requirements. In 2009, Luke Wroblewski tested inline validation against post-submission validation and found the following results for the inline version:

  • 22% increase in success rate,
  • 22% decrease in errors made,
  • 31% increase in satisfaction rating,
  • 42% decrease in completion times,
  • 47% decrease in the number of eye fixations.

But inline validation should be implemented carefully:

  • Avoid showing inline validation on focus.
    In this case, as soon as the user taps a field, they see an error message. The error appears even when the field is completely empty. When an error message is shown on focus, it might look like the form is yelling at the user before they’ve even started filling it out.
  • Don’t validate after each character typed.
    This approach not only increases the number of unnecessary validation attempts, but it also frustrates users (because users will likely see error messages before they have completed the field). Ideally, inline validation messages should appear around 500 to 1000 milliseconds after the user has stopped typing or after they’ve moved to the next field. This rule has a few exceptions: It’s helpful to validate inline as the user is typing when creating a password (to check whether the password meets complexity requirements), when creating a user name (to check whether a name is available) and when typing a message with a character limit.
Reward early, punish late is a solid validation  approach. (Image: Mihael Konjević) Accessibility

Users of all abilities should be able to access and enjoy digital products. Designers should strive to incorporate accessibility needs as much as they can when building a product. Here are a few things you can do to make your forms more accessible.

Ensure The Form Has Proper Contrast

Your users will likely interact with your form outdoors. Ensure that it is easy to use both in sun glare and in low-light environments. Check the contrast ratio of fields and labels in your form. The W3C recommends the following contrast ratios for body text:

  • Small text should have a contrast ratio of at least 4.5:1 against its background.
  • Large text (at 14-point bold, 18-point regular and up) should have a contrast ratio of at least 3:1 against its background.

Measuring color contrast can seem overwhelming. Fortunately, some tools make the process simple. One of them is Web AIM Color Contrast Checker, which helps designers to measure contrast levels.

Do Not Rely On Color Alone To Communicate Status

Color blindness (or color vision deficiency) affects approximately 1 in 12 men (8%) and 1 in 200 women in the world. While there are many types of color blindness, the most common two are protanomaly, or reduced sensitivity to red light, and deuteranomaly, or reduced sensitivity to green light. When displaying validation errors or success messages, don’t rely on color alone to communicate the status (i.e. by making input fields green or red). As the W3C guidelines state, color shouldn’t be used as the only visual means of conveying information, indicating an action, prompting a response or distinguishing a visual element. Designers should use color to highlight or complement what is already visible. Support colorblind people by providing additional visual cues that help them understand the user interface.

Use icons and supportive text to show which fields are invalid. This will help colorblind people fix the problems. (Large preview) Allow Users To Control Font Size

Allow users to increase font size to improve readability. Mobile devices and browsers include features to enable users to adjust the font size system-wide. Also, make sure that your form has allotted enough space for large font sizes.

WhatsApp provides an option to change the font size in the app’s settings. (Large preview) Test Your Design Decisions

All points mentioned above can be considered as industry best practices. But just because something is called a “best practice” doesn’t mean it is always the optimal solution for your form. Apps and websites largely depend on the context in which they are used. Thus, it’s always essential to test your design decisions; make sure that the process of filling out a form is smooth, that the flow is not disrupted and that users can solve any problems they face along the way. Conduct usability testing sessions on a regular basis, collect all valuable data about user interactions, and learn from it.

Conclusion

Users can be hesitant to fill out forms. So, our goal as designers is to make the process of filling out a form as easy as possible. When designing a form, strive to create fast and frictionless interactions. Sometimes a minor change — such as properly writing an error message — can significantly increase the form’s usability.

This article is part of the UX design series sponsored by Adobe. Adobe XD is made for a fast and fluid UX design process, as it lets you go from idea to prototype faster. Design, prototype and share — all in one app. You can check out more inspiring projects created with Adobe XD on Behance, and also sign up for the Adobe experience design newsletter to stay updated and informed on the latest trends and insights for UX/UI design.

(al, yk, il)
Categories: Web Design

UX And HTML5: Let’s Help Users Fill In Your Mobile Form (Part 2)

Mon, 08/27/2018 - 05:00
UX And HTML5: Let’s Help Users Fill In Your Mobile Form (Part 2) UX And HTML5: Let’s Help Users Fill In Your Mobile Form (Part 2) Stéphanie Walter 2018-08-27T14:00:31+02:00 2018-09-15T11:11:14+00:00

In this second part, I want to focus more on mobile-specific capabilities. HTML5, for instance, has brought us a lot of really cool features to help users fill in mobile forms and format their data. We will see in detail how HTML5 attributes can help you with that. Then, we will go beyond “classic” form elements and see how to use mobile capabilities such as the camera, geolocation and fingerprint scanners to really take your mobile form experience to the next level on websites and in native applications.

Helping The User Format Content With HTML5

In the first part of this series, we saw some general advice on how to display fields. Now it’s time to go a bit deeper and look at how a few well-crafted lines of HTML5 code can improve your mobile forms.

HTML5 Mobile-Optimized Goodness

HTML5 opens a whole world of possibilities for optimizing forms for mobile and touch devices. A lot of interesting new input types can trigger different keyboards to help users. We can also do some interesting things with capturing media directly in the browser.

Entering Numerical Data

input type= number

The HTML5 <input type=number> attribute restricts an input field to numbers. It has a built-in validation system that rejects anything that is not a number.

In some desktop browsers, this input is presented with little arrows on the right that the user can click to increment the number. On mobile, it opens a keyboard with numbers, which decreases typos and form-validation errors. The input’s look and feel depend on the operating system.

On the left, Android’s keyboard, and on the right, the iOS keyboard with numbers. (Large preview)

The input should allow for decimals and negative numbers (but few keyboards respect that). As explained in the W3C’s specifications, “a simple way of determining whether to use type=number is to consider whether it would make sense for the input control to have a spinbox interface (e.g. with ‘up’ and ‘down’ arrows)”. This means that the input is not supposed to be used for credit cards or area codes.

Meet SmashingConf New York 2018 (Oct 23–24), focused on real challenges and real front-end solutions in the real world. From progressive web apps, Webpack and HTTP/2 to serverless, Vue.js and Nuxt — all the way to inclusive design, branding and machine learning. With Sarah Drasner, Sara Soueidan and many other speakers.

Check all topics and speakers ↬

The pattern And inputmode Attributes

To add some restrictions to your number inputs, you could use the pattern attribute to specify a regular expression against which you want to control values.

This is what it looks like:

<input type="number" id="quantity" name="quantity" pattern="[0-9]*" inputmode="numeric" />

You can use this pattern to bring up the big-button numeric keyboard on the iPhone (but not the iPad). This keyboard does not have the minus sign or comma, so users lose the ability to use negative numbers and decimals. Also, they can’t switch back to another keyboard here, so be careful when using this.

Also, note that patterns can be applied to any other type of inputs.

Using only this pattern won’t work on most Android phones. You’ll still need a combination of input type=number and the attribute to make this work.

Android and iOS demo with input type=number, pattern and inputmode. (Large preview)

inputmode

If you only want to trigger the mobile numeric keyboard but don’t want to deal with the type=number and pattern mess, you could use a text input and apply the inputmode=numeric attribute. It would look like this:

<input type="text" id="quantity" name="quantity" inputmode="numeric" />

Unfortunately (at the time of writing), only Chrome 67 mobile supports this, but it should be arriving in Chrome desktop 66 without a flag.

To learn more about how to enter numbers in a form, read “I Wanted to Type a Number”.

input type=tel

If you want users to enter a phone number, you can use the input type=tel. As you can see in the screenshot below, it triggers the same digits on iOS’ keyboard as the pattern attribute described above. Due to the complexity of phone numbers across the world, there is no automatic validation with this input type.

input type=tel on Android and iOS (Large preview) Entering Dates

Even if they are technically numerical data, dates deserve their own section. There are a few HTML5 input types for entering dates. The most used is input type=date. It will trigger a date-picker in supported browsers. The appearance of the date-picker depends on the browser and OS. To learn more on how browsers render input type="date", I recommend you read “Making input type=date complicated.”

A date-picker based on input type=date on Android and iOS (Large preview)

There’s also type=week to pick a week, type=time to enter a time (up to the hour and minute), and type=datetime-local to pick a date and a time (using the user’s local time). So many choices!

Example of date-picker with more options on Android (week, date and time, etc.) (Large preview)

input type=date works well for booking interfaces, for example. You might have some needs that require you to build your own date-picker, though (as we’ve already seen in the section on sensible defaults). But input type=date is always a nice option if you need a date-picker and don’t want to bring a whole JavaScript library into the website for the job.

Yet, sometimes not using type=date for dates is better. Let’s take the example of a birth date. If I was born in 1960 (I’m not — this is just an example), it would take me many taps to pick my birth date if I was starting from 2018. On Android, I discovered recently that if I press on the year in the picker, I get a sort of dropdown wheel with all of the years. A bit better, but it still requires a fair amount of scrolling.

A user told me on Twitter:

"I’m born in 1977 and can confirm the annoyance. The more time it takes to scroll, the older you feel :-("

So, maybe birth dates are not the best candidate for date-pickers.

With Android’s date-picker, even though you can press and hold the year to get a year-picker, picking a birth date is still tedious. (Large preview) URL, Email, Tel And Search

Mobile phones hide some other keyboard and input-optimization goodness that enhance the user’s experience when filling in a form. The devil is in the details, as they say.

Using the input type=url field will bring up an optimized keyboard on mobile, with / (the slash key) directly accessible. Depending on the OS, you can also give quick access to commons top-level domains, like the .fr in the screenshot below. If you long-press this button, shortcuts to other top-level domains will appear. This also comes with automatic browser validation that checks that the URL’s format is valid.

input type=url keyboard on Android and iOS (Large preview)

The input type=emailfield brings up an email-optimized keyboard giving quick access to the @ symbol. This input requires the presence of @ somewhere in the field in order to be valid. That’s the only verification it does.

input type=email keyboard on Android and iOS (Large preview)

The input type=search field brings up a search-optimized keyboard. The user can directly launch the search from a button on the keyboard. There’s also a little cross to clear the field and type a new query.

input type=search keyboard on Android and iOS (Large preview) Range And Color

The last two input types we looked at are not particularly optimized for mobile, but by using them, we can avoid having to load heavy custom JavaScript libraries, which is a good idea for mobile users.

input type=range provides a visual UI slider to input a number. The UI for this control is browser-dependent.

input type=color provides an easy way for the user to enter a color value. In many browser implementations, this comes with a color-picker.

input type=range and input type=color on Android and iOS (Large preview) HTML Media Capture: Taking And Uploading Pictures And Recording Sound

I remember the time of the iPhone 3, when Apple would not even allow a simple input type=file to be used on a website, for security reasons. Those times are long gone. With the HTML media capture API, it’s now possible to access different sensors of a device. We can capture photos and videos, and we can even record voice directly in the browser.

The accept attribute lets you specify what kind of media to accept in the input: audio, image, video. The user can give the browser direct access to their camera, for example.

The code looks like this:

<input type="file" id="take-picture" accept="image/*"> The accept attribute is set to image. The browser asks whether I want to access the camera directly or the files on the device. (Large preview)

The capture attribute lets you specify the preferred mode of capture. If you add the capture attribute on top of the accept attribute, you can make the browser open the camera or voice recorder directly.

<input type="file" accept="image/*" capture> // opens the camera> <input type="file" accept="video/*" capture> // opens the camera in video mode <input type="file" accept="audio/*" capture> // opens the voice recorder The mobile browser directly opens the capture mechanism: on the left, the camera, on the right, the video recorder. (Large preview)

For more details on how to use media directly in the browser, read the section “Accessing and Handling Images, Video and Audio Directly in the Browser” in my article on the secret powers of mobile browsers.

HTML5 Autos: Autocorrect, Autocomplete, Autofill, Autocapitalize And Autofocus

HTML5 comes with a slew of automatic attributes. To enhance the mobile experience, you will want to be smart about what can be automated and what can’t. Here are some general rules of thumb:

  • Disable autocorrect on things for which the dictionary is weak: email addresses, numbers, names, addresses, cities, regions, area codes, credit card numbers.
  • Disable autocapitalize for email fields and other fields where appropriate (for example, website URLs). Note that type=email does the job for you in recents version of iOS and Android, but disable it anyway for older versions or if type=email is not supported.
  • You can set the autocapitalize attribute to words to automatically uppercase the first letter of each word the user types. This can be useful for names, places and the like, but, again, be careful with it, and test it.
Use input type=email for email addresses. If you don’t, at least deactivate auto-capitalization. No email address starts with a capital letter. (Large preview)
  • For input type=tel, set autocomplete="tel".
  • You could use autofocus to give the focus to a control element when the user loads the page. But just because the user opens the “contact” page, it does not mean they are ready to jump right to the first field of your form. So, again, use it wisely.
In this example, we could use autofocus to take the user directly to the first field once they’ve clicked on the button. (Large preview)

If you want more autocomplete options, a whole list is on the WhatWG Wiki. Just make sure you use the right ones. Implement, test, and test again.

HTML5 Form Validation

I won’t get into the technical details here, but you should know that HTML5 has a built-in form-validation API for many fields. It’s nice if you don’t want to use a JavaScript library to display inline validation messages. Here are the main things you need to know as a UX designer about HTML5 form validation:

HTML native form validation in an Android browser (Large preview)

In “Native Form Validation, Part 1,” Peter-Paul Koch goes into detail on why HTML and CSS form validation doesn’t really make forms better at this time.

Offline Support To Save User Data

A lot of things can go wrong, especially on mobile. Mistakes happen. A user could mistap the back button in the browser and lose all of their data.

If the user comes back to the page, it would be nice to display their data again. The same goes for if the browser crashes or the user closes the tab. You can store the user’s data in local or session storage to ensure nothing gets lost if something goes wrong. Geoffrey Crofte has written a JavaScript library to help you with that.

If the connection is lost as the user is submitting the form, they might also lose the data. To avoid this, you could use a combination of the** HTML5 offline API** and the Service Workers API to:

  • store the data in the cache,
  • try to automatically send it again when the connection comes back.

To learn how to code this, check out the article on “Offline-Friendly Forms”.

Mobile Device Capabilities Can Take the Experience To The Next Level

In part 1, we stuck to the basic common HTML form elements and attributes for enhancing mobile forms. But mobile devices capabilities now go far beyond displaying HTML, CSS and JavaScript web pages. Those little devices come equipped with a lot of sensors. And we will be able to use many of those in native apps and on the web to make our users’ lives so much easier.

Detecting The User’s Location

In the previous section, I wrote about pre-filling information for places and addresses. That’s a good start. We can go one step further. Instead of asking users to type a location, we can detect it. Meet the geolocation API for the web. There are also native iOS, Android and Windows Phone geolocation APIs.

Citymapper is a website and an app that helps users plan their travels. When the user goes into the first field, they see the “Use current location” option. If they select it, they are asked to allow the browser to access their geolocation data. This is the geolocation API. The browser then autocompletes the location it found and, the user can proceed to the destination field. The native app works pretty much the same way.


Citymapper proposes the user’s current location as the starting point for the journey. Be Smart When Asking For The User’s Permission

You might have noticed in the previous video that I had to agree to give access to my position to the Citymapper website. In the browser, the user handles permissions website by website, API by API.

You also need to be careful how you ask for permission. The user might refuse access to the geolocation, notification or other API if you ask too soon. They also might refuse if they don’t understand why you need the permission. You get one chance; use it wisely. After that, it will be almost impossible to recover. I’m an Android power user, and even I have to search around for the options in my browser when I want to reset the permissions I’ve given to a website. Imagine the trouble your users will have.

Here is some general advice on asking for permissions on the web:

  • Don’t be the creepy geolocation or notification stalker: Don’t ask for permission as soon as the user arrives on your website. They might not know about you or your service yet.
  • Let the user discover your website and service. Then, ask for permission in context. If you want to access their location, ask them only when you need it (Citymapper is a good example).
  • Explain why you need permission and what you will do with it.
Citymapper asks for access to the user’s location only when it needs it. Clearing permissions after the user refuses it can get really complicated because the user will need to search through their settings for that website. (Large preview)

If you want to go further, Luke Wroblewski (yes, him again) has created a nice video to help you with the permission-asking process.

A Better Checkout Experience

A big area of improvement for forms is the whole checkout payment experience. Here again, sensors on the device can make this an almost painless experience. The only pain will be the amount of money the user spends.

iOS Credit Card Scanner

In the previous section, I wrote about autodetection of credit cards and autocompletion features based on the user’s previous input. This still means that the user has to type their credit card data at least once.

Apple has taken this to the next level with its credit card scanner. Since iOS 8 in Safari, users can use their camera to scan and autocomplete their credit card information. To perform this magic, you will need to add the autocomplete cc-number attribute and some name to identify this as a credit card field. Apple doesn’t have much official information on it, but some people did some testing and put the results on StackOverflow.

Safari also has autofill options that users can use to add their credit card, allowing them reuse it on multiple websites.

The credit card scanning option appears when Safari detects a field that matches the credit card format. If the user already has a card registered on the phone, they can use the autofill option. (Large preview) Take Checkout One Step Further With Google Pay API

Google launched something similar: the Google Pay API. When implemented on a website, the API eliminates the need to manually enter payment information. It goes one step further: It can store billing and shipping addresses as well.

The user gets a dialog in Chrome that displays the various payment information they’ve stored. They can choose which one to use and can pay directly through the dialog.

The Google Pay API pop-up triggered on an e-commerce website (Source) (Large preview)

A standardized version of the Payment Request API is currently a W3C candidate recommendation. If this gets implemented in browsers, it would allow users to check out with a single button, which would request the API. Every step thereafter would be handled by native browser dialogs.

Making Authentication Easier

Mobile phones are, in most cases, personal devices that people don’t usually share with others. This opens up some interesting opportunities for authentication.

Magic Link

I use a password manager. I don’t know 99% of my passwords. They are all randomly generated. In order to log into a new Slack workspace, I must:

  1. open my password manager,
  2. enter my master password,
  3. search for the workspace,
  4. copy and paste the password into the Slack app.

It’s a tedious process, but Slack was smart enough to provide a better option.

Many users have they mail synchronized on their phone. Slack understood that. When you add a new Slack workspace in the app, you can either log in using the password or ask for the “magic link” option. If you opt for the latter, Slack sends a magic link to your mailbox. Open the mail, click on the big green button, and — ta-da! — you’re logged in.

Behind the scenes, this magic link contains an authentication token. The Slack app catches this and authenticates you without requiring the password.

When using the magic link option, Slack sends you an email with a link that lets you connect to your slack without having to enter your password. (Large preview) Fingerprint For Smart Identification

I do almost all of my banking on my mobile device. And when it comes to logging into my bank accounts, there’s a world of difference between my French Societe General bank app and the German N26 app.

With Société Générale, I have a login string and a passphrase. I can ask the app to remember the login string, which is 10 random digits. I’m not able to remember that one; I use a password manager for it. I must still remember and enter the six-digit passphrase on a custom-built keypad. Of course, the numbers’ positions change every time I log in. Security — yeah, I know. Also, I must change this passphrase every three months. The last time I was forced to change the passphrase, I did what most people do: choose almost the same passphrase, because I don’t want to have to remember yet another six-digit number. And of course, I was damn sure I would remember it, so I did not enter it in my password manager. Rookie mistake. Two weeks later, I tried to log in. Of course, I forgot it. I made three failed attempts, and then my account was blocked. Fortunately, I only use this account for savings. In the app, you can ask for a new passcode. It took almost one week for the bank to send me a new six-digit passphrase by paper mail to my home address in Luxembourg. Yeah.

N26, on the other hand, uses my email address as the login string. I can remember that without a password manager. When I want to log in, I put my finger on the start button of my Xperia phone, and that’s it. In the background, my phone scans my fingerprint and authenticates me. If that does not work, I can fall back to a password.

Same device, two apps, two totally different experiences.

Dropbox has another example of fingerprint authentication. (Large preview)

More and more apps on both Android and iOS now offer user the possibility to authenticate with a fingerprint. No more passwords — it’s an interesting and elegant solution.

Of course, people have expressed some security concerns about this. For the National Institute of Standards and Technology (NIST), biometrics is not considered secure enough. It advises combining biometrics with a second factor of authentication.

Fingerprint sensors can also be tricked — yes, like in spy movies. Did you hear about the plane that was forced to land because a woman learned of her husband’s infidelity after using his thumb to unlock his phone while he was sleeping?

Facial Recognition And Face ID

In 2018, Apple launched the iPhone X with the brand new face ID. Users can unlock their iPhone X using their face. Of course, some other Android phones and Windows tablets and computers had proposed this feature earlier. But when Apple launches something, it tends to become “a thing”. For the moment, this technology is mostly used as authentication to unlock phones and computer.

There are some pretty big challenges with facial-recognition technology. First, some algorithms can be fooled by a picture of the person, which is easily hackable. Another bigger concern is diversity. Facial-recognition algorithms tend to have difficulty recognizing people of color. For instance, a black researcher had to wear a white mask to test her own project. The researcher is Joy Buolamwini, and she gave a TED talk about the issue.

Some facial-recognition software is also used by some customs services to speed up border processing. It is used in New Zealand and will be used in Canada.

Most of us have seen enough science fiction to see the potential problems and consequences of systems that use facial recognition at scale. This kind of technology used outside of the private space of unlocking phones can get controversial and scary.

Google: One-Tap Sign-Up

If a user has a Google account, they can benefit from Google’s one-tap sign-up. When visiting a website and prompted to create an account in an inline dialog, the user doesn’t need to enter a password. Google provides a secure token-based password-less account, linked to the user’s Google account. When the user returns, they are automatically signed in. If they store their passwords in the Smart Lock, they get automatically signed in on other devices as well.

Google’s one-tap sign-up dialog (Source) (Large preview)

Note: This is an interesting password-less solution. Of course, by using it, users are linked to Google, which not everyone will feel comfortable with.

Conclusion

You can do a lot of really cool things when you start using mobile capabilities to help users fill in forms. We need a mobile-first mindset when building forms; otherwise, we’ll get stuck on the desktop capabilities we are familiar with.

Again, be careful with the device’s capabilities: always have a fallback solution in case a sensor fails or the user refuses access. Avoid making those capabilities the only options for those functions (unless you are building a map app that relies on geolocation).

This is the end of a series of two really long articles in which I’ve given you some general UX and usability advice and best practices. In the end, what matter are your form and your users. Some things described here might not even work specifically for your users — who knows? So, whatever you do, don’t take my (or Luke’s) word for it. Test it, with real users, on real devices. Measure it. And test again. Do some user research and usability testing. User experience is not only about best practices and magic recipes that you copy and paste. You need to adapt the recipe to make it work for you.

So, in short: Test it. Test it on real devices. Test it with real users.

(lf, ra, al, il)
Categories: Web Design

Making Distributed Product Teams Work More Efficiently With monday.com

Thu, 08/23/2018 - 05:00
Making Distributed Product Teams Work More Efficiently With monday.com Making Distributed Product Teams Work More Efficiently With monday.com Nick Babich 2018-08-23T14:00:26+02:00 2018-09-13T12:25:49+00:00

(This is a sponsored article.) The way that product teams work is changing: The software industry is quickly moving to remote work. In the US alone, 43% of employed Americans have spent at least some time working remotely, and that number has steadily increased in recent years. Many successful digital products on the market today were designed and developed by a distributed team. Such teams don’t have an office in the traditional sense. Everyone chooses to work from where they like, both geographically and functionally (in a coworking space, coffee shop, home office, etc.).

While a distributed product team might sound tempting to you, creating an effective design process on such a team requires a lot of effort. Collaboration and communication are two of the most significant challenges distributed teams face. Managing a distributed team requires an understanding of how the individuals on your team operate, as well as requires a digital toolset that makes the team’s operations as efficient as possible. That’s why investing in the right remote tools and technology is so critical for product managers.

If you’re a team manager who is looking to establish a robust design process for a distributed team, then this article for you. You’ll find seven of the most common challenges distributed product teams should overcome and learn how a team-management tool called monday.com (formerly dapulse) can help them with that.

1. Build A Shared Understanding Of A Project’s Goals

When it comes to organizing a work process on a remote team, one of the key goals is to keep the whole team on the same page. Management needs to set goals and make sure everyone on the team understands and accepts them. Building understanding is especially important for remote teams because interaction tends to be more sporadic. Ensure that everyone on the team knows the following:

  • What are the project’s overall goals? When a team clearly understands the product strategy (what they want to build and why), that understanding motivates engagement.

  • What is expected of them, and how do they fit in the bigger picture? People want to know their role in the process. Even though every team member will be deep in the details when working on a project, understanding the big picture will help them to focus on what’s really important.

  • What are other people involved in the project doing? Each team member should have visibility on what the other team members are working on.

The more everyone knows, the better they can work as a team.

Visualize The Product Development Process

Helping everyone on the team know what is expected of them and when is possible using monday.com’s feature named the “timeline.” The timeline makes tasks more visual — team members will be able to see when each task is scheduled for, how long it will take and how it fits in the entire project. The tool enables you to see not only what tasks your team members are working on, but also how those tasks are distributed over time. It is great for when some activities depend on others (for example, developers are waiting on mockups from designers).

The timeline enables team members to see a high-level roadmap. (Large preview) 2. Manage The Team’s Workload

As anyone who has ever worked on a remote team will tell you, remote working is quite different from working face to face. Many project managers find it hard to manage the team’s workload.

Most product teams use project-tracking software to plan and estimate their work. Usually, a team will prepare all of the work in a task list, in which each task has a text description and a time estimate. The biggest downside of this approach is that it’s not very representative. For example, Kanban boards, used by many product teams today, are not very representative — it’s almost impossible from a glance at the board to understand the order in which tasks should be completed, especially when they have dependencies.

Using a Kanban board might make it hard to see how tasks should be distributed in time. (Image source) (Large preview) Track Everything Your Team Is Working On

Interaction cost (i.e. the cognitive or physical effort required to complete an action) plays a vital role in the user experience of a product. The more effort required to complete an operation, the less usable the interface becomes for the end user. If the project manager has to switch to different products to see the team’s progress, that will create unnecessary friction and hinder the team from working efficiently.

monday.com assembles and displays progress data in a logical and understandable way. The tool has a feature called a board. The board is where all team members can track everything the team is working on. The main advantage of the board is that it enables product managers to monitor the team’s progress in real time and instantly see who is working on what and see where things stand.

monday.com gives you a clear sense of what needs to get done and who is responsible for what. The board provides in-depth insight into a project and its tasks. (Large preview) Communicate Current Status

Each team needs a mechanism that makes it easy to understand what’s going on at a glance.

One way to solve this problem is to use color coding for different elements. Color coding speeds up visual search because it allows users to quickly filter a particular object (or objects) by knowing the color associated with it. monday.com uses color coding to indicate the current status of a task. For example, it’s easy to see where things have gotten stuck just by looking at the board and finding all tasks colored in red.

Status updates can be color coded. (Large preview) Create, Modify And Assign Tasks In A Few Clicks

Adding tasks in a project-management tool doesn’t sound very exciting. Generally, the more time it takes, the less happy the product manager will be.

monday.com simplifies the process of data input. Managers can quickly add rows to the board — monday.com calls them pulses. Pulses can be tasks, projects, missions, to-do items, etc. Creating a pulse requires just a few clicks.

(Large preview)

After you create a pulse, simply assign it to a team member.

Assign teammates to particular tasks or projects. (Large preview) Tailor The Platform To Your Needs

There’s no such thing as a universal design process. Every project is different and requires its own design process. A product-management tool should be very adaptive to change; the product team should be able to customize the process according to their needs, without having to put much effort into customization.

monday.com is extremely customizable and lets the user configure almost any option. You can customize monday.com to manage any workflow or process, to address any challenge and to manage basically anything.

When it comes to creating a board, you don’t need to start from scratch. A multitude of templates allow you to start quickly. For example, the “Team Tasks” template would be very useful for product teams.

Finding the right template for your activity is really simple because all templates are visualized. (Large preview)

After selecting a template for your needs, you can customize it by manipulating different sections. Product teams often need to combine task into groups, whereby each group represents a milestone (for example, “Release 1”, “Release 2”, etc.). Doing this in monday.com is relatively simple. As a board owner, you can have as many groups as you want.

Easy to organize tasks. You can have as many groups as you want. (Large preview)

But it doesn’t stop there. You can use the checklist feature to break down tasks even further. For example, each task can be broken down into smaller to-do steps. This feature is handy when a few activities need to get done before the task can be completed — for example, if a product specification needs to be approved by a few designers before it can be handed over to the development team. The checklist sits within a pulse, in the “Updates” section, and can help create a structure for each pulse.

The checklist sits within a pulse, in the “Updates” section. This feature can help create a structure for each pulse. (Large preview) Plan The Team’s Workload Visually

Designers, developers and managers often work with compressed timeframes and simultaneous projects. A team must be able to respond quickly to feedback on their product from stakeholders and users. Following the build-measure-learn cycle, a product team should be really flexible; it should be ready to implement feedback from testing sessions and adjust the design process according to the new information. The same level of flexibility should be in all products the team uses.

Using monday.com’s timeline, it’s possible to make corrections and improve the team’s efficiency. The visual editor makes the process of managing tasks easy. The product manager can see where each project is at each point, and can see and focus on areas of struggle, quickly and effectively.

The timeline makes it possible to see each team member’s capacity over a set period of time (say, the next few weeks), seeing where they have room to take on more work and where they need to delegate tasks to others.

Change the time range in the timeline. The time range is updated in real time. (Large preview) 3. Create Effective Internal Communications

Communication plays a critical role in the design process. When it comes to product design, it’s essential for all team members to be on the same page. Unlike colocated teams, a distributed team won’t have an opportunity to arrange regular face-to-face meetings. When you take out face-to-face interaction, you can’t expect things to just work the same way. Poorly established communication patterns can lead to some team members feeling like they’re working in a vacuum.

Tools matter more in remote work because they are the foundation for communication. The goal is to make sure everyone on the team feels connected.

Centralize All Communication

In today’s world, we communicate with a variety of tools: from traditional email to online messengers such as Skype, WhatsApp, Slack and Facebook Messenger. Having to switch from a task-management tool to another tool for communication can be stressful. Worse, some information can get lost during the transition (for example, an email inbox can fill up to the point that a team member can overlook a critical email).

Product teams can use monday.com as a single communication platform for their workplace. And it would be a much better solution because it allows for communication in the context of each task. With monday.com, you no longer need to use email for internal communication. When a team member clicks on a pulse on any board, a box opens to the right of the screen, showing the “updates”. Simply mention a person’s username (“@johndoe”), and send your message. The great thing is that the chat thread stays with that task, so finding a conversation after a while is relatively easy.

Cut Down On Meetings And Optimize Required Meetings

Meetings are an essential part of the communication process. When it comes to reviewing plans and brainstorming on design decisions, there’s no substitute for a meeting. But for a distributed team, the number of potential hours available for real-time meetings can be limited, so it’s essential to make the best use of that time. A distributed team should continually try to reduce their number of meetings and maximize the effectiveness of the time that team members have together.

Take a weekly kickoff meeting as an example. This meeting happens on a Monday, and team members come together to discuss plans for the week. For many teams, such meetings are rarely productive. Quite often, the information shared in a weekly kickoff meeting becomes outdated shortly after the meeting, and team members need to reprioritize tasks.

monday.com saves the team vast amounts of time in meetings. Instead of discussing the plan for the week, the product manager can break down complex tasks into weekly achievable goals. This will help team members plan the week based on what they need to get done.

Create a weekly task board. (Large preview) Share Valuable Resources With The Entire Team, Not Individual Members

Imagine you’ve found a really valuable resource and want to share it with your peers. You tweet about it and send a link to a group chat. You get feedback like, “Awesome resource! Thanks!” from some people in the chat. Shortly after, most of your peers forget about the resource, especially if they can’t use it in the work they’re doing right now. Sad, right? We can do better.

Instead of sending a link to a group chat, share all the resources you find on a separate board. monday.com has a template named “Design Inspiration & Resources”. The great thing about this approach is that it’ll be much easier for team members to find a particular resource when they actually need it.

(Large preview) Organize Better Planning And Brainstorming Sessions

Task prioritization is a typical activity in agile project management. Team members get together, discuss tasks and vote on what to implement in the next sprint.

monday.com incorporates voting. Team members can use the voting column when they want to decide on something together as a team. Simply add a voting column to a board, and team members will be able to cast their vote in one click.

Vote for ideas during brainstorming and planning sessions. (Large preview) Notify Team Members In Real Time

Fear of missing out (FOMO) is a common problem on distributed teams. When working remotely, team members might be afraid to miss an important piece of information. As a result, they spend a lot of time in communication tools, checking mail and messengers. This can get really distracting. Team members should spend less time in communication tools and more time in tools they use to design (tools for prototyping and development). It’s all too easy to waste the day reading messages and replying.

A communication tool should serve vital information just when team members need it; it should have an effective mechanism of notification. monday.com notifies users via desktop and mobile in real time. The platform has an app for iOS and Android. The app allows team members to stay connected on their phone or tablet and to respond quickly from anywhere. It’s also possible to customize notification rules. For example, you can manage which activity triggers an email.

(Large preview) Create A Work Schedule For Your Team

If your team is distributed across the globe and you need to arrange a meeting, you have to be sure that it won’t happen at awkward hours (such as in the middle of the night). It would be great to see the team members’ working hours.

The work schedule board is a cornerstone of your business operations. Team members in each time zone can commit to the times that work for them. This helps product managers schedule meetings at times that work for everybody.

The work schedule board shows when team members will be online and available for chat. (Large preview) 4. Involve Users In The Design Process

Most commercially successful products were created with a strong focus on the target audience. Designers know that if they want to release a successful product, they need to introduce real users to the design process. User involvement is most efficient and influential in the early stages of product development, because the cost of making changes increases as the system develops. Generally, the earlier you create a strong feedback loop, the better the final product will be.

Share Designs With Users And Gather A Valuable Feedback

The feedback that a product team gets from users is extremely valuable. It can validate that the design team is moving in the right direction.

On monday.com, users can create a board and choose whom to share it with. For example, if you are working with a client, you can set up a board for their project and invite them to work as a guest. The board could include key features you want to work on. As soon as you share the board, the client will get a notification and then can open the board, review the plan and request modifications.

5. Find All Required Information Easily

Documentation is another challenge. Distributed teams don’t have a physically shared space where they can share product documentation. Information might be stored in many different places: email, cloud drives, local computers, etc. It could lead to team members missing an important piece of information and being unaware of it. This leads to fragmented knowledge.

Centralize All Documents

Having all documents in one place is critical to success. monday.com syncs all information in a single accessible hub. All team members can store all relevant discussions in a searchable database. The platform provides an option to upload different types of files simply by dragging and dropping. The next time a designer needs to share a product’s specifications, all they need to do is upload a file to the platform.

Upload all assets by dragging and dropping. (Large preview) Search Anything And Everything

Anyone who has ever worked with a knowledge base will tell you how critical search functionality is. Without proper search, your chance of finding information decreases significantly.

monday.com allows you to quickly find anything your team has ever worked on, including images, updates, projects and assignments. Your work becomes a rich knowledge base.

(Large preview)

For example, when you need to find the latest version of a product’s specification, all you need to do is click the search box, select the “Files” tab and enter the project’s name as a search query.

(Large preview) 6. Make The Collaboration Tool A Natural Part Of The Team

The platform you choose for team management should feel like second nature. Technology should work for you and your team, not the other way around.

Minimize The Time Required To Learn A Tool

When you introduce a new tool in the design process, one goal should be to have total agreement to work using this tool. This agreement is not always easy to come by because team members are usually skeptical about the next “magical tool that will solve all of their problems”. What’s worse is that they have to spend extra time learning how to use it. Nobody wants to learn new software.

One of the most significant advantages of monday.com is its intuitiveness. Regardless of whether you’ve used a similar app before, monday.com can be picked up with no training. Team members will be able to understand how to use the tool without preparation.

monday.com provides basic onboarding to help users get started. (Large preview) Scalable

When companies select a collaboration tool, they often think of it as an investment. They want a tool that will scale with the business.

monday.com is suitable for any sized team, from two freelancers working together to thousands collaborating across the globe. The tool scales with you, from simplicity to complexity, with total ease. Also, as your business expands, monday.com makes it painless to shift to a premium version (Standard, Pro or Enterprise) and get more of the platform’s premium features.

Integrate The Platform With Existing Tools

A task-management tool is essential for any team hoping for good results. But the team’s toolbox also needs to support the design process (for prototyping and development) and the collection of design artifacts (for example, on Google Drive or Dropbox). It’s essential that the team-management tool integrates seamlessly with other tools the team uses.

When it comes to integration, monday.com does a lot to be part of the established software ecosystem. It can connect to Dropbox, Zapier, Google Drive and other sharing tools. As a team member, you can attach a mockup file to your updates, sharing it in the context of the tasks it relates to.

monday.com also comes with an open API architecture, which lets developers build their own integrations.

(Large preview) 7. Keep The Team Motivated

Having the right atmosphere is extremely important. Team leaders should not only be in tune with each person on the team, but should continually look for ways to increase engagement.

Celebrate Successes With Team Members

It’s natural for people to seek acknowledgment. The need for social approval drives us to look for confirmation from people we know (parents, friends, colleagues). When someone recognizes our results by saying something as simple as “Great job!”, we feel motivated to work towards our goals. It’s essential for team players to get acknowledged, especially when working remotely.

monday.com has a few features that help create a sense of acknowledgment. The first one is the thumb-up feature, which is basically a positive reaction to an activity. Most people are familiar with this from social networks. People are used to measuring the effect of a post by the number of likes they get. monday.com allows you to give a thumb up to your teammates’ work.

(Large preview)

Another nice feature are the animated GIFs. You can liven up comments with GIFs. monday.com lets you pick from thousands of GIFs when responding to teammates, which will add a bit of personality to your comments.

(Large preview)

Last but not least, monday.com has a confetti feature. As soon as a designer completes their last “in progress” task on a board, they will see an animated confetti effect. This subtle detail adds a bit of delight and motivates team members to have an all-green board.

(Large preview) Conclusion

Establishing an effective process on a distributed team is hard. What works for a colocated team won’t necessarily work for a distributed team, and what works for one distributed team won’t necessarily work for another.

Build a remote-friendly work culture by focusing on following priorities:

  • Prioritize transparency.
    Keep important information accessible to everyone.

  • Stay on top of the team’s activity.
    Understand what every member of your team is doing and where the team is in the process at a glance.

  • Build an effective communication system.
    The foundation of distributed teams is communication. Create a healthy system of meetings and habits to keep people communicating.

  • Lower the barrier to entry.
    Choose a team-collaboration tool that will be the least painful for everyone to get on board with. It should be a reference point that brings everything together.

(ms, ra, il, al)
Categories: Web Design

Designing The Invisible: 3 Things I Learned Designing For Voice

Wed, 08/22/2018 - 05:00
Designing The Invisible: 3 Things I Learned Designing For Voice Designing The Invisible: 3 Things I Learned Designing For Voice William Merrill 2018-08-22T14:00:44+02:00 2018-09-13T12:25:49+00:00

The current iteration of voice-controlled digital assistants are still struggling to integrate as seamlessly as the big three voice players of Amazon, Google and Apple would hope. A 2017 report by Voicelabs states there’s only a 3 percent chance a user will be active in the second week after downloading a voice application and 62 percent of Alexa’s skills are still to get any kind of rating on its store (as of September 2017).

As designers, we have a real opportunity to provide valuable meaning to these assistants but we’re still trying to work out where the technology can add real benefits to the user. For many, embarking on a voice UI (VUI) project can be a bit like entering the Unknown. There are few success stories for designers or engineers to be inspired by, especially within contexts that illustrate how this nascent technology could help people thrive in new ways.

Experimenting With speechSynthesis

The Web Speech API gives you the ability to voice-enable your website in two directions: listening to your users via the SpeechRecognition interface and talking back to them via the speechSynthesis interface. All of this is done via a JavaScript API, making it easy to test for support. Read article →

As part of BBC2’s Big Life Fix docuseries where teams of inventors create new and life-changing solutions for people in need, I had the opportunity to test and build a voice-controlled assistant for a woman called Susan. Susan has been living with a progressive form of Multiple Sclerosis for over 20 years and is now unable to complete everyday tasks for herself easily. With full-time carers, she relies on others to wash and dress her and has no ability to even change the channel on the TV without help.

While voice technology seemed like it would provide the smoothest pathway to overcoming Susan’s physical difficulties, Susan has never used a smartphone, so propelling her straight into an interaction with a voice assistant was never going to be easy — we had to think cleverly to help her learn to communicate with an incredibly alien technology.

Getting the process just right ain't an easy task. That's why we've set up 'this-is-how-I-work'-sessions — with smart cookies sharing what works really well for them. A part of the Smashing Membership, of course.

Explore features →

The result for Susan is a highly customized voice-controlled assistant that now empowers her to complete everyday tasks with the freedom that others take for granted — from making a phone call to family, to listening to music. Built as an enhanced version of Amazon Alexa technology on their Echo Dot device, Susan’s voice assistant also involved physical customization as we 3D printed a casing in the shape of her favorite animal, an owl.

As we rapidly experimented and iterated on a solution for Susan, my team and I uncovered dozens of intricacies that come with designing for voice in a more inclusive and accessible way. Although it was a unique project, there were three key takeaways that are applicable to any VUI project.

1. Make It Personal

The tech works. It’s not just a matter of sitting back and waiting for computing power to increase in line with user expectation. We found the voice detection, recognition, and synthesis of each of the devices far more powerful than we anticipated. And it’s not as though there’s a lack of choice. There are over 30,000 Alexa skills on Amazon with an average of 50 new ones being published daily. Skills are specific capabilities that enable designers and developers to create a more personalized voice experience when using devices like the Amazon Echo Dot. They operate much like an app within the App store on your smartphone, allowing you to customize your voice assistant the way you please.

However, there currently is a big barrier to access. Skills must be added via the app rather than the device, often negating the benefits of a VUI and breaking the conversational flow (not to mention excluding those who can’t/won’t use a smartphone). This makes the process feel clumsy and disjointed at best, completely isolating at worst. Even once a skill is installed, no skill visibility and a restricted time frame for interaction result in a lack of confidence and anxiety; can it do what I want? How do I talk to it? Has it heard me? So, how do you build that connection and trust?

For Susan, it meant stripping away the unnecessary and presenting a curated selection of core functionality. By personalizing the content to the unique behaviors and requirements, we presented much-needed clarity and a more meaningful experience. Susan wanted to perform key tasks: answer the phone, make a call, change the TV channel, play music, and so on. By getting to understand her and her needs, we created an assistant that always felt relevant and useful. This was quite a manual process, but there is a huge opportunity for machine learning and AI here. If every voice assistant could offer an element of personalization, it could make the experience feel more relevant for everyone.

As we were designing for one individual, we could easily tailor the physical elements of the product for Susan. This meant designing — then 3D printing — a light diffuser in the shape of an owl (her favorite animal and something with a significant meaning to her). The owl acted as a visual manifestation of the technology and gave her something to talk to and project towards. It was her guide that gave her access to those skills she wanted, such as listening to music. As it was personal to her, it made the potentially alien, intimidating technology feel much more approachable and familiar.

Humanizing technology helps make it more accessible: Susan’s personalized owl glows in response to her voice, letting her know she is being heard and understood. (Large preview)

Although a fully custom 3D printed housing isn’t an option for every VUI project, there is an opportunity to create a more relevant device for people to communicate with, especially if their needs or usage of home assistants is quite specific. For example, you might talk to a voice-enabled light about your home lighting and a fridge about your groceries.

2. Think About Audio Affordances

Currently, the user does all the heavy lifting. With an obscured mental model and no hand-holding from the tech, we’re forced to imagine our desired endpoint and work backwards through the necessary commands. The simplest tasks aside (set a timer for 5 minutes, play Abba on Spotify, etc.), that’s incredibly hard to do, especially if you suffer from ‘foggy moments’ something that Susan explained to us — difficulty in finding the right words.

When Apple famously used skeuomorphic visual elements for their early iPhone apps, the user gained valuable, familiar reference points which afforded its use and method of interaction. Only once the mental model became more established did they have the freedom to move away from this literal representation, into their current flat UI.

When designing our VUI, we decided to lean on the well-established menu system seen throughout digital and web navigation. It’s a familiar tool which demands less cognitive processing from the user and allowed us to incorporate methods of way-finding that didn’t result in starting from the beginning if things went wrong.

As an example, Susan found verbalizing what she wanted, in the time frame offered by current digital assistants, a stressful and often unpleasant experience; often compounded by an error message from the device at the end of it. Rather than expecting her to give an explicit command such as “Alexa, play Abba from my Spotify playlist,” we decided to create a guided menu tool that could help her start slowly and get incrementally more specific about what she wanted Alexa to do.

Susan’s owl now prompts her with a curated list of options such as, “Play Music” or “Watch Something.” If she chooses music, it gets more specific as she progresses through each decision gate, to uncover the genre she feels like listening to; in the case of Abba, she would select “60s music.” This enables Susan to navigate to her desired outcome much more easily, and at a pace that suits her. All the while, the owl was glowing and responding to her voice, letting her know she was being heard and understood.

Susan’s voice assistant gives her back some of the independence she lost to her condition, from empowering her to making a phone call to family, or simply listening to music. (Large preview) 3. There’s More To VUIs Than Voice

The non-lexical components of verbal communication impart a great deal of meaning to a conversation. Some can be replicated by the synthesized voice (intonation, pitch, and speed of speaking, hesitation noises, to name a few), but many can’t (such as gesture and facial expression). The tangible elements of the product need to replace these traditional, visual cues for the interaction for it to feel even slightly natural. But there’s more to it than that.

Firstly, when someone interacts with a product designed to replicate human behaviors, the visual components are interpreted by the user’s preconceived notions of the world (both inherent and learned) and affect their emotional responses. If something looks imposing and cold, you’re much less likely to initiate a conversation than with something that looks cute and cuddly.

In our case, as the technology was so foreign to the user, we needed to make it feel as familiar and inviting as possible — an owl. In doing so, we hoped to remove the feelings of anxiety and frustration we had experienced with other products. We also amplified the visual side of it — there is one color for an idle state — a gentle glow, almost like breathing, but when Susan says the wake words the light changes to awake and listening.

You can go further. Apple, for example, has a full-color display on their Homepod which affords a higher level of nuance to their interaction and visualization. Adding a visual experience might sound counterintuitive, but visualizations can be very helpful for the user.

Conclusion

Although applied to an individual use-case, these top-level learnings can help any project hoping to utilize the inherent benefits voice affords. Personalizing the content (where possible) provides much-needed clarity and a logical, relatable navigation system reduces cognitive load. Finally, don’t underestimate the importance of the visual components; when done well, they not only deliver fundamental conversation cues, they set the tone for the whole interaction.

For those looking to experiment with voice, Amazon now showcases tens of thousands of skills from companies like Starbucks and Uber, as well as those created by other innovative designers and developers. The Alexa Skills Kit (ASK) is a collection of self-service APIs, tools, documentation, and code samples that make it easy for you to add skills to Alexa, and start creating your own solutions. Wondering if voice even makes sense? Here’s some considerations before you get started.

(ra, il)
Categories: Web Design

UX And HTML5: Let’s Help Users Fill In Your Mobile Form (Part 1)

Mon, 08/20/2018 - 04:45
UX And HTML5: Let’s Help Users Fill In Your Mobile Form (Part 1) UX And HTML5: Let’s Help Users Fill In Your Mobile Form (Part 1) Stéphanie Walter 2018-08-20T13:45:31+02:00 2018-09-07T14:07:14+00:00

Forms are one of the most basic primary interactions users will have with your websites (and mobile apps). They link people together and let them communicate. They let them comment on articles and explain to the author how they strongly disagree with what they’ve written. They let people chat directly on a dating app to meet “the one”. Whether for forums, product orders, online communities, account creation or online payment, forms are a big part of users’ online life.

It’s 2018, and we have more mobile than desktop users around the globe. Yet, we still treat those users as second-class citizens of the web. Everybody writes and speaks about user experience all the time. So, why, why, why are so many websites and products still doing it wrong. Why is their mobile user experience damaged for half of the world? Why is it still a pain, why is it still super-hard to book a flight and register an account in a mobile form today? Users expect better!

Recommended reading: World Wide Web, Not Wealthy Western Web

This is the first part of a series of two articles. In this one, I will sum up some essential best practices to improve your mobile forms, including scannability and readability. I will guide you through label and input placement, size and optimization. We will see how to choose the right form element to reduce interaction costs. Finally, you will learn how to prevent and deal with errors on mobile forms.

In the second part, I will take a closer look at specific mobile capabilities and HTML5 form elements, and we will go beyond classic form elements to make unique and enjoyable web applications and websites.

Note: While most of the code enhancement in this article are web-related (because I don’t know Swift or Java), the usability best practices hold true for mobile applications.

Nope, we can't do any magic tricks, but we have articles, books and webinars featuring techniques we all can use to improve our work. Smashing Members get a seasoned selection of magic front-end tricks — e.g. live designing sessions and perf audits, too. Just sayin'! ;-)

Explore Smashing Wizardry → Form Design 101: Prioritizing Scannability And Readability

“A form is the name, value, pairs, in a structure for storing data on a computer barfed out as labels and input fields to human being.” This is a direct quote from Luke Wroblewski at a conference. Like him, I believe that most form usability issues come from this tendency to serve the structure of the database to users.

Strong Information Architecture

To build better forms, you first need to take a few steps away from your database’s structure. Try to understand how users want to fill in forms. This is where doing some usability testing and user research on your forms becomes handy. User mental models is a UX concept that can help you with that. Nielsen Norman Group describes it as “what the user believes about the system at hand”. Ask your tester to think aloud and tell you how they would fill the form. Which steps do they expect? What come first? What comes next? This will give you a better idea of how to structure your form in a more user-friendly way.

Visually grouping fields that belong together will also help users fill a form. In the code, use the fieldset tag to group them programmatically. It will also help screen readers understand the hierarchy.

Chunking information and grouping related pieces of information helps the human brain process this information in an easy, more readable way (Large preview)

If the form is long, don’t expose everything by default. Be smart about what you display. Use branching wisely to display only the fields that people need. In a checkout form, for example, don’t display all of the detailed fields for all of the shipment options. This will overwhelm the user. Display enough information to help them choose the right shipment option. Then, display only the details and fields related to that choice.

User attention spans get shorter with time: Ask for optional things at the end of the form. For instance, if your form is a customer-satisfaction survey, ask for demographic information at the end. Better yet, auto-fill them, if possible. Ask users only for what’s necessary.

Finally, plan ahead for localization: What will happen when your form gets translated? What will happen, say, for German? Will your design still work?

Label Placement And Input Optimization Single-Column Layout Works Best

Due to the lack of space, you don’t get endless options for placing labels and fields on mobile screens:

  • Present fields in a single-column layout. There’s no room on mobile for multiple columns. Multi-columns forms are not a great idea on desktop either anyway.
  • In portrait mode, it’s better to place the label on top of the field so that users can see what’s in the field when they type.
In portrait mode, it’s better to put the label on top of the field. (Large preview)
  • In landscape mode, the screen’s height is reduced. You might want to put labels on the left and inputs on the right. But test it to make sure it works.
In landscape mode, you want to put labels on the left and inputs on the right. (Large preview)

For more on label placement, see Baymard Institute’s “Mobile Form Usability: Place Labels Above the Field”.

Labels Should Be Clear And Visible And Work Without Context

Remember that as soon as a field gets focus, the keyboard opens and will take at least one third of the screen’s area. On small mobile screens, users will also have to scroll to fill the form. This means that they will lose part of the context while filling the form. Plan accordingly:

  • Your labels should be clear, visible text that can be read and understood without context. User should be able to complete each label and field pair as a separate task, even if they lose context.
Just “Address” without context is more complicated to process that “Shipping Address”. (Large preview)
  • Avoid jargon, abbreviations and industry-specific language whenever you can.
  • Be consistent. If you use “customer” in a label once, stick with that word. Avoid using “clients” later because it might confuse users.
  • The font size should be big enough. Test your form on real devices as soon as possible, and adjust the size accordingly.
  • All-caps text can be hard to read for some users. You might want to avoid using all-caps text on labels.
  • The label copy should be short and scannable. If a field needs clarification, don’t put it in the label. Use a field description instead.
Avoid full caps, jargon and very long labels. (Large preview) Input Size Best Practice

If possible, the size of the input element should match the size of the expected content. This will help users quickly fill in the form and understand what’s expected.

Properly sized inputs help the user scan the form and understand what is expected in the fields. (Large preview) Using Masks To Avoid Splitting Inputs On Mobile

Don’t split inputs just for the sake of formatting. It’s especially annoying on mobile, where users can’t use the keyboard to navigate between fields. It requires extra taps just to go to the next field to fill in the form. You might be thinking, “But I’ll automagically put the focus on the next field when I get the required number of characters in that field”. That could work. But you will have taken control of the UI, which becomes unpredictable for the user. Also, it would be a pain if you automagically sent them to the next field and they needed to correct something in the last field. Finally, it’s more complicated to guess what’s mandatory with split inputs. So, let’s stop playing the “But what if” game and simply not split inputs.

Don’t split the phone number into many little inputs. (Large preview)

I get it: You still want to be able to format your user’s data in small pieces to help them fill in your fields. And you are perfectly right about that. To do so, you could use masks. Instead of splitting an input, just put a mask on top of it, to visually help the user fill it. Here is a video example of what a mask would look like to help users fill in a credit-card field:

Masks help to prevent errors by guiding users to the correct format. Avoid gradually revealing them — show the format directly. Also, avoid putting fake values in the mask. Users might think it’s already filled. That’s why I’ve replaced the numbers with a little “X” in my demo. Find what works best for your type of input.

Finally, remember that some data can vary between countries, and sometimes the format changes, too (phone numbers, for example). Plan accordingly.

Efficient Fields Descriptions

Displaying efficient field descriptions can make the difference between a seamless and a painful form experience.

What Can Descriptions Be Used For?

Descriptions can help users in so many ways. Here are a few examples.

  • What Exactly Are You Asking For?

    For whatever database-related reason, some shipment companies ask for "Address 1" and “Address 2” fields. This is highly confusing for users, but you might not have a choice here. Add description fields to help users understand what they need to put in each field.

    Inline descriptions help users understand why you need this information. (Large preview)

    The same goes for acronyms and abbreviations. I know I said that you should avoid them, but sometimes you can’t. If you work on complex forms for a particular industry, for instance, they might have their own set of abbreviations. Any new user who needs to fill in the form might not be familiar (yet) with those abbreviations. Having a description available somewhere will help them.

  • Why Do You Need This Information?
    Users might be reluctant to give you personal information if they don’t understand why you need it and what you will do with it. But sometimes you still need to ask for such information for legal reasons (like date of birth for a website that sells alcohol). Using field descriptions here will help users understand why this kind of information is needed.

    On e-commerce websites, you might want to ask for the user’s phone number in case the delivery person needs to contact them. This is a legitimate reason. So, again, use descriptions to explain to e-commerce users why you need their phone number.

    Sometimes you need information for legal or practical reasons. Again, tell the user why. (Large preview)
  • “Where Do I Find the Information?”
    If your users need to find certain information somewhere else in order to fill a form, tell them where to find it. I worked on a mobile app that lets user track their house. Users needed to pair the app to the monitoring device using a serial number. It’s not very easy to find this serial number on the device; it requires some instruction. We added a little ? button next to the serial number field. The button opens a modal that shows a picture and some indication to help the user understand where to find the serial number on the monitoring device. E-commerce websites do the same with promo codes: They give indicators that tell users where to find the codes. Users can tap on the link (left) or the question mark (right) to open a popup where they can find extra information to help them fill in the field. (Large preview)
  • “How Should I Format The Information?”
    Some fields need a particular format. In this case, use descriptions to let users know the formatting rules up front. Here are a few examples:
    • Phone number: do I need to put the international dialing code (+xx) in front of the field?
    • Is there a maximum length? Twitter on mobile does a good job with that one.
    • When dealing with monetary amounts, is the format with comma (like 10,000) or a space (like 10 000)?
    • What format do you expect for dates? I’ll let you check on Wikipedia what a nightmare that is. The difference between DD MM YY and MM DD YY can cause a *lot* of trouble to users when booking online.
    Note that a lot of those formatting issues can be solved by input masks. We will come to that later in the article (or you can jump right in if you are impatient). In the old 180-character days, Twitter used to tell you exactly how many characters you had left. Also, the date format varies from one country to another, so you might want to explain what to expect. (Large preview)
How To Display Descriptions

In the examples, above, we saw a few ways to display field descriptions. Here is a summary of what to do:

  • Inline descriptions should be directly visible and displayed next to the field.
  • If you need more in-depth descriptions with heavy content, you can use tooltips or modals. Tooltips are generally triggered on hover on desktop and on tap on mobile. The same goes for the modals: Open it when the user taps the help icon or “see more” link, for instance.
Be Careful With Placeholders

I get it: it’s tempting to remove fields on mobile to gain space and use placeholders instead. We’ve all gone down that road. But please don’t. The HML5 specification is clear about this: “The placeholder attribute represents a short hint (a word or short phrase) intended to aid the user with data entry”. And here is why:

  • The placeholder disappears when the user starts typing. The user must then rely on short-term memory to remember what they are supposed to put in the field. If they can’t, they will need to empty the field to see the indication.
  • It’s hard for users to double-check fields before submitting because the fields no longer have any label indications.
  • It’s hard to recover from errors once a field has been submitted because, again, there’s no label to help the user.
Placeholders rely on short-term memory. They make forms hard to check before submission. And recovering from errors is hard, especially when error messages don’t help much. (Large preview)

Even if you use placeholders with labels, you might still have some issues. It’s hard to tell the difference between a filled field and a field with a placeholder. I’m a UX designer who writes about mobile form design and even I got tricked last week by one of those. If it happens to me, it will happen to your users — trust me on that one. Finally, most placeholders have light-gray text, so you might have some contrast issues as well.

It’s easy to mistake some of these fields for being filled in. The right screenshot is something I’ve seen online. I’ll let you guess what is filled in and what is not. (Large preview)

If you want to go deeper in this topic, there’s a great article named “Placeholder Attribute Is Not A Label, and also Joshua Winn and FeedbackGuru go into detail on why this is a bad idea. Nielsen Norman Group also wrote a piece on the topic, named “Placeholders in Form Fields Are Harmful.”

Placeholders are not mandatory in HTML5. From a usability point of view, you most certainly don’t need a placeholder in every field of your form. But with the massive adoption of Bootstrap and other frameworks, it looks like a lot of people just copy and paste components. Those components have placeholders, so I guess people feel kind of obligated to add something to the placeholder in the code? If your form’s placeholders look like “Please fill your — label — here”, you’re doing it wrong.

I’m not joking: I’ve actually seen forms with 12 fields, with each placeholder less useful than the last. (Large preview)

Labels inside fields could, nevertheless, work well for short forms in which fields are predictable. Login forms are a good candidate for this. But please don’t use the HTML5 placeholder to code this. Use a real label in the code and move it around with CSS and JavaScript.

Labels inside fields can work on really short forms, like login forms, where users don’t have a lot of information to remember. (Large preview)

Since the success of Android’s material design, a pattern has started to emerge: the floating label. This label is inside the field when the field is not filled in, so it takes a bit less vertical space on mobile. When users start interacting with the field, the label moves above the field.

This looks like an interesting way to gain some space, without running into the “placeholders in place of labels” issues cited above. Nevertheless, it does not solve the problem of users possibly mistaking a placeholder for filled-in content.

The floating label, even if not perfect, is an interesting alternative to gaining vertical space on the screen. (Large preview) Interaction Cost Reduction For Successful Forms

Reducing the interaction cost (i.e. the number of taps, swipes, etc.) of users achieving their task will help you build a seamless form experience. There are different techniques to achieve that. Let’s look at a few of them in detail.

A Magic Study On The Internet Told Me To Reduce The Number Of Fields

More fields mean fewer conversions, right? You might have encountered the “we reduced our subscription form from 11 to 4 fields, and it drove up conversions by 160%” study. It’s a classic. And if you look at their contact form, it kind of makes sense. Why would users want to fill in 11 fields just to contact the company? You can’t ask such a big commitment of people who barely know you, right?

Start by asking only for useful information. Why do you need a person’s gender to create an account for them? Why do you have two lines for the address if your subscription form is for an online service?

Ask only for the information you need. And then ask for the information in context. If you have an e-commerce website, users might be more inclined to give you their address in the shipping section of the checkout process than when they register. It will make your e-commerce registration form so much easier to fill on mobile!

Ask for the user’s address in the shipping section of the checkout, not when they register. (Large preview)

Also, don’t blindly trust every statistic and study you find on the Internet. Remember the 11-fields-to-4 study? Well another more recent study showed that by reducing fields from 9 to 6, conversions dropped by 14%. Shocking, isn’t it? Why? Well, they removed the most engaging fields. Long story short, they then went back to 9 fields, put the most important on the top, and voilà, conversions increased by 19.21%.

The bottom line is that while these studies are interesting, those websites are not your website. Don’t blindly trust the first study you find on the Internet.

So, what can you do? Test. Test. And test!

  • Do some user testing to see the time to completion of your mobile form.
  • Measure drop outs.
  • Measure problems with certain fields.
  • Measure the frustration associated with certain fields. How willing are users to give that information? How personal is that information?
Optimizing Touch Interactions Making Controls Touch-Friendly

If your fields are too small or hard to reach, users will make errors and will need extra interactions to achieve their goals. Remember Fitt’s law? You could apply it to mobile design as well: Make your labels, fields and form controls easy to tap by increasing the touch target size. For labels on the web, a little more padding can increase the touchable area. Sometimes you will also need to add some margins between elements to avoid missed taps.

Also, don’t forget to link labels with their components by pairing for and ID values. That way, if the user misses a tap on the label, the corresponding field will still get focus.

On mobile, respect mobile touch-optimized best practices, and make sure inputs are big enough to be easily tappable. (Large preview)

Steven Hoober conducted some user research on touch areas. You’ll find a summary in “Designing for Touch”. Based on what he discovered, he built a little plastic ruler tool: the mobile touch template. The tool could help you make sure your touch areas are big enough for mobile forms and more generally for mobile design.

Image from Steven Hoober’s mobile touch template. (Large preview)

To learn more about designing for touch you can read the following:

Providing Feedback

Mobile users don’t have a mouse (no kidding), so they don’t get the “click” feedback that desktop users get when hitting a button. Mobile form users need clear feedback when interacting with elements:

  • Provide a focus state for the form field that the user is interacting with.
  • Provide visual feedback when the user interacts with a button.

I’m not a big fan of material design’s ripple effect on buttons. But I must admit that the animations on Android provide clear feedback when the user interacts with a button.

Honor The Next And Previous Button Order

Finally, honor the next and previous buttons on mobile keyboards. Users can use them to quickly navigate fields. The tabindex order should match the visual order of fields and components.

iOS has small arrows on the keyboard to go from one field to another. (Large preview) Avoid Dropdowns On Mobile If Possible

Dropdowns (the HTML select element) on the web require a lot of tabs and interactions. Therefore, as Luke Wroblewski said, they should be the UI of last resort. Many other UI components work better than dropdowns in many situations.

Segment controls and radio buttons are good alternatives to dropdowns if you have between two and four options. Why hide the options under a dropdown when you can show them all directly on one screen? Note that, like radio buttons, segment controls are mutually exclusive.

Example of segment controls in the iOnic library. (Large preview)

A country list is a good candidate for a component. A dropdown of over a hundred countries is an interaction nightmare on mobile. It’s OK if you are looking for Afghanistan (at the beginning of the list) or Zimbabwe (the end of the list). If you’re looking for Luxembourg, you will end up in a game of scrolling to reach the middle of the list, going too far to the letter M, trying to come back to L, and so on.

Long dropdowns can be replaced by predictive text input fields. When the user starts typing L, the interface would propose nine countries. If they add a U — voilà! — Luxembourg it is. Four interactions instead of two, versus as many as six or seven scrolling interactions with the dropdown.

Long dropdowns are a nightmare when you’re searching for France. Predictive fields work better. (Large preview)

If you need users to pick a date, forget about splitting it into a day, month and year dropdown like people are used to doing on paper forms. Replace multiple date dropdowns with a date picker. The HTML5 input type=date works in most cases. But you might have some special needs and end up building your own date picker in JavaScript, especially if you are in the booking business (hotels, cars, flights).

A double date-picker built in JavaScript makes it easy to pick arrival and departure dates with a minimum of interaction (Large preview)

In his article “Mobile DropDowns Revisited”, Klaus Schaefers explains how using a date-picker for arrival and departure dates made interactions 60% faster.

A date-picker, using HTML5 or JavaScript, instead of dropdowns, via Mobile DropDowns Revisited. (Large preview)

Let’s stick with the booking business. Suppose the user needs to add multiple travellers to their itinerary. You can **replace the dropdown *with a* stepper** to select the number of passengers. A stepper is a control that allows the user to increase and decrease values simply by tapping on + and - buttons. That tends to be faster when fewer than six persons have to be added. It’s also more intuitive. Below is an example of a stepper used in the Android-native Airbnb app to select guests, and on the mobile-optimized website of Kayak to add passengers.

A stepper is used in the Android-native Airbnb app to select guests and on the mobile-optimized website of Kayak to add passengers. (Large preview)

A final alternative to dropdowns is the list view. The options would be listed in a specific subview, as radio buttons, for instance. This is mostly how Android settings work.

In our monitoring app, when the user clicks on “notification type 1”, it opens a list view with the options. (Large preview) Getting Smart With Auto-Completion

If you want to decrease the interaction cost of your form, be smart. Don’t ask for information that you can auto-detect or guess based on other information users have given you. Autocomplete and prefill as much as you can.

Places and Addresses

If the user searches for a place or needs to enter an address, you can offer auto-completion to help them. As they type, an API would fill in the rest of the address for them. This also reduces errors.

You could use:

In the Algolia Place demo, as the user types, it offers suggestions and can autocomplete the field.

In France and many other countries, you can guess the city based on the area code. So, if a French user enters an area code, you could automatically auto-complete or at least propose the city. My country, Luxembourg, is small (don’t make fun of me). My area code is linked to my street. So, if I enter my area code, the form should even be able to suggest my street.

Credit Cards

Another area where auto-detection is easy is credit cards. You don’t need to ask the user what type of credit card they have. You can auto-detect this based on the initial numbers they enter. There’s even a library that can do the job for you.


A demo of the payment script that detects credit card type. Using HTML5 Autocompletion (Autofill)

The HTML autocomplete attribute can prefill fields based on the user’s earlier inputs. This attribute has an on and off state. Some smart people have started working on a specification to make this more powerful and to extend the autocomplete attribute for form fields. The WHATWG also has an interesting list.

Chrome and other mobile browsers already support some of the extended values for credit cards and names. This means that users can prefill forms with their name and credit card data that they use on other websites.

Help users check out faster with Autofill (Source: Google Developers) (Large preview)

In short, when you must choose between different systems, count the number of interactions each is going to require.

Mistakes Happen: Handling Errors In Mobile Forms

The last step on our journey towards better mobile forms is handling errors and mistakes. We can try to reduce mistakes to ease the user’s cognitive load. We can also help them recover from errors, because no matter how great your form design is, mistakes happen.

Avoiding Errors While Filling The Forms

“Prevention is better than a cure,” my mother used to say. That’s also true of form design: Preventing errors will improve your mobile form’s experience.

Explicit Format Limitation

“Be conservative in what you do. Be liberal in what you accept from others.” This robustness principle can be applied to form fields as well. If possible, let the user enter data in any format.

If you think you need to limit what a user can enter in the field, start by asking yourself “why”. In the user experience field, we have a technique called “the three whys”. If the answer is “because blah blah database”, maybe it’s time to change things. For instance, why do you refuse special characters like é, à and ö in the user name field? I wrote an article explaining how rude forms are to me when I try to enter “Stéphanie” as a user name. I’m still trying to figure out a good reason for that (apart from database reasons).

If you have a good reason to require a specific format from users, state this up front. You can use HTML5 placeholders to give users a hint about what the data should look like, but again, be careful with those. You could also use all of the field description techniques explained at the beginning of this article. Finally, input masks can guide users towards the right format.

Marking Mandatory Fields (And Optional Ones)

Don’t wait for users to submit a half-completed form to tell them about required fields. If a field is mandatory, users should know about it. Marking mandatory fields with an asterix (*) and a legend has become a standard pattern for forms. The good part is that it does not take much space. The problem is that it has no semantic value, so it can cause accessibility issues if poorly coded and if you rely on people’s habits with form interaction.

You could instead explicitly mark both mandatory and optional fields with the words “required” (or “mandatory”) and “optional”. Both Baymard Institute and Luke Wroblewski agree on that. This avoids ambiguity with long forms on mobile, such as when using a scroller, proceeding with something else, then coming back and not remembering if mandatory fields were marked with an asterisk or something else.

A form with both mandatory and optional fields marked. (Large preview)

Eventually, the decision on how to mark those fields will depend on the design and length of the field and on the context. The best way to know whether you’ve made the right decision is, again, to test the form.

Sensible Defaults

Be careful about default selected options in forms. When I applied for my previous job, there was an information form. The marital status was optional. They made the first element in the dropdown, “divorced”, the default field. So, I could either not answer (because it was an optional field) and let the system believe that I was divorced, or correct this and disclose my actual marital status even if I did not want to.

Also, be careful about gender. Again, have an option for people who don’t want to disclose it; make clear why you’re asking for their gender; better yet, ask for pronouns, or don’t ask if you don’t really need to. If you are interested in this topic, I recommend “Designing Forms for Gender Diversity and Inclusion.” And if the gender is optional, again, don’t auto-check the first choice, otherwise people won’t be able to uncheck that radio button and choose not to answer.

Should I leave the default and lie, or put the right information even I don’t want to? (Large preview)

Smart defaults, on the other hand, can help users avoid mistakes when filling a form. Unless you’re in a Dr. Who episode, you’re not supposed to book a hotel in the past. Booking.com understands that. When you open the date-picker on the website, the default date is set to the current date and you can’t select a date in the past. When you select a return date, the default is the day after the departure date.

Booking.com’s smart defaults help users avoid mistakes. You can’t search in the past or before your arrival date. (Large preview) Less Painful Password Experience

I’ve written about password-less authentication, but you can’t always use those techniques. Users will eventually have to create a password and enter it in a mobile form. And most of the time, that experience sucks. Here are a few ideas on how to make it better and help users avoid mistakes.

  • When Creating An Account
    I won’t get into the details of what kind of passwords you should require and how many characters they should be composed of — plenty of articles on that topic are on the web — just make up your mind about your password criteria. When users create an account, be proactive, not reactive. For the love of Cthulhu, don’t let people guess. Tell users your password criteria up front.

    A lot of websites now show you a gauge for password strength telling you in real time what is missing. This is an interesting and excellent pattern. KLM uses it in its sign-in form: KLM sign-in form example (Large preview) But there are still some big problems with this design.
  1. They don’t tell users their password criteria up front. Users who want to generate a password (using a password manager, for instance) must first guess that they need to first interact with the field in other to see the password criteria.
  2. They limit the password’s length to 12 characters, but they never tell users how many characters are left. Sure, let’s add "counting the dots" to the cognitive load of building a password with so many criteria. After 12 characters, you can keep on typing on the keyboard, and nothing will happen.
  3. What happens if, like me, you reached the 12-character limit but haven’t met all of the criteria? Well, you would just have to delete the entire password and start over again.
  4. Finally, you must enter the password twice. How is a user supposed to remember and retype the password that they just created based on those criteria while counting the dots?
  5. Back to 1, generating a password with a password manager.

If KLM wanted to make this form better, it could provide a mask/unmask option for the password. Doing so, it would not need to ask for the same password twice. Users could visually check that the password they typed is the one they want.


TransferWise doesn’t solve my first problem in the list, but at least I can unmask while typing.
  • When Logging In
    In a login form, a mask/unmask password option would tremendously improve the user experience.
    A button to show and hide the password in a form.

    Amazon has an interesting history of iterating on passwords in its login form. It used to have a version in which you could not see the password. The next iteration allowed users to reveal it. Then, the password was revealed by default, and you could hide it. This is what is looked like in 2015:

    Showing Passwords on Log-In Screens, Luke Wroblewski, 2015 (Large preview)

    Amazon tested the last version, and 60% people got suspicious. So, they replaced the “hide password” unchecked checkbox with a “show password” checked box. This would show the password in smaller characters, under the field, while the user typed. This is what it looks like at the time of writing this article:

    Amazon’s show and hide password functionality (Large preview)

    As you can see, there’s always room for improvement.

Inline Validation

If you are familiar with usability principles, you might know the Gestalt law of proximity. On mobile, avoid the summary of errors at the top of the page, with no contextual information, after the user has tapped the submit button.

Instead, error messages should be located close to the errors themselves.

An example of inline validation (Large preview) Real-Time Validation

You also don’t need to wait until users hit the submit button. You can validate fields and display feedback while the user is filling them in.

A few tips:

  • As mentioned earlier, password fields would benefit from real-time validation and feedback on each keystroke.
  • You might also want to validate user names in real time when accounts are being created, to make sure they’re available. Twitter does a good job of that.
  • Don’t validate every keystroke. Wait until the user has finished typing. (Use JavaScript blur for web forms, or just wait a few seconds to detect inactivity.)

Note: *Mihael Konjević has written a nice article on “Inline Validation in Forms: Designing the Experience.” He explains the concept of “reward early, punish late.”*

“If the user is entering the data in the field that was in a valid state, perform the validation after the data entry.” “If the user is entering the data in the field that was in an invalid state, perform the validation during the data entry.”
Example from Keechma based on the article. Color Matters

I’m not saying that color matters just because of my current ginger, pink and purple hair color. Color really matters in form design.

There are some conventions on the web that you don’t want to break. Non-colorblind users know that red is for errors, yellow is for warnings, and green is almost always for confirmation or success. It’s best to stick with these three colors. Red can make people anxious, though. The user might think they’ve made a really serious mistake. Using orange or yellow for error messages could cause less panic. The problem with yellow and orange is that it’s hard to find colorblind-friendly hues of them.

Colors have different connotations across countries and cultures. Be careful with them. (Large preview)

Speaking of colorblindness: Color should not be the only way to convey an error message. This is an accessibility criterion.

In the example below on the left, the field with an error is in orange, and the field that has been corrected has turned green. I used a colorblind testing tool to take the screenshot in the middle: You can’t distinguish between the default gray border and the green one anymore. Adding some icons in the last screenshot ensures that the error messages are conveyed to colorblind people.

Color should not be the only way to convey error messages. The colorblind simulation in the middle shows that the green border cannot be seen by a colorblind person. (Large preview) Recovering From Errors: Writing User-Friendly Error Messages

At this point, we’ve done everything we can to help users fill our forms and avoid errors. But sometimes, despite our best effort, mistakes happen. It’s time to figure out how to help users recover from those mistakes.

First, remember: Don’t hijack control of the system. If a problem isn’t critical, the user should be able to continue interacting with as much of the rest of the interface as possible. Avoid those JavaScript alert error message and modals that blocks users whenever possible. Also, if your form needs some permission, request it in the flow of use. If permission is not granted, do not consider this an error because it is not. Be careful about the copy you use here.

You’re Not A Robot, And Neither Are Your Users

Robots are cool, I know. But you’re not a robot, and neither are your users. Yet so many error messages are still so poorly written. Here are a few tips when it comes to human-friendly error messages:

  • Never show a raw error message, like “An error of type 2393 has occurred. Server could not complete the operation.” Instead, explain what happened in human language and why it happened.
  • Never show a dead-end error message, like “An error has occurred.” Instead suggest ways to recover from the error. Write actionable copy.
  • Never show a vague error message, like “A server with the specified hostname could not be found”, with a “Try again” button. Instead, make error messages informative and consistent. Please don’t sound like a robot.
  • Don’t assume that people know the context of a message. Your users are not tech-savvy geeks. Instead, explain to them in plain language, without technical jargon, how to recover from this error.
Examples of non-human-friendly error messages. Eek! (Large preview) Beware The Language You Use In Messages

Whatever you write, avoid making people feel stupid about a mistake. If possible, leave out negative words; they tend to scare people and make them even more anxious. Use a courteous, positive, affirming tone instead.

Don’t blame users for mistakes; blame the system instead. The system won’t hold a grudge, I promise. Shift the user’s attention to how the system could not process the action, and explain to them how to find a solution.

A little trick is to read your own message out loud. It will help you hear whether it works or is too harsh or too casual, etc.

You could also get creative with error messages and incorporate imagery and humour to make them less threatening. This will really depend on your brand’s identity and tone, though.

To help you write better error message, I suggest you read the following:

Time To Submit The Form

The user has filled in the form, there are no more errors, and everything looks good. Finally, it’s time to submit the form!

The first rule is, don’t mask the submit button. Seriously! I wonder what twisted mind came up with this idea, but I’ve seen it in some forms. The submit button would be displayed only once all required fields were filled in without any errors. It’s disturbing for the user to wonder whether something is wrong or the form’s button has not loaded or the website is broken and so on.

If you don’t want users to be able to hit the submit button if there’s missing mandatory fields or there are validation errors, use the disabled HTML attribute on the submit input. You will need to re-enable the button using JavaScript once the form is valid and ready for submission.

Do not hide the submit button. Instead, deactivate it until users have filled in the required information. (Large preview)

If you have a primary and secondary call to action, use color, size and styling to show the hierarchy.

Example of primary and secondary actions (Large preview)

If are wondering whether the confirmation button should come before or after the cancellation button, so am I (and a lot of other people). If you are building a native app, stick to the OS guidelines. It’s become particularly fun since Android changed the button positions in its fourth version. On the web, it’s more complicated because there are no real guidelines. Regardless of the OS, here are some general guidelines for mobile-optimized submit buttons:

  • Give the call to action descriptive, actionable verbs.
  • Provide visual feedback when the user taps it.
  • If you have two buttons, make the primary action stand out.
  • Unless you’re working on a very specific back-office enterprise form (in which case, you’ll have a lot of challenges optimizing for mobile), avoid a reset button. Users might confuse it with the submit button and will lose all of their data by accident.
Conclusion

In this first part, I’ve discussed a lot of little techniques to take your form to the next level and help users fill it in. Some of these general guidelines and mobile best practices might not work 100% of the time — that’s the catch with best practices. So, always test your forms on real users and real devices, and adapt the guidelines to your users’ specific needs and experience.

Also, do some regression and automated functional testing — again, on real devices. Chrome’s mobile emulator won’t be enough to test touch-optimized forms. I say this because I had launched an e-commerce website with a search form that didn’t work on mobile. We only did automated testing using an emulator. Here is what happened. The search form was hidden under a search icon. You could tap on the button, which opened a box with the search field. It worked by emulating a mouse hover as a touch event. We tested tapping on the button, and it opened the box. Nobody tried to launch a search. So, nobody (not even the client) saw that the search field disappeared as soon as users tried to interact with it. What happened? When the input element got focus, the button lost the hover state, so it closed the box with the field. Automated testing was not able to catch this because the input was not losing focus. So, we launched an e-commerce website without search functionality on mobile. Not a super experience.

In the second part of this series, we will see more advanced mobile-specific techniques. We will see how to use cool HTML5 features to format fields and how to use mobile capabilities to take the mobile user experience to the next level.

(lf, ra, al, il)
Categories: Web Design

Designing For Micro-Moments

Fri, 08/17/2018 - 04:50
Designing For Micro-Moments Designing For Micro-Moments Suzanne Scacca 2018-08-17T13:50:09+02:00 2018-09-07T14:07:14+00:00

A couple of years ago, Google announced a new mobile-first initiative it wanted web designers and marketers to pick up on. This was our introduction to micro-moments.

These are not to be confused with micro-interactions, which are miniscule engagements websites have with visitors when they "touch" key points of the interface. A mouse changes its appearance when a user hovers over a clickable element. A display error appears after a field is incorrectly populated. A checkbox briefly enlarges and changes color after it’s been ticked off. These are micro-interactions.

A micro-moment, however, originates with your visitor. In Myriam Jessier’s "Things Designers Should Know About SEO In 2018", she sums up Google’s four micro-moments:

  1. “I want to know.”
  2. “I want to go.”
  3. “I want to do.”
  4. “I want to buy.”

Basically, these are four key moments in every consumer’s life when they decide to pick up their mobile device for a specific purpose. As such, it’s your job to know how to specifically design for these micro-moments.

Recommended reading: What You Need To Know To Increase Mobile Checkout Conversions

How You Should Be Designing For Micro-Moments

When a visitor arrives at a mobile website (or app), they’ve come with a clear motivation:

  1. “I want to know.”
  2. “I want to go.”
  3. “I want to do.”
  4. “I want to buy.”

Seems pretty simple, right? However, as Google launched this initiative a couple of years ago, its had time to quietly observe users in these micro-moments as well as the websites that have most aptly responded to them. As you will soon see, consumers have incredibly high expectations for what the mobile web can do for them. Basically, they want you to be a mind reader and anticipate their every need (and even their location) without them having to say a word.

Is your pattern library up to date today? Alla Kholmatova has just finished a fully fledged book on Design Systems and how to get them right. With common traps, gotchas and the lessons she learned. Hardcover, eBook. Just sayin'.

Table of Contents →

Is that intimidating? It shouldn’t be. You already have all the information you’d ever need to answer that question.

Here is how you should be designing your mobile website to respond to and draw in consumers as they experience these micro-moments:

1. Start With The Data

Google Analytics will help you decipher where they’re spending the most time productively on your website.

An example of Google Analytics’ visitor behavior breakdowns. (Source: Google Analytics) (Large preview)

Google Search Console will tell you which keywords are most effective in driving high-quality leads to the site.

An example listing of keywords and associated clicks and impressions for a website. (Source: Google Search Console) (Large preview)

Once you know where exactly visitors see the greatest value in your product, you can then turn to third-party tools like Answer the Public to give you some insights into what relevant questions your users may be asking about you.

An example of how Answer the Public provides micro-moment answers. (Source: Answer the Public) (Large preview)

Ultimately, this data needs to tell you all about your customers’ journey before they ever reach you. What exactly was the question that triggered them to pick up their smartphone and do that search? If you can identify those micro-moments, you can start using various design elements to respond to these questions.

2. Respond With Immediacy

According to Google:

People are searching at the exact moment they need something and are looking for places that can meet their immediate need. In other words, when making these on-the-spot decisions, they are more loyal to their need than to any particular place.

Although we’ve heard a lot about customer loyalty to brands in the past, it’s interesting to get Google’s take on this matter.

While consumers may indeed still remain loyal to brands that take very good care of them and produce a high-quality product nearly 100% of the time, this opportunity to steal attention from those customers in one of their micro-moments is real. Do that enough times and your brand and website could realistically win that customer over so long as you are there every time they go searching to fill that need.

One of the ways you can do this is by providing users with instant solutions. Is your business open now? Can you mail out that new product same-day? Will there be an open table at your restaurant tonight? Answer that immediately and you could find conversions increase dramatically.

Take the Delaware State Fair website, for example.

The top of the Delaware State Fair home page gives users easy access to everything they want to know and do. (Source: Delaware State Fair) (Large preview)

Look at the top of the homepage. There are the dates of the fair, which probably answer one of the most commonly searched questions. There is a link to the concert lineup as well as calendar, which answers anything people would want to know about special events they might want to go to. And then there’s a button to buy tickets right away. It’s all right there.

Office Depot is a company that also explicitly addresses immediate needs:

The Office Depot mobile site uses a variety of time-driven design elements to satisfy visitors’ needs. (Source: Office Depot) (Large preview)

As you can see in the example above, Office Depot uses a number of design tactics and elements to play into this need for immediacy.

  • There is a search bar at the very top. Consumers don’t have to even bother with navigation or scrolling through pages if they don’t want to/have the time to.
  • You’ll also see that the closest store’s hours are posted and boldly tell me how quickly I can have any products available in store.
  • Finally, you have the promotional categories for upcoming needs for parents that are about to send kids back to school.

Another website is Universal Studios Orlando; it does a great job sparing mobile users the trouble of sifting through irrelevant information and instead gets them to exactly what they need:

Universal Studios includes immediate options for research and booking on the home page and navigation. (Source: Universal Studios) (Large preview)

Aside from a single banner at the top of the home page, the Universal Studios website design gives visitors exactly what they want right away. The navigation includes only the most pertinent links to information and booking as does this succinct section on the home page. There’s really no time to waste when the options are so clear.

And here is one final example of a website that deals in immediacy, albeit with a more subtle design technique: Nordstrom:

Nordstrom appeals to immediacy with this one subtle trick. (Source: Nordstrom) (Large preview)

As you can see, this is a pretty typical e-commerce product page. However, there’s one key difference: Nordstrom is subtly calling attention to its Anniversary Sale and the main reason why there is a significant price drop for this purchase. Rather than use an obtrusive pop-up to announce the sale and pester users to shop, it’s made the price change directly on the page and drawn attention to it with the highlighted text.

3. Respond With Relevant Content

According to Google:

Not only have mobile searches for ‘best’ grown over 80% in the past two years, but searches for ‘best’ have shown higher growth among ‘low-consideration’ products than ‘high-consideration’ products. In other words, we’re all becoming research-obsessed, even about the small stuff.

We understand that the opinions of family, friends, and colleagues matter greatly in the minds of consumers. But as more and more of them to turn the web to make their purchases, it means being open to trusting other opinions online as well — ones that may be more conveniently expressed from a company’s website, from an influencer’s blog, or from social media.

Wherever those words of wisdom happen to come from, it’s important to take Google’s research to heart. With so many consumers now obsessed with this idea of having the best of everything and being able to get it in a pinch, your website needs to be the answer to that question.

But that’s the tricky part. According to Google, it’s not as simple as being a dog food manufacturer and configuring your site to be the answer to:

“Best Dog Food”

Consumers experience these micro-moments at a granular level. Sure, there may be some who think, “What is the best dog food?” But isn’t it more likely that question would be more specific in nature? For instance:

  • Best puppy food?
  • Best grain-free dog food?
  • Best vegan dog food?

Let's take a look at Google, for example. Here’s a variety of searches for a singular “best of” concept:

Example of the variety in “Best” searches in Google. (Source: Google) (Large preview)

As you can see, it goes beyond the basic questions. Through your design and your content, you must be ready to answer the most relevant questions your users have about your product or service.

With content, you’ll be able to answer many of the “I want to know” questions that are related to the brand with things like:

  • Informational pages regarding services and products.
  • Whitepapers, ebooks, case studies, reports, and other long-form content that provide heavily researched answers on related matters.
  • Blog posts, vlogs, podcasts, and other shorter content that can dabble more in appealing to the emotions of consumers.
  • Tutorials and guides that directly answer questions that consumers are asking.

As far as the design piece is concerned, it’s your responsibility to highlight these pages, so visitors don’t have to dig through various parts or layers of the site (like the footer or secondary navigation) to find their answers.

Google told them it was here, so it’s your job to get them right to it.

The navigation will play a big part in this, as evidenced by Globus Journeys:

Globus Journeys provides answers to micro-moments in the navigation. (Source: Globus Journeys) (Large preview)

As you can see in this example, Globus Journeys answers many of those micro-moments right within the navigation: tips on touring (Touring 101), tips on travel best practices (Travel Tips), deals available for travel (Deals & Offers), etc.

Another way to use navigational design to inform visitors on what they’ll learn/know from this experience can take place on the blog. Salesforce has an interesting example of this:

Salesforce includes a navigation menu for the blog. (Source: Salesforce) (Large preview)

There is the standard navigation for the Salesforce website, and then there is the navigation that’s specific to the Salesforce blog. This gives you — as the designer and planner of the site’s layout — a chance to better and more clearly organize content found within it. So, when visitors show up and want to know tips specific to one of those categories, it doesn’t require random searches or (even worse) endless scrolling through a full blog feed.

Another way you can more quickly and thoroughly inform visitors on topics of interest to them is by using strategically placed sections within blog posts.

While you likely won’t have anything to do with the writing of a website’s blog content, you will have control over its layout and formatting. The first thing you can do to expedite the knowledge acquisition process is by using callouts to detail and link to the various sections covered on the page as Be Brain Fit does:

Be Brain Fit calls out a linkable index of topics from the blog post. (Source: Be Brain Fit) (Large preview)

Of course, the post itself is easy to scan, so readers could guide themselves to the most relevant parts. However, by placing this towards the top of the piece, you’re enabling them to get right to the information they seek.

I’m also going to suggest that pop-ups would be helpful in this matter.

I know, I know. Mobile pop-ups can be annoying, but not when they’re used properly as Fit Small Business has done here.

Fit Small Business not only provides all the information needed, but also offers an alternative solution to what they seek. (Source: Fit Small Business) (Large preview)

I encountered this blog post after doing a search for the best way to create a Facebook page. This was one of the links on the first SERP. I was actually quite pleased with the post as a whole. It broke it up into easy-to-follow steps, attractive and informative visuals, and got me the answer I needed.

However, I was especially pleased to see the bottom banner pop-up after I finished getting through the post. Not only has Fit Small Business attempted to reach its audience by providing helpful content, but it’s also providing an alternative solution to anyone who got here and realized, “Eh, I really don’t want to bother with this on my own."

4. Respond With Geotargeting

According to Google:

Looking for something nearby — a coffee shop, noodle restaurant, shoe store — is one of the most common searches we do. In fact, nearly one-third of all mobile searches are related to location.

Here’s the thing though: users aren’t using “near me” qualifiers as much anymore.

Google demonstrates how location qualifiers are decreasing in use. (Source: Google) (Large preview)

According to Google, this is because many consumers now assume that search engines, websites, and mobile apps are tracking this sort of information already. They expect that if they search for something like “dog food,” Google will automatically serve them the most relevant results — and that includes taking into account location proximity.

In Google’s research, it found that about two-thirds of mobile consumers are more likely to buy something from a website or app if information is geographically personalized. There are a plethora of ways to communicate this local-friendliness to visitors — through the copy, through various design elements, and even photos.

Google is a pioneer in this space and so I want to give it a special shout-out in this section for what it does with search results:

Google’s auto-populated search results aren’t just for Google. (Source: Google) (Large preview)

The biggest thing to take away from here is the fact that Google provides its users with auto-populated search recommendations. These are based on the users’ geography, behavior, history, as well as what Google knows about the query itself. As you can see here, it expands on Baltimore to provide more specific results based on the area of the city in which the user wants to drink.

With AI-assisted search functionality, any website can offer this same level of smart search for its users.

Of course, you first need to get access to visitors’ geographic data before you can provide them with these kinds of smart and geographically relevant results. One way to do this is to require them to sign in and fill out a profile with these details. Another way, however, is by serving them with this geotargeting request as Best Buy has done:

Best Buy requests for access to users’ geographic location. (Source: Best Buy) (Large preview)

Once you have access to a visitors’ current location, however, you can start providing them with information that helps them with the “I want to go”, “I want to do”, and the “I want to buy” micro-moments that caused them to reach for the phone in the first place.

Here is what the Best Buy website shows me after I granted it permission:

Best Buy uses its visitors’ location to provide helpful in-store visit details. (Source: Best Buy) (Large preview)

The top of the page now displays the nearest location to me as well as opening hours. As I peruse the rest of the site, I will receive relevant information regarding in-store product availability, buy-online-pick-up-in-store options, and so on. This is a really great option for businesses with a sales website and brick-and-mortar location that want to merge the two experiences.

You could also benefit from using this on websites that offer services, appointments, and reservations. Here is an example of what The Palm Restaurant does with my information:

The Palm Restaurant streamlines the reservation process with geotargeting. (Source: The Palm Restaurant) (Large preview)

To start, it uses my information to let me know right away if there even is a location close to me. Philadelphia isn’t too far, but it’s still nice to have the address fully displayed so I can make up my mind about whether I want to dine there. And, if I do, I can choose the “Reservations” button above it.

What’s especially nice about this is that the reservation form is pre-populated:

The Palm pre-populates its reservation form based on user information. (Source: The Palm Restaurant) (Large preview)

As you can see, it’s used a mixture of my geographic location along with the most popular reservation types (i.e. two people at 7 p.m.) to pre-populate the form. This saves me, as the user, time in filling it out and making my reservation.

5. Respond With Convenience

According to Google:

Every day, people are becoming more reliant on their smartphones to help make last-minute purchases or spur-of-the-moment decisions. In fact, smartphone users are 50% more likely to expect to purchase something immediately while using their smartphone compared to a year ago.

Recently, I wrote a post about what you need to know to increase mobile checkout conversions. The underlying message was that mobile consumers have certain expectations that need to be met if you intend on converting them there (as opposed to switching back to desktop).

  • Convenience in getting the information they want is one of them.
  • Speed in getting to and through checkout is another.
  • Handling their contact and payment information securely is the final piece.

Clearly, web designers are doing something right as over half of smartphone users reach for their phone to buy something and subsequently do. But it can’t stop with the 10 tips offered in that article. You need to be able to predict what they’re going to purchase and what exactly they want to do when you catch them in those exact micro-moments.

Let’s use UPack as one example.

UPack includes a price quote form at the very top of the website. (Source: UPack) (Large preview)

At the very top of every page is a short price quote form that asks only the most pertinent details they need in order to provide a quote to interested customers. By anticipating that’s what they’re looking to do when they visit a moving company’s website, UPack likely experiences very high conversion rates.

However, if someone should arrive at this form and wonder, “Should I even bother with a quote from UPack?”, they’ve provided an answer to that on the next step down on the home page:

UPack uses an explainer graphic to sell the value of its service right away. (Source: UPack) (Large preview)

This explainer graphic is simple. It includes four points and shows how exactly someone uses the UPack service to move their home from one destination to another. When someone arrives there with the intention of getting help with their move, UPack has already made it all the more simple in just one scroll and two panels of the home page.

Then, you have a company like HostGator that doesn’t waste any time at all:

HostGator’s home page includes smart design callouts that sum up its services. (Source: HostGator) (Large preview)

If someone shows up on a web hosting company’s website — especially one that is well known as they are — of course they know what they want to do. Now, they could hop into the navigation and dig deeper into the various hosting plans (which some may do). However, HostGator is probably hoping to appeal to two specific audiences with these “Buy Now!” callouts on the home page:

  • The web developer who knows exactly which plan he or she needs, and doesn’t need a full page to explain the benefits to him.
  • The small business owner who doesn’t know a thing about web hosting, but trusts HostGator’s good name and just wants to get their web hosting purchases ASAP.

This is a really good choice of design techniques if you know that a good portion of your audience will be immediately ready to buy upon entering the site. If they don’t have to click through to another site, don’t make them do it.

And, of course, CTAs, in general, are an important element to use when designing for micro-moments. When they’re designed well — colorful, large, well-labeled — you’re essentially giving your users a shortcut to conversion.

BarkBox uses a number of these right on its home page:

BarkBox has a number of CTA shortcuts available on its website. (Source: BarkBox) (Large preview)

Since the brand is particularly well-known among dog owners, this is a good move. While there are some people who enjoy scrolling through the site to see the funny dog pictures and find out more about what’s in this month’s BarkBox, if they’ve arrived here on mobile, they shouldn’t have to wait to subscribe. BarkBox provides those shortcuts in a number of locations, ensuring there’s no friction between its customers and their goals.

Wrapping Up

It’s pretty amazing to watch the web change so quickly as consumers become more trusting of their mobile devices. Now, nearly two years after Google first began recommending that we design with micro-moments in mind, it appears that these suggestions have really paid off.

Designing for micro-moments gives us the opportunity to more effectively reach consumers in their moment of need. This, consequently, means reaching consumers who are in a more purchase-intent mindset as opposed to ones casually browsing the web. If you can use your data and design to actively reach consumers in their micro-moments, you can effectively increase your mobile site’s conversion rate in the years to come.

(lf, ra, yk, il)
Categories: Web Design

Scroll Bouncing On Your Websites

Wed, 08/15/2018 - 05:00
Scroll Bouncing On Your Websites Scroll Bouncing On Your Websites William Lim 2018-08-15T14:00:49+02:00 2018-09-03T12:33:55+00:00

Scroll bouncing (also sometimes referred to as scroll ‘rubber-banding’, or ‘elastic scrolling’) is often used to refer to the effect you see when you scroll to the very top of a page or HTML element, or to the bottom of a page or element, on a device using a touchscreen or a trackpad, and empty space can be seen for a moment before the element or page springs back and aligns itself back to its top/bottom (when you release your touch/fingers). You can see a similar effect happen in CSS scroll-snapping between elements.

However, this article focuses on scroll bouncing when you scroll to the very top or very bottom of a web page. In other words, when the scrollport has reached its scroll boundary.

Collecting Data, The Powerful Way

Did you know that CSS can be used for collecting statistics? Indeed, there's even a CSS-only approach for tracking UI interactions using Google Analytics. Read article →

A good understanding of scroll bouncing is very useful as it will help you to decide how you build your websites and how you want the page to scroll.

Scroll bouncing is undesirable if you don’t want to see fixed elements on a page move. Some examples include: when you want a header or footer to be fixed in a certain position, or if you want any other element such as a menu to be fixed, or if you want the page to scroll-snap at certain positions on scroll and you do not want any additional scrolling to occur at the very top or bottom of the page which will confuse visitors to your website. This article will propose some solutions to the problems faced when dealing with scroll bouncing at the very top or bottom of a web page.

Getting the process just right ain't an easy task. That's why we've set up 'this-is-how-I-work'-sessions — with smart cookies sharing what works really well for them. A part of the Smashing Membership, of course.

Explore features → My First Encounter With The Effect

I first noticed this effect when I was updating a website that I built a long time ago. You can view the website here. The footer at the bottom of the page was supposed to be fixed in its position at the bottom of the page and not move at all. At the same time, you were supposed to be able to scroll up and down through the main contents of the page. Ideally, it would work like this:

Scroll bouncing in Firefox on macOS. (Large preview)

It currently works this way in Firefox or on any browser on a device without a touchscreen or trackpad. However, at that time, I was using Chrome on a MacBook. I was scrolling to the bottom of the page using a trackpad when I discovered that my website was not working correctly. You can see what happened here:

Scroll bouncing in Chrome on macOS. (Large preview)

Oh no! This was not what was supposed to happen! I had set the footer's position to be at the bottom of the page by setting its CSS position property to have a value of fixed. This is also a good time to revisit what position: fixed; is. According to the CSS 2.1 Specification, when a “box” (in this case, the dark blue footer) is fixed, it is “fixed with respect to the viewport and does not move when scrolled.” What this means is that the footer was not supposed to move when you scroll up and down the page. This was what worried me when I saw what was happening on Chrome.

To make this article more complete, I’ll show you how the page scrolls on both Mobile Edge, Mobile Safari and Desktop Safari below. This is different to what happens in scrolling on Firefox and Chrome. I hope this gives you a better understanding of how the exact same code currently works in different ways. It is currently a challenge to develop scrolling that works in the same way across different web browsers.

Scroll bouncing in Safari on macOS. A similar effect can be seen for Edge and Safari on iOS. (Large preview) Searching For A Solution

One of my first thoughts was that there would be an easy and a quick way to fix this issue on all browsers. What this means is that I thought that I could find a solution that would take a few lines of CSS code and that no JavaScript would be involved. Therefore, one of the first things I did, was to try to achieve this. The browsers I used for testing included Chrome, Firefox and Safari on macOS and Windows 10, and Edge and Safari on iOS. The versions of these browsers were the latest at the time of writing this article (2018).

HTML And CSS Only Solutions Absolute And Relative Positioning

One of the first things I tried, was to use absolute and relative positioning to position the footer because I was used to building footers like this. The idea would be to set my web page to 100% height so that the footer is always at the bottom of the page with a fixed height, whilst the content takes up 100% minus the height of the footer and you can scroll through that. Alternatively, you can set a padding-bottom instead of using calc and set the body-container height to 100% so that the contents of the application do not overlap with the footer. The CSS code looked something like this:

html { width: 100%; height: 100%; overflow: hidden; position: relative; } body { width: 100%; margin: 0; font-family: sans-serif; height: 100%; overflow: hidden; } .body-container { height: calc(100% - 100px); overflow: auto; } .color-picker-main-container { width: 100%; font-size: 22px; padding-bottom: 10px; } footer { position: absolute; bottom: 0; height: 100px; width: 100%; }

This solution works in almost the same way as the original solution (which was just position: fixed;). One advantage of this solution compared to that is that the scroll is not for the entire page, but for just the contents of the page without the footer. The biggest problem with this method is that on Mobile Safari, both the footer and the contents of the application move at the same time. This makes this approach very problematic when scrolling quickly:

Absolute and Relative Positioning.

Another effect that I did not want was difficult to notice at first, and I only realized that it was happening after trying out more solutions. This was that it was slightly slower to scroll through the contents of my application. Because we are setting our scroll container’s height to 100% of itself, this hinders flick/momentum-based scrolling on iOS. If that 100% height is shorter (for example, when a 100% height of 2000px becomes a 100% height of 900px), the momentum-based scrolling gets worse. Flick/momentum-based scrolling happens when you flick on the surface of a touchscreen with your fingers and the page scrolls by itself. In my case, I wanted momentum-based scrolling to occur so that users could scroll quickly, so I stayed away from solutions that set a height of 100%.

Other Attempts

One of the solutions suggested on the web, and that I tried to use on my code, is shown below as an example.

html { width: 100%; position: fixed; overflow: hidden; } body { width: 100%; margin: 0; font-family: sans-serif; position: fixed; overflow: hidden; } .body-container { width: 100vw; height: calc(100vh - 100px); overflow-y: auto; -webkit-overflow-scrolling: touch; } .color-picker-main-container { width: 100%; font-size: 22px; padding-bottom: 10px; } footer { position: fixed; bottom: 0; height: 100px; width: 100%; }

This code works on Chrome and Firefox on macOS the same way as the previous solution. An advantage of this method is that scroll is not restricted to 100% height, so momentum-based scrolling works properly. On Safari, however, the footer disappears:

Missing Footer on macOS Safari. (Large preview)

On iOS Safari, the footer becomes shorter, and there is an extra transparent (or white) gap at the bottom. Also, the ability to scroll through the page is lost after you scroll to the very bottom. You can see the white gap below the footer here:

Shorter Footer on iOS Safari.

One interesting line of code you might see a lot is: -webkit-overflow-scrolling: touch;. The idea behind this is that it allows momentum-based scrolling for a given element. This property is described as “non-standard” and as “not on a standard track” in MDN documentation. It shows up as an “Invalid property value” under inspection in Firefox and Chrome, and it doesn’t appear as a property on Desktop Safari. I didn’t use this CSS property in the end.

To show another example of a solution you may encounter and a different outcome I found, I also tried the code below:

html { position: fixed; height: 100%; overflow: hidden; } body { font-family: sans-serif; margin: 0; width: 100vw; height: 100vh; overflow-y: auto; overflow-x: hidden; -webkit-overflow-scrolling: touch; } .color-picker-main-container { width: 100%; font-size: 22px; padding-bottom: 110px; } footer { position: fixed; }

This actually works well across the different desktop browsers, momentum-based scrolling still works, and the footer is fixed at the bottom and does not move on desktop web browsers. Perhaps the most problematic part of this solution (and what makes it unique) is that, on iOS Safari the footer always shakes and distorts very slightly and you can see the content below it whenever you scroll.

Solutions With JavaScript

After trying out some initial solutions using just HTML and CSS, I gave some JavaScript solutions a try. I would like to add that this is something that I do not recommend you to do and would be better to avoid doing. From my experience, there are usually more elegant and concise solutions using just HTML and CSS. However, I had already spent a lot of time trying out the other solutions, I thought that it wouldn’t hurt to quickly see if there were some alternative solutions that used JavaScript.

Touch Events

One approach of solving the issue of scroll bouncing is by preventing the touchmove or touchstart events on the window or document. The idea behind this is that the touch events on the overall window are prevented, whilst the touch events on the content you want to scroll through are allowed. An example of code like this is shown below:

// Prevents window from moving on touch on older browsers. window.addEventListener('touchmove', function (event) { event.preventDefault() }, false) // Allows content to move on touch. document.querySelector('.body-container').addEventListener('touchmove', function (event) { event.stopPropagation() }, false)

I tried many variations of this code to try to get the scroll to work properly. Preventing touchmove on the window made no difference. Using document made no difference. I also tried to use both touchstart and touchmove to control the scrolling, but these two methods also made no difference. I learned that you can no longer call event.preventDefault() this way for performance reasons. You have to set the passive option to false in the event listener:

// Prevents window from moving on touch on newer browsers. window.addEventListener('touchmove', function (event) { event.preventDefault() }, {passive: false}) Libraries

You may come across a library called “iNoBounce” that was built to “stop your iOS webapp from bouncing around when scrolling.” One thing to note when using this library right now to solve the problem I’ve described in this article is that it needs you to use -webkit-overflow-scrolling. Another thing to note is that the more concise solution I ended up with (which is described later) does a similar thing as it on iOS. You can test this yourself by looking at the examples in its GitHub Repository, and comparing that to the solution I ended up with.

Overscroll Behavior

After trying out all of these solutions, I found out about the CSS property overscroll-behavior. The overscroll-behavior CSS property was implemented in Chrome 63 on December 2017, and in Firefox 59 on March 2018. This property, as described in MDN documentation, “allows you to control the browser's scroll overflow behavior — what happens when the boundary of a scrolling area is reached.” This was the solution that I ended up using.

All I had to do was set overscroll-behavior to none in the body of my website and I could leave the footer’s position as fixed. Even though momentum-based scrolling applied to the whole page, rather than the contents without the footer, this solution was good enough for me and fulfilled all of my requirements at that point in time, and my footer no longer bounced unexpectedly on Chrome. It is perhaps useful to note that Edge has this property flagged as under development now. overscroll-behavior can be seen as an enhancement if browsers do not support it yet.

Conclusion

If you don’t want your fixed headers or footers to bounce around on your web pages, you can now use the overscroll-behavior CSS property.

Despite the fact that this solution works differently in different browsers (bouncing of the page content still happens on Safari and Edge, whereas on Firefox and Chrome it doesn’t), it will keep the header or footer fixed when you scroll to the very top or bottom of a website. It is a concise solution and on all the browsers tested, momentum-based scrolling still works, so you can scroll through a lot of page content very quickly. If you are building a fixed header or footer on your web page, you can begin to use this solution.

(rb, ra, yk, il)
Categories: Web Design

The Complete Anatomy Of The Gutenberg WordPress Editor

Tue, 08/14/2018 - 05:00
The Complete Anatomy Of The Gutenberg WordPress Editor The Complete Anatomy Of The Gutenberg WordPress Editor Manish Dudharejia 2018-08-14T14:00:22+02:00 2018-09-03T12:33:55+00:00

It seems that Gutenberg has been a term of controversy in the world of WordPress lately. Hailed as the most significant change to WordPress 5.0 this year, the Gutenberg editor has received a mixed response from web developers and regular folk alike. All of this chaos is making it difficult to see Gutenberg for what it really is. So, I’ll try to put some of the confusion to rest once and for all.

In this article, I will cover the following:

  1. What is Gutenberg?
  2. More Than Just An Editor
  3. What Does Gutenberg Change In WordPress?
  4. Installing Gutenberg
  5. Exploring Gutenberg At Length
  6. Pros And Cons
  7. Understanding Compatibility Issues
  8. Gutenberg Is The Future
  9. Latest News And Further Resources
1. What Is Gutenberg?

Named after Johannes Gutenberg, who invented the mechanical printing press, Gutenberg was introduced to the world by Matt Mullenweg at WordCamp Europe in 2017. In essence, Gutenberg is a new WordPress editor, with dozens of cutting-edge features. It simplifies website creation and editing for the average non-technical user.

It has earned several accolades, from “WordPress’s new publishing experience” to “the future of website creation”. Some skeptics think it is the nail in the coffin for WordPress. All this babble aside, Gutenberg is going to be way more than just an editor for WordPress (which I will discuss next).

It allows website creators to build a website using blocks, which are small drag-and-drop units. Thus, it replaces the current inconsistent and distracting customization process. It also enables HTML tags such as section and figure, outputting solid HTML. At the time of writing, Gutenberg is still a plugin. However, the community is planning to merge it with WordPress 5.0 this year.

Getting workflow just right ain’t an easy task. So are proper estimates. Or alignment among different departments. That’s why we’ve set up “this-is-how-I-work”-sessions — with smart cookies sharing what works well for them. A part of the Smashing Membership, of course.

Explore features → 2. More Than Just An Editor

Gutenberg is more than just an editor because it allows you to handle website content in customizable chunks or blocks. You don’t need to be fluent in HTML or write shortcodes. You can control a website’s entire layout (both back end and front end) from a single console.

This new editor attempts to combine the best features from both page-builder plugins such as Divi and Visual Composer, as well as do-it-yourself platforms such as Medium, Wix and Squarespace. So, just like those page-builder plugins, you can handle multi-column layouts through a single interface.

Does this spell the end of plugins such as Divi and Beaver Builder? That’s a topic for another post, but the short answer is no. Gutenberg is unlikely to replace those plugins completely. You can continue to use them even once Gutenberg becomes the default editor.

3. What Does Gutenberg Change In WordPress?

The sole purpose of the Gutenberg editor is to provide an alternative to the current open text editor, not to mention the difficult-to-remember shortcodes, with an agile and visual user interface (UI). So, unlike the current WordPress editor, you don’t have to:

  • import images, multimedia and approved files from the media library or add HTML shortcodes;
  • copy and paste links for embeds;
  • write shortcodes for specialized assets of different plugins;
  • create featured images to be added at the top of a post or page;
  • add excerpts for subheads;
  • add widgets for content on the side of a page.

In short, Gutenberg doesn’t change how WordPress functions. It does, however, change the way website owners (or creators) interact with it. Instead of a whole lot of shortcodes and meta boxes, you will be using simple blocks.

What Are Blocks?

Consider a block as the most basic (therefore, smallest) unit of the new editor. They will be the building blocks of WordPress 5.0. In other words, everything—including content, images, quotes, galleries, cover images, audio, video, headings, embeds, custom codes, paragraphs, separators and buttons—will turn into distinct blocks. Because you can drag and drop each block, identifying these items and placing them on the page becomes a lot easier.

4. Installing Gutenberg

You can download the latest version of Gutenberg directly from the WordPress repository. You can also search for it under “Add New” plugins in your WordPress dashboard. I would recommend installing it in your staging environment. However, you’ll need the latest version of WordPress (version 4.8 or later) to install the Gutenberg editor.

  1. Sign into your WordPress admin dashboard.
  2. Go to the Plugins menu on the left side of the dashboard.
  3. Click “Plugins” to open the “Add New” menu.
  4. Type “Gutenberg” in the search box, located in the top-left corner.
  5. You will see the Gutenberg plugin in the results.
  6. Click the “Install Now” button.
  7. Click the “Activate” button to initiate the plugin.
Gutenberg Installation Steps (Large preview) 5. Exploring Gutenberg At Length

Once installed and activated, Gutenberg will show an icon in the left menu bar. When you launch it for the first time, you will see a new sample post, titled “Gutenberg Demo.” You can practice on the demo post before creating your own.

Gutenberg Sample Post (Large preview) A. Add New

Go to “Posts” in the left menu bar of your WordPress dashboard. The new post will launch in Gutenberg first. You can later edit it in both the classic editor and Gutenberg.

Adding a new post in Gutenberg (Large preview) B. Edit

Go to the “Posts” menu, and hover the mouse over a saved post to see the option to choose between the two editors. Although the classic editor option is available for the time being, it will most likely be removed with the launch of WordPress 5.0.

Editing a post in Gutenberg (Large preview) C. Switch Between Editors

You can also switch between the two editors when editing a post. Click on the dropdown menu in the upper-right corner to toggle between the visual editor mode and the text editor (i.e. code). Alternatively, you can also use the shortcut Ctrl + Shift + Alt + M to switch between editors.

Text editor:

The text editor in Gutenberg (Large preview)

Visual editor:

The visual editor in Gutenberg (Large preview) D. Copy All Content

This feature allows you to copy all content in the HTML version with just one click. You can open this feature in both editors by clicking on the dropdown menu in the upper-right corner of the dashboard.

“ The ‘Copy All Content’ tool in Gutenberg (Large preview) E. Content Structures

This feature allows you to count the number of words in an entire post. You can also see the number of headings, paragraphs and blocks with just a click. Click the information icon (i) in the upper-left area.

Content information in Gutenberg (Large preview) F. Redo and Undo

You can find these options next to the information icon (i). They allow you to undo or redo the last command.

Undo/Redo Command (Large preview) G. Page and Document Settings

This allows you to change various page and document settings. You can find it in the right menu bar. You can make the following adjustments:

  • Make a post public or private.
  • Change the publishing date.
  • Select a post’s format.
  • Add or edit categories and tags.
  • Upload featured images.
  • Write an excerpt.
  • Enable and disable comments, pingbacks and trackbacks.
Page/Document Settings (Large preview) H. Stick to Front Page

This feature will come handy if you’re running a blog. When you turn this on in the document settings, that particular post will always appear on the front page of your blog. And just turn it off to remove it from the front page.

Making your post stick to the front page (Large preview) I. Using Blocks

As mentioned, blocks are the fundamental unit of the new Gutenberg editor. To use Gutenberg efficiently, you need to understand how to use these blocks. I will cover the main blocks one by one. Click the plus (+) button next to the redo/undo option to open the blocks menu.

Common Blocks

Common blocks allow you to add the elements required to create a rich UI.

  • Paragraph
    The paragraph block comes with a few excellent features, such as custom font sizes, drop caps, background colors and text colors, among others. You are also able to add more CSS classes here.
Gutenberg Text Editor Options (Large preview)
  • Image
    This element comes with a new feature that allows you to toggle between gallery and image layouts. You also get more control over images because you can set particular size dimensions, percentage size ratios, and an alternative text description for each image.
Image Settings in Gutenberg (Large preview)
  • Other elements include:
    • quotes,
    • galleries,
    • cover images,
    • headings,
    • lists,
    • audio,
    • files,
    • subheadings,
    • video.
Formatting

As the name suggests, these blocks comprise all of the formatting tools.

  • Table
    Adding a table using custom HTML code was a tedious job. With the table block, however, the task is a lot easier. You are able to add and remove rows and columns of a table without coding.
Table Block in Gutenberg (Large preview)
  • Custom HTML
    You can use a custom HTML code in Gutenberg. And the nice part is that you can insert your code and see a preview in the block itself.
Custom HTML in Gutenberg (Large preview)
  • Other elements include:
    • code,
    • classic,
    • preformatted,
    • pull quote,
    • verse.
Layout

Use your imagination to create a stunning layout using this block. Each element in this block comes with excellent features.

  • Button
    You can add buttons such as “Subscribe now” and “Buy now” using this block. It has different options, including alignment and font styles. You can also set the background color and shape of the button.
Button Layout in Gutenberg (Large preview)
  • Columns (beta)
    Creating columns in the code-based editor is time-consuming and laborious. This block allows you to add text columns. You are able to add one to six columns in a single row.
Column Layout in Gutenberg (Large preview)
  • Other elements include:
    • read more,
    • page break,
    • separator,
    • spacer.
Widgets

These blocks allow you to add an archive, categories, the latest posts and the latest comments with just a click anywhere on the page. You are also able to adjust these elements without any coding.

  • Latest Post
    With this block element, you can show posts in a grid view or list view, organize them in categories, and order them alphabetically or according to publication date. You can also choose to display the publication date.
Latest Posts Setting in Gutenberg (Large preview) Embeds

You can easily access any embeds using these blocks. Whether you want to add a YouTube or Twitter link, it’s super-easy and quick. All you need to do is paste the URL in the given blank space, and Gutenberg will embed the code for you. Here is an example of inserting a YouTube link:

Embed Youtube Link in Gutenberg (Large preview) Reusable Blocks

Reusable blocks give developers improved usability. You can convert any block into a reusable block so that you can use it in a different location. You can edit the same and save it as a new reusable block again.

You can also see a preview of a reusable block. All reusable blocks are available under the “Shared Block” options. Most importantly, you can turn one back into a regular block anytime.

Reusable Blocks in Gutenberg (Large preview) Most Used

Under this option, you will see the most used blocks, for quick access. Alternatively, you can use the search box to find a block by name.

J. Edit Block

To edit any block, open the dropdown menu by clicking in the upper-right corner of the block. You will see different options, including to edit as HTML, duplicate and add to the reusable blocks.

Edit Block in Gutenberg (Large preview) K. Insert Blocks

Using this feature, you can insert a new block anytime. When you bring your mouse over a block, you will see a plus icon (+). Click it to insert a new block.

Inserting a block in Gutenberg (Large preview) L. Slash Autocomplete

The Slash Autocomplete feature is available in Gutenberg 1.1.0 and later versions. Chances are you are already familiar with the similar feature in Slack. It was added to reduce the amount of pointing and clicking required to create new blocks.

When you open a new block, just press / (slash key) on your keyboard to select any of the autocomplete options. It works in the default paragraph block only, but it might become a part of other types of blocks in the future.

Slash Autocomplete in Gutenberg (Large preview) M. Move Blocks

Gutenberg enables you to move each block up and down. You can use the arrows (on the left side of each block) to move them vertically.

Moving a block in Gutenberg (Large preview) 6. Gutenberg Pros And Cons Pros
  • No technical skill is required to make a custom layout for a blog post or website. It works like Medium, so people looking for that kind of style and user-friendly editing experience will love it.
  • It allows you to create a consistent and advanced design without relying much on TinyMCE.
  • Furthermore, blocks are an excellent concept. They allow non-developers to intuitively craft complex layouts. If you are new to WordPress or have no knowledge of it whatsoever, you are still going to love it.
  • The Gutenberg editor itself works well on mobile (it’s responsive). Unlike its predecessor, it allows you to make quick edits on the go. In fact, mobile-savvy developers can manage to do more than just a few quick edits.
  • The increased screen space is proving to be a less distracting user experience for many developers.
  • Hardcore developers can still create customized reusable blocks using HTML5. So, it seems like a win-win for both geeks and non-technical users.
Cons
  • For the time being, there is no Markdown support in the beta version of the WordPress editor.
  • It still doesn’t support responsive columns. You will need to do some custom coding to make this feature responsive. So, using this feature on mobile isn’t an option right now.
  • The design layout options are inadequate at the moment.
  • Compatibility issues could be a significant concern for some WordPress users.
  • You get only partial support for meta boxes, however, developers are working hard to extend meta box support.
  • Backward compatibility is going to be a primary concern for most developers. It will destroy current plugins and themes, especially ones that require integration with TinyMCE.
7. Understanding Compatibility Issues

Despite its simplicity and agility, Gutenberg might not be everyone’s cup of tea. Most WordPress developers might find it difficult to work with, especially in the beginning. They will need to retrain their reflexes to get used to the new UX.

  • Owing to the backward-compatibility issue, you will need to update many plugins and themes to ensure they are fully compatible with the new editor.
  • For the time being, blocks are more focused on content. As a result, Gutenberg lacks precision and control over the layout of custom websites.
  • Shortcodes are replaced by shortcode blocks. However, you will still be able to add shortcodes from the widget block.
  • Meta boxes will be available under a new name and a new UI. Conflicting meta boxes are likely to lead to the classic editor, instead of Gutenberg, with an alert. While this system might prove helpful, some meta boxes will not be supported in Gutenberg.
  • Custom post types are supported and remain backward-compatible in Gutenberg.
  • You won’t be able to turn off Gutenberg once it is integrated in WordPress core. However, you can disable it using the official plugin anytime.
8. Gutenberg Is The Future

Contrary to popular opinion, Gutenberg is not a replacement for the current text editor. It is a new way to build websites. I like to think of it as Facebook for WordPress.

You don’t need to be a computer geek to publish things on Facebook or any other social media platform. Gutenberg is just a way to bring this simplicity and flexibility to WordPress, so that people don’t need to code in order to create and publish websites. That’s why I think it is going to be the future, not only for WordPress, but for the web in general.

Granted, Gutenberg has a long way to go. People (including me) have had issues with its implementation, but soon we will have Gutenberg-ready themes, plugins and tools surfacing everywhere. Nevertheless, you have to start somewhere. So, you might as well be a part of this change from the beginning.

9. Latest News And Further Resources

If you are interested in riding the Gutenberg train from the beginning, here are a few links to find the latest buzz. Keep in mind that none of these websites are officially endorsed by WordPress.

For official updates and news, you can try the following:

Wrapping Up

Whether you like it or not, Gutenberg is coming to WordPress 5.0. Do try to be a part of the ongoing discussion about it on the web. It will certainly help. In fact, while you’re at it, try to speed up the development process with your skills. Meanwhile, let me know if this post has shed some light on the topic. Drop your queries and suggestions in the comments section. I would love to keep the conversation going.

(ra, il)
Categories: Web Design

Everything You Need To Know About Alignment In Flexbox

Mon, 08/13/2018 - 05:00
Everything You Need To Know About Alignment In Flexbox Everything You Need To Know About Alignment In Flexbox Rachel Andrew 2018-08-13T14:00:57+02:00 2018-09-03T12:33:55+00:00

In the first article of this series, I explained what happens when you declare display: flex on an element. This time we will take a look at the alignment properties, and how these work with Flexbox. If you have ever been confused about when to align and when to justify, I hope this article will make things clearer!

History Of Flexbox Alignment

For the entire history of CSS Layout, being able to properly align things on both axes seemed like it might truly be the hardest problem in web design. So the ability to properly align items and groups of items was for many of us the most exciting thing about Flexbox when it first started to show up in browsers. Alignment became as simple as two lines of CSS:

See the Pen Smashing Flexbox Series 2: center an item by Rachel Andrew (@rachelandrew) on CodePen.

The alignment properties that you might think of as the flexbox alignment properties are now fully defined in the Box Alignment Specification. This specification details how alignment works across the various layout contexts. This means that we can use the same alignment properties in CSS Grid as we use in Flexbox — and in future in other layout contexts, too. Therefore, any new alignment capability for flexbox will be detailed in the Box Alignment specification and not in a future level of Flexbox.

Nope, we can't do any magic tricks, but we have articles, books and webinars featuring techniques we all can use to improve our work. Smashing Members get a seasoned selection of magic front-end tricks — e.g. live designing sessions and perf audits, too. Just sayin'! ;-)

Explore Smashing Wizardry → The Properties

Many people tell me that they struggle to remember whether to use properties which start with align- or those which start with justify- in flexbox. The thing to remember is that:

  • justify- performs main axis alignment. Alignment in the same direction as your flex-direction
  • align- performs cross-axis alignment. Alignment across the direction defined by flex-direction.

Thinking in terms of main axis and cross axis, rather than horizontal and vertical really helps here. It doesn’t matter which way the axis is physically.

Main Axis Alignment With justify-content

We will start with the main axis alignment. On the main axis, we align using the justify-content property. This property deals with all of our flex items as a group, and controls how space is distributed between them.

The initial value of justify-content is flex-start. This is why, when you declare display: flex all your flex items line up against the start of the flex line. If you have a flex-direction of row and are in a left to right language such as English, then the items will start on the left.

The items line up to the start (Large preview)

Note that the justify-content property can only do something if there is spare space to distribute. Therefore if you have a set of flex items which take up all of the space on the main axis, using justify-content will not change anything.

There is no space to distribute (Large preview)

If we give justify-content a value of flex-end then all of the items will move to the end of the line. The spare space is now placed at the beginning.

The items line up at the end (Large preview)

We can do other things with that space. We could ask for it to be distributed between our flex items, by using justify-content: space-between. In this case, the first and last item will be flush with the ends of the container and all of the space shared equally between the items.

The spare space is shared out between the items (Large preview)

We can ask that the space to be distributed around our flex items, using justify-content: space-around. In this case, the available space is shared out and placed on each side of the item.

The items have space either side of them (Large preview)

A newer value of justify-content can be found in the Box Alignment specification; it doesn’t appear in the Flexbox spec. This value is space-evenly. In this case, the items will be evenly distributed in the container, and the extra space will be shared out between and either side of the items.

The items are spaced evenly (Large preview)

You can play with all of the values in the demo:

See the Pen Smashing Flexbox Series 2: justify-content with flex-direction: row by Rachel Andrew (@rachelandrew) on CodePen.

These values work in the same way if your flex-direction is column. You may not have extra space to distribute in a column however unless you add a height or block-size to the flex container as in this next demo.

See the Pen Smashing Flexbox Series 2: justify-content with flex-direction: column by Rachel Andrew (@rachelandrew) on CodePen.

Cross Axis Alignment with align-content

If you have added flex-wrap: wrap to your flex container, and have multiple flex lines then you can use align-content to align your flex lines on the cross axis. However, this will require that you have additional space on the cross axis. In the below demo, my cross axis is running in the block direction as a column, and I have set the height of the flex container to 60vh. As this is more than is needed to display my flex items I have spare space vertically in the container.

I can then use align-content with any of the values:

See the Pen Smashing Flexbox Series 2: align-content with flex-direction: row by Rachel Andrew (@rachelandrew) on CodePen.

If my flex-direction were column then align-content would work as in the following example.

See the Pen Smashing Flexbox Series 2: align-content with flex-direction: column by Rachel Andrew (@rachelandrew) on CodePen.

As with justify-content, we are working with the lines as a group and distributing the spare space.

The place-content Shorthand

In the Box Alignment, we find the shorthand place-content; using this property means you can set justify-content and align-content at once. The first value is for align-content, the second for justify-content. If you only set one value then both values are set to that value, therefore:

.container { place-content: space-between stretch; }

Is the same as:

.container { align-content: space-between; justify-content: stretch; }

If we used:

.container { place-content: space-between; }

This would be the same as:

.container { align-content: space-between; justify-content: space-between; } Cross Axis Alignment With align-items

We now know that we can align our set of flex items or our flex lines as a group. However, there is another way we might wish to align our items and that is to align items in relationship to each other on the cross axis. Your flex container has a height. That height might be defined by the height of the tallest item as in this image.

The container height is defined by the third item (Large preview)

It might instead be defined by adding a height to the flex container:

The height is defined by a size on the flex container (Large preview)

The reason that flex items appear to stretch to the size of the tallest item is that the initial value of align-items is stretch. The items stretch on the cross axis to become the size of the flex container in that direction.

Note that where align-items is concerned, if you have a multi-line flex container, each line acts like a new flex container. The tallest item in that line would define the size of all items in that line.

In addition to the initial value of stretch, you can give align-items a value of flex-start, in which case they align to the start of the container and no longer stretch to the height.

The items aligned to the start of the cross axis (Large preview)

The value flex-end moves them to the end of the container on the cross axis.

The items aligned to the end of the cross axis (Large preview)

If you use a value of center the items all centre against each other:

Centering the items on the cross axis (Large preview)

We can also do baseline alignment. This ensures that the baselines of text line up, as opposed to aligning the boxes around the content.

Aligning the baselines (Large preview)

You can try these values out in the demo:

See the Pen Smashing Flexbox Series 2: align-items by Rachel Andrew (@rachelandrew) on CodePen.

Individual Alignment With align-self

The align-items property means that you can set the alignment of all of the items at once. What this really does is set all of the align-self values on the individual flex items as a group. You can also use the align-self property on any individual flex item to align it inside the flex line and against the other flex items.

In the following example, I have used align-items on the container to set the alignment for the group to center, but also used align-self on the first and last items to change their alignment value.

See the Pen Smashing Flexbox Series 2: align-self by Rachel Andrew (@rachelandrew) on CodePen.

Why Is There No justify-self?

A common question is why it is not possible to align one item or a group of the items on the main axis. Why is there no -self property for main axis alignment in Flexbox? If you think about justify-content and align-content as being about space distribution, the reason for their being no self-alignment becomes more obvious. We are dealing with the flex items as a group, and distributing available space in some way — either at the start or end of the group or between the items.

If might be also helpful to think about how justify-content and align-content work in CSS Grid Layout. In Grid, these properties are used to distribute spare space in the grid container between grid tracks. Once again, we take the tracks as a group, and these properties give us a way to distribute any extra space between them. As we are acting on a group in both Grid and Flexbox, we can’t target an item on its own and do something different with it. However, there is a way to achieve the kind of layout that you are asking for when you ask for a self property on the main axis, and that is to use auto margins.

Using Auto Margins On The Main Axis

If you have ever centered a block in CSS (such as the wrapper for your main page content by setting a margin left and right of auto), then you already have some experience of how auto margins behave. A margin set to auto will try to become as big as it can in the direction it has been set in. In the case of using margins to center a block, we set the left and right both to auto; they each try and take up as much space as possible and so push our block into the center.

Auto margins work very nicely in Flexbox to align single items or groups of items on the main axis. In the next example, I am achieving a common design pattern. I have a navigation bar using Flexbox, the items are displayed as a row and are using the initial value of justify-content: start. I would like the final item to be displayed separated from the others at the end of the flex line — assuming there is enough space on the line to do so.

I target that item and give it a margin-left of auto. This then means that the margin tries to get as much space as possible to the left of the item, which means the item gets pushed all the way over to the right.

See the Pen Smashing Flexbox Series 2: alignment with auto margins by Rachel Andrew (@rachelandrew) on CodePen.

If you use auto margins on the main axis then justify-content will cease to have any effect, as the auto margins will have taken up all of the space that would otherwise be assigned using justify-content.

Fallback Alignment

Each alignment method details a fallback alignment, this is what will happen if the alignment you have requested can’t be achieved. For example, if you only have one item in a flex container and ask for justify-content: space-between, what should happen? The answer is that the fallback alignment of flex-start is used and your single item will align to the start of the flex container. In the case of justify-content: space-around, a fallback alignment of center is used.

In the current specification you can’t change what the fallback alignment is, so if you would prefer that the fallback for space-between was center rather than flex-start, there isn’t a way to do that. There is a note in the spec which says that future levels may enable this.

Safe And Unsafe Alignment

A more recent addition to the Box Alignment specification is the concept of safe and unsafe alignment using the safe and unsafe keywords.

With the following code, the final item is too wide for the container and with unsafe alignment and the flex container on the left-hand side of the page, the item becomes cut off as the overflow is outside the page boundary.

.container { display: flex; flex-direction: column; width: 100px; align-items: unsafe center; } .item:last-child { width: 200px; } Unsafe alignment will give you the alignment you asked for but may cause data loss (Large preview)

A safe alignment would prevent the data loss occurring, by relocating the overflow to the other side.

.container { display: flex; flex-direction: column; width: 100px; align-items: safe center; } .item:last-child { width: 200px; } Safe alignment tries to prevent data loss (Large preview)

These keywords have limited browser support right now, however, they demonstrate the additional control being brought to Flexbox via the Box Alignment specification.

See the Pen Smashing Flexbox Series 2: safe or unsafe alignment by Rachel Andrew (@rachelandrew) on CodePen.

In Summary

The alignment properties started as a list in Flexbox, but are now in their own specification and apply to other layout contexts. A few key facts will help you to remember how to use them in Flexbox:

  • justify- the main axis and align- the cross axis;
  • To use align-content and justify-content you need spare space to play with;
  • The align-content and justify-content properties deal with the items as a group, sharing out space. Therefore, you can’t target an individual item and so there is no -self alignment for these properties;
  • If you do want to align one item, or split a group on the main axis, use auto margins to do so;
  • The align-items property sets all of the align-self values as a group. Use align-self on the flex child to set the value for an individual item.
(il)
Categories: Web Design

Attracting Users To Evaluate Your Product

Sun, 08/05/2018 - 15:30
Attracting Users To Evaluate Your Product Attracting Users To Evaluate Your Product Joe Leech 2018-08-05T23:30:38+01:00 2018-08-30T12:00:56+00:00

(This is a sponsored article.) The entire ecosystem in which we are designing and researching the user experience is shifting and changing constantly. Traditional UX skills need to be expanded to meet the reality of the modern digital ecosystem. Understanding the user is essential to the job, but you also need to understand the wider user context. How do they discover they have a need? How do they find and evaluate a product to meet that need?

This three-part series outlines the three phases of the product life cycle, the future of UX, and the skills and approach you’ll need to design modern digital products.

  • Part 1: Attraction
    Going out there to get users to evaluate your product.
  • Part 2: Activation
    Signing up, onboarding users, asking for payment.
  • Part 3: Retention
    Encouraging users to come back and keep using and paying for your product.

Due to their technical skills, creativity and deep understanding of user needs, UXers are in a perfect position to apply marketing, SEO and growth-hacking tools and processes to their work.

For focused UX efforts, it’s all about knowing user outcomes at each stage of their journey.

1. Attraction Large preview Getting Started

The days of changing the text on one button and having a dramatic effect on the user experience are behind us. Luckily, we have the processes and skills in our UX toolbox to meet this changing world.

More often than not, there are many small usability and experience issues throughout a user journey that cumulatively create a poor experience.

Mapping out the full user life cycle will help us discover and fix these problems. It’s often the case that a problem at the very beginning of the user journey only surfaces when a user drops out further along in the product life cycle.

We need data to help us understand how UX professional can improve performance. We’ll need user research data, business metrics, data to frame decisions made when improving UX, and metrics to help us understand the business values.

Marketing metrics tracked by team employing growth hacking. (Source). (Large preview) Plotting Out the Journey

When we talk about the attraction phase, we’re talking about users discovering they have a need, discovering our product and visiting our website to see if our product meets their needs.

Within the life cycle, we can split the larger three phases into smaller phases to help us plan our approach. In this case, we can use Philip Kotler's model (expanded to six steps by Bryony Thomas):

  1. Awareness: realizing they have a need;
  2. Interest: looking for something to help with that need;
  3. Evaluation: looking at products that help with their need;
  4. Trial: trying the product to see if it meets their need;
  5. Adoption: choosing a product and using it for a while;
  6. Loyalty: deciding to continue using the product or switching to a different one.

We’re interested in the first three parts, which fall under the attraction phase.

Large preview

We’ll look into trial, adoption and loyalty in future parts of this series.

We’ll use the customer life cycle to align user needs and expectations — what they want and when they need it — to business metrics. We’ll also look at a tool and UX process to use at each step on the journey.

As we move through the process we’ll use the example of a money management app that helps people understand what they are spending and save money.

1. Awareness: They Understand That They Have A Need The first battle isn’t fought on the ground but in the mind of the customer.
It isn’t fought with your built out solution but instead with an offer.

The Science of How Customers Buy Anything

This is most challenging phase because there is very little that is concrete in terms of user need.

Users can’t articulate what they want, but by looking at how they complete a task or the context of their life, we can identify the problems they face, how they address (or don’t!) the problems now, and potential product features to address the problems.

The goal here is to identify unmet, hidden user needs. This is something Amazon, for example, is very good at.

The secret to Amazon’s success? Be the first to uncover hidden needs. Jeff Bezos, founder of amazon.com. (Large preview) How To Identify A Need And A Solution Using Fro-Tos

A good technique to use here is to plot the current problem as articulated by the user and then the result of that problem being solved.

Al Ramadan, in his book Play Bigger, named this overarching science category design.

Category design takes people on a journey. We refer to it as creating a from/to. Actually, we use a shorthand term: frotos. Remember, a great new category is one that solves a problem people didn’t know they had, or solves an obvious problem no one thought could be solved.

You have to help them move from the way they used to think, to a new frame of reference. This is what it means to condition the market. You have to first define and market the problem — and only then can you help people understand that you can solve the problem better than anyone else.

The “from” is the problem the user is facing. The “to” is the solution your product offers. The solution described here are the words the user uses to solve the problem.

If we take the example of our money management tool, in user research, we would identify the from as:

I don’t have much money left at the end of the month. Why?

The user then identifies the to as:

I need to something to help me analyze what I spend.

Put the two together and you have frotos: a definition of the problem and an articulation of the solution.

There is a slidedeck that has a good overview of Play Bigger and its techniques.

Bonus: You can also use the jobs-to-be-done timeline as a great tool to map the intent phase.

User research helps us uncover the hidden needs and identify the frotos.

User Research To Uncover Frotos And Other Useful Details

Traditionally, user research has been focused on the experience of the product. We need to expand user research to include all parts of the user acquisition phase.

It’s not easy to research with users who aren’t yet interacting with you. We can turn to the same tools that we are using to raise awareness to also find users to research with.

Recruit and conduct research with users who might respond to your product’s messaging by using Facebook ads or Google demographic targeting. You can then use a tool like Ethn.io to ask them a few questions to aid with recruitment.

The value in researching users who are in the user acquisition phase is that they don’t bring any preconceptions of your product. In fact, when you are reaching out to users for them to give you feedback, don’t talk much about who you are researching for.

Ethnographic and contextual research is the most useful tool here. Going out and observing users in their homes and offices is a great technique. Watching a user go through a typical task will help you identify their needs. You can’t simply ask users what their unmet needs are because they won’t know. The only true way to get to unmet need is to observe behavior.

With our money management app, we might observe that some potential users under 30 years of age don’t have much money left at the end of the month to save or are curious about how much they spend on coffee.

The user research can also uncover any common identifiable traits (and patterns of behavior) that your users show, such as age-related (for example, they are under 30) or interests they share (love of coffee). We can use these traits to target them in our messaging.

The goal from the user research is to uncover unmet needs and identify the frotos: the from state and the to state.

An example of a froto might be:

FROM
I love coffee, but it can get expensive. I wonder how much I spend a month on coffee?

TO
I need to know how much I spend on expensive luxuries like coffee, so that I can reduce my spend.

We can also use the jobs-to-be-done interview framework to help identify unmet needs.

Journey Maps To Understand The Details

Taking the frotos and other learnings, you can add more detail to the journey by mapping out the steps and behaviors at a granular level.

Niall O’Connor has a great overview of how to build a journey and experience map.

Below is a high-level journey map for our money management app, showing needs mapped against each phase of the life cycle.

In the awareness phase, we can see how the need is quite abstract, but we can clearly see a need for our product. Our money management app can help people understand their current spending. (Large preview) Personas To Target

Personas are a divisive issue in the UX world. For the purpose of targeting users in the intent stage, we need to know demographic traits and interests.

We can then use tools such as Facebook ads to target the users who will respond to our frotos.

Facebook ad targeting: We can see how easy it is to find the users we are looking for based on their interests and age group. (Large preview)

In Facebook ads, we can target a specific age group who are coffee lovers. We can use this to target users who might be in the market for our product because they might spend a lot on coffee. Let’s roll up our sleeves and start designing the interactive elements to support this behavior.

Prototyping Attraction

Prototyping and wireframing have traditionally been limited to designing just the product. A modern UXer needs to take prototyping into the wider context and design interactions from the very beginning of the user journey. Rapid prototyping interactions at each step of the product life cycle to gather user feedback and validate ideas can save a lot of time, money and effort later.

For our money management app, we’ll design a Facebook ad to target potential users. We know what copy to include in the ad from our frotos.

An example showing how easy it is to create a Facebook ad prototype interaction. (Large preview)

When we get our target users and run user testing on the prototype, we’re testing the entire user experience — from awareness onwards — receiving high-quality UX insights from all parts of the user journey.

The attraction phase is really important for the user experience because it’s where expectations are set. As shown below, we need to use the tools and UX activities at our disposal to design the interactions with our user as we would design the interactions within the product.

An overview of tools and activities to use to improve the UX during the attraction phase. (Large preview) 2. Interest

The interest phase is characterized by the user looking for a product to help with the frotos we identified during the awareness phase.

Here, we’ll be working with our SEO colleagues, which means we UXers need to know the tools and processes that SEO practitioners use to help design the search and discovery journey.

Back To The Experience Map To Review The Interest Phase

We used user research to identify the frotos and the questions and information at each step of the journey.

Large preview

If we take the interest phase, we can see that the user has come to the conclusion they need something to:

  • Analyze what I spend, and
  • Manage my money.

We can take these interest statements and look to search and keyword-planning tools to refine the language used.

Using Google’s Keyword Planner:

Google’s Keyword Planner shows the suggested terms to target. (Large preview)

We are offered the following:

After selecting a keyword, we are shown alternatives we might not have considered. (Large preview)

Google’s documentation has some more useful help with the search terms report.

We can see from the related search terms what other words our target audience might type in when looking for our product. These words will help us design and improve the search user experience.

You can also use the free Google keyword research tool from SERPS.com to help define the terms used by your users to describe the problem. The higher the volume, the more likely a person is to search for that term.

A list of related search terms based on our initial query. Also shown is the relative popularity of each term. (Large preview)

We can use these search terms to refine the language we use when building the next part of our prototype.

Design The Ad In Your Prototype Tool

We can use Google’s Keyword Planner to design the interest phase of our prototype. You can update the text and the design will change in real time. This is the best approach because Google is constantly changing the format of paid and organic search listings, and any design templates will be quickly out of date.

Creating the ad in Google’s tool shows a live preview of how it will look. (Large preview)

You can also live prototype the ad in using Google’s tools on desktop and mobile.

You can preview the ad on desktop and mobile. (Large preview)

Our prototype now contains details for the first two subphases of the attraction part of the user life cycle.

Now that we have generated interest in the product, we need to start looking at how our user will evaluate our product to see if it is something they would want to invest time in.

3. Evaluation

The evaluation phase is all about the first visit to our website and that all-important first impression.

We need to look at where users are landing from, be it Facebook ads, Google search results or indeed other routes to our product, such as YouTube, Instagram or Pinterest.

Google Analytics can tell us the most common landing pages and where people come from. A report named “Network Referrals” can help.

We can see here that Facebook is major source of inbound traffic. (Large preview)

SiteTuners’ custom Google Analytics report identifies landing pages with a high bounce rate. We can interpret these as pages users are interested in, but users can’t find what they need or the messaging might not resonate with them. This report is fantastic for UXers to find pages that are causing problems and need to be improved.

Google Analytics shows pages with high-traffic and high-bounce rates (i.e. problematic pages). (Large preview)

Quick Sprout’s tool is great for evaluating landing pages to give you some clues as to why the page we identified from the custom report is failing.

Prototype The Landing Page

User research has helped us define what our users need at each step, and we’ve mapped out those needs. If it’s an existing product, then we know which landing pages are causing us problems.

The journey map can help us determine the type of copy to include on the landing page — what the user is expecting to see, what questions they need answering and what concerns they may have.

The three parts of the attraction phase and user questions and information needs. (Large preview)

We can then directly translate the user needs into the design for the landing page.

A quick mockup of the landing page meeting the user questions and information needs. (Large preview)

Understanding and mapping the problems users have, the solutions they need, as well as the questions they have when evaluating will make designing this page a straightforward task. If we have an existing but underperforming landing page, we’ll know what content the user is expecting and can evaluate and recommend what needs to change.

Previously, when prototyping we may have used lorem ipsum text. Now, we don’t need to because we have the copy we need. We can design the calls to action to reflect the problems our users are facing, increasing the likelihood of them using our product. No more need for lorem ipsum!

This landing page is just the start. In the next UX life cycle article, we’ll look at further enhancements.

Here’s more great guidance on How To Design An Effective Mobile Landing Page.

User Research The Journey, Including The Landing Page

We can now use the prototype to user test the whole attraction journey, from initial awareness to evaluation. Another Smashing Magazine article has some great suggestions to help with your user research.

Just Scratching The Surface

We’ve looked at how UXers can learn from other disciplines, such as marketing and SEO, to better understand, research, design and improve the attraction phase of the product life cycle.

If you’d like to learn more, I suggest these great books:

In the next part of the series, we’ll look at the next phase, activation: helping users to sign up, onboard and pay for your product.

This article is part of the UX design series sponsored by Adobe. Adobe XD tool is made for a fast and fluid UX design process, as it lets you go from idea to prototype faster. Design, prototype and share — all in one app. You can check out more inspiring projects created with Adobe XD on Behance, and also sign up for the Adobe experience design newsletter to stay updated and informed on the latest trends and insights for UX/UI design.

(ra, yk, il)
Categories: Web Design

What Happens When You Create A Flexbox Flex Container?

Thu, 08/02/2018 - 05:00
What Happens When You Create A Flexbox Flex Container? What Happens When You Create A Flexbox Flex Container? Rachel Andrew 2018-08-02T14:00:35+02:00 2018-08-28T14:30:50+00:00

In a short series of articles, I’m going to spend some time in detailed unpacking of Flexbox — in the same way I have done in the past with grid. We’ll have a look at the things Flexbox was designed for, what it really does well, and why we might not choose it as a layout method. In this article, we will take a detailed look at what actually happens when you add display: flex to your stylesheet.

A Flex Container, Please!

In order to use Flexbox, you need an element that will be the flex container. In your CSS, you use display: flex:

See the Pen Smashing Flexbox Series 1: display: flex; by Rachel Andrew (@rachelandrew) on CodePen.

Let us spend a little while thinking about what display: flex really means. In the Display Module Level 3, each value of display is described as actually being a combination of two things: an inner display model, and an outer display model. When we add display: flex, we are really defining display: block flex. The outer display type of our flex container is block; it acts like a block level element in normal flow. The inner display type is flex, so items directly inside our container will participate in flex layout.

This is something you might never have really thought about but probably understand anyway. The flex container acts like any other block on your page. If you have a paragraph followed by a flex container, both of these things behave as we have become accustomed to block elements behaving.

Nope, we can't do any magic tricks, but we have articles, books and webinars featuring techniques we all can use to improve our work. Smashing Members get a seasoned selection of magic front-end tricks — e.g. live designing sessions and perf audits, too. Just sayin'! ;-)

Explore Smashing Wizardry →

We can also define our container with a value of inline-flex which is like using display: inline flex, i.e. a flex container that acts like an inline level element, with children that participate in flex layout. The children of our inline flex container behave in the same way that children of our block flex container behave; the difference is how the container itself behaves in the overall layout.

See the Pen Smashing Flexbox Series 1: display: inline-flex; by Rachel Andrew (@rachelandrew) on CodePen.

This concept of elements having an outer display type, which defines how they behave as a box on the page (plus an inner display type) dictating how their children behave is quite useful. You can apply this thinking to any box in CSS. How does this element act? How do the children of this element act? The answers relate to their outer and inner display models.

Rows Or Columns?

Once we have defined our flex container, some initial values come into play. Without our adding any extra properties, the flex items display as a row. This happens because the initial value of the flex-direction property is row. If you don’t set it, you get a row.

The flex-direction property is how we set the direction of the main axis. Other values for flex-direction are:

  • column
  • row-reverse
  • column-reverse

With our items in a row, the items are placed with the first item at the start edge of the inline dimension and display in the order that they appear in the source. In the specification, this edge is described as main-start:

main-start is at the start of the inline dimension (Large preview)

If we use the value column, the items begin to lay out from the start edge of the block dimension and therefore form a column.

main-start is the start of the block dimension (Large preview)

When we use row-reverse, the location of main-start and main-end are switched; therefore, the items lay themselves out one after the other ending up in reverse order.

main-start is at the end of the inline dimension (Large preview)

The value column-reverse does the same thing. It’s important to remember that these values don’t “switch the order of items” although this is what we see happening, they change the place where the flow of items starts: by switching where main-start is. So our items do display in reverse order, but that is because they start laying out at the other end of the container.

It is also important to remember that when this happens, the effect is purely visual. We are asking the items to display themselves starting at the end edge; they are still flowing in the same order and this is the order that your screen reader uses and also the order they can be tabbed through. You should never use row-reverse when what you really want to do is change the order of the items. Make that change in your document source.

The Two Axes Of Flexbox

We have already exposed an important feature of flexbox: the ability to switch the main axis from row to column. This axis switching is why I think that often it is easier to understand things like alignment in Grid Layout first. With Grid, working in two dimensions, you can align on both axes in pretty much the same way. Flexbox is a little trickier because different things happen depending on whether you are working with the main axis, or the cross axis.

We have already encountered the main axis, i.e. the axis that you define as the value of flex-direction. The cross axis is the other dimension. If you have set flex-direction: row, your main axis is along the row, and your cross axis is down the columns. With flex-direction: column, the main axis is down the column and your cross axis along the rows. It is here where we need to explore another important feature of Flexbox, and that is the fact that it is not tied to the physical dimensions of the screen. We don’t talk about a row running from left to right, or a column from top to bottom, because that is not always the case.

Writing Modes

When I described row and column above, I mentioned the block and inline dimensions. This article is written in English, which is a horizontal writing mode. This means that when you ask Flexbox to give you a row, you get a horizontal display of your flex items. In this case, main-start is on the left — the place in which sentences start in English.

If I were working in a right-to-left language such as Arabic, then the start edge would be on the right:

See the Pen Smashing Flexbox Series 1: row with rtl text by Rachel Andrew (@rachelandrew) on CodePen.

The initial values of flexbox mean that if all I do is create a flex container, my items would start on the right and be displayed moving towards the left. The start edge in the inline direction is the place where sentences start in the writing mode you are using.

If you happen to be in a vertical writing mode and ask for a row, your row will run vertically, because that is the way in which rows of text run in a vertical language. You can try this by adding the writing-mode property to your flex container and setting it to the value vertical-lr. Now, when you set flex-direction to row, you get a vertical column of items.

See the Pen Smashing Flexbox Series 1: row with a vertical writing mode by Rachel Andrew (@rachelandrew) on CodePen.

So a row can run horizontally, with a main-start of the left or the right, and also run vertically with main-start at the top. It’s still a flex-direction of row even if our horizontal text accustomed minds find it hard to think of a row running vertically!

To cause the items to lay themselves out in the block dimension, we set the value of flex-direction to column or column-reverse. In English (or in Arabic), we then see the items displaying one on top of the other down the page, starting at the top of the container.

In a Vertical Writing Mode, the Block dimension runs across the page, as this is the direction blocks are laid out in those writing modes. If you ask for a column in vertical-lr, your blocks will run left to right vertically:

See the Pen Smashing Flexbox Series 1: column in vertical-lr writing mode by Rachel Andrew (@rachelandrew) on CodePen.

However, no matter in which direction the blocks are displayed, if you are working with a column then you are working in the block dimension.

Understanding the fact that a row or a column can run in different physical directions is helpful in understanding some of the terminology being used for Grid and Flexbox. We don’t refer to ‘left and right’ or ‘top and bottom’ in Flexbox and Grid because we don’t make any assumption as to the writing mode of our document. All of CSS is becoming more writing mode aware; if you are interested in some other properties and values being implemented to make the rest of CSS behave in this same way, read my article on Logical Properties and Values.

As a summary, remember that:

  • flex-direction: row

    • main axis = inline dimension
    • main-start will be where sentences begin in that writing mode
    • cross axis = block dimension
  • flex-direction: column

    • main axis = block dimension
    • main-start will be where blocks start to lay out in that writing mode
    • cross axis = inline dimension
Initial Alignment

Some other things happen when we apply display: flex. Some initial alignment happens. In a future article in this series, we will take a good look at alignment; however, in our exploration of display: flex, we should look at the initial values that are applied.

Note: It is worth noting that while these alignment properties started life in the Flexbox specification, the Box Alignment specification will ultimately supersede those defined in the Flexbox specification, as explained in the Flexbox specification.

Main-Axis Alignment

The initial value of justify-content is set to flex-start. It is as if our CSS was:

.container { display: flex; justify-content: flex-start; }

This is the reason that our flex items line up at the start edge of the flex container. It’s also the reason why when we set row-reverse they switch to the end edge because that edge then becomes the start of the main axis.

When you see an alignment property which begins with justify-, then it applies to the main axis in Flexbox. So justify-content performs main-axis alignment and aligns our items to the start.

The other possible values for justify-content are:

  • flex-end
  • center
  • space-around
  • space-between
  • space-evenly (added in Box Alignment)

These values deal with the distribution of available space in the flex container. This is why the items are moved around, or spaced out. If you add justify-content: space-between, then any available space is shared out between the items. However, this can only happen if there is free space to start with. If you had a tightly packed flex container (with no extra space after all the items had been laid out), then justify-content would do nothing at all.

You can see this if you switch your flex-direction to column. Without a height on the flex container there is no free space, so setting justify-content: space-between won’t achieve anything. If you add a height and make it so that the container is taller than is required to display the items, then the property has an effect:

See the Pen Smashing Flexbox Series 1: column with a height by Rachel Andrew (@rachelandrew) on CodePen.

Cross-Axis Alignment

Items are also aligned on the cross axis with a single line flex container; the alignment that we are performing is to align the boxes against each other in the line. In the next example, one of our boxes has more content in than all the others. Something is telling the other boxes to stretch to the same height. That something is the align-items property, which has an initial value of stretch:

See the Pen Smashing Guide to Layout: clearfix by Rachel Andrew (@rachelandrew) on CodePen.

When you see an alignment property which begins with align- and you are in flexbox, then you are dealing with cross-axis alignment, and align-items aligns the items within the flex line. The other possible values are:

  • flex-start
  • flex-end
  • center
  • baseline

If you do not want the boxes to all stretch to the height of the tallest, then setting align-items: flex-start will cause them all to align to the start edge of the cross axis.

See the Pen Smashing Flexbox Series 1: align-items: flex-start by Rachel Andrew (@rachelandrew) on CodePen.

Initial Values For The Flex Items

Finally, the flex items themselves also have initial values, they are set to:

  • flex-grow: 0
  • flex-shrink: 1
  • flex-basis: auto

This means that our items will not grow by default to fill the available space on the main axis. If flex-grow were set to a positive value, this would cause the items to grow and take up any available space.

The items can shrink, however, as flex-shrink is set to the positive value of 1. This means that if we have a very narrow flex container, then the items will get as small as they can before any overflow happens. This is sensible behavior; in general, we want things to stay inside their boxes and not overflow if there is space to display them.

In order to get the best possible layout by default, flex-basis is set to auto. We will have a proper look at what that means in a future article in this series, however, most of the time you can think of auto as “big enough to fit the content”. What you will see happen, when you have flex items that fill the container, and one of those items has a larger amount of content than the others, the larger item will be given more space.

See the Pen Smashing Flexbox Series 1: initial values of flex items by Rachel Andrew (@rachelandrew) on CodePen.

This is Flexbox’s flexibility in action. With a flex-basis of auto and no sizing applied to the items, the flex items have a base size of the max-content size. This would be the size they would be if they stretched out and did no wrapping whatsoever. Then, space is taken away from each item in proportion, detailed in the following note in the flexbox specification.

“Note: The flex shrink factor is multiplied by the flex base size when distributing negative space. This distributes negative space in proportion to how much the item is able to shrink, so that e.g. a small item won’t shrink to zero before a larger item has been noticeably reduced.”

The larger item has less space taken away and so we get the final layout. You can compare the two screenshots below, both taken using the example above. However, in the first screenshot, the third box has a smaller amount of content, and therefore our columns have a more equal distribution of space.

The items flex to give the larger item more room (Large preview)

Flexbox here is helping us to end up with a reasonable end result given no other input from the person writing the CSS. Rather than reduce the space evenly and end up with a very tall item with a couple words on each line, it assigns that item more space to lay itself out. Within this kind of behavior is the key to the real use cases for Flexbox. Flexbox is at its best when used to lay sets of things out — along one axis — in a flexible and content aware way. I’m touching on a little of the detail here, but we will take a proper look at these algorithms later in this series.

Summary

In this article, I’ve taken the initial values of Flexbox, in order to explain what actually happens when you say display: flex. It’s a surprising amount once you begin to unpack it, and contained within these few properties are many of the key features of flex layouts.

Flex layouts are flexible: they try to make good choices by default about your content — squishing and stretching to get the best readability. Flex layouts are writing mode aware: the directions of row and column relate to the writing mode being used. Flex layouts allow alignment of the items as a group on the main axis, by choosing how space is distributed. They allow alignment of items within their flex line, moving the items on the cross axis in relationship to each other. Importantly, flex layouts understand how big your content is, and try to make good basic decisions in order to display it. In future articles, we will explore these areas in more depth, and consider further exactly when and why we might choose to use Flexbox.

(il)
Categories: Web Design

Sunshine All Day Every Day (August 2018 Wallpapers Edition)

Tue, 07/31/2018 - 04:11
Sunshine All Day Every Day (August 2018 Wallpapers Edition) Sunshine All Day Every Day (August 2018 Wallpapers Edition) Cosima Mielke 2018-07-31T13:11:56+02:00 2018-08-17T10:16:34+00:00

Everybody loves a beautiful wallpaper to freshen up their desktops. So to cater for new and unique artworks on a regular basis, we embarked on our monthly wallpapers adventure nine years ago, and since then, countless artists and designers from all over the world have accepted the challenge and submitted their designs to it. It wasn’t any different this time around, of course.

This post features wallpapers created for August 2018. Each of them comes in versions with and without a calendar and can be downloaded for free. A big thank-you to everyone who participated!

Finally, as a little bonus, we also collected some “oldies but goodies” from previous August editions in this collection. Please note, that they only come in a non-calendar version. Which one will make it to your desktop this month?

Please note that:

  • All images can be clicked on and lead to the preview of the wallpaper,
  • We respect and carefully consider the ideas and motivation behind each and every artist’s work. This is why we give all artists the full freedom to explore their creativity and express emotions and experience throughout their works. This is also why the themes of the wallpapers weren’t anyhow influenced by us, but rather designed from scratch by the artists themselves.
Submit your wallpaper

We are always looking for creative designers and artists to be featured in our wallpapers posts. So if you have an idea for a wallpaper, please don’t hesitate to submit your design. We’d love to see what you’ll come up with. Join in! →

Meet Smashing Book 6 with everything from design systems and accessible single-page apps to CSS Custom Properties, Grid, Service Workers, performance, AR/VR and responsive art direction. New frontiers in front-end and UX with Marcy Sutton, Harry Roberts, Laura Elizabeth and many others.

Table of Contents → Purple Haze

“Meet Lucy: she lives in California, loves summer and sunbathing at the beach. This is our Jimi Hendrix Experience tribute. Have a lovely summer!” — Designed by PopArt Web Design from Serbia.

Coffee Break Time

Designed by Ricardo Gimenes from Sweden.

A Midsummer Night’s Dream

“Inspired by William Shakespeare.” — Designed by Sofie Lee from South Korea.

This August, Be The Best!

“Here is the August monthly calendar to remind you of your as well as your team’s success in the previous months. Congratulations, you guys deserved all the success that came your way. Hope you continue this success this month and in the coming months.” — Designed by Webandcrafts from India.

No Drama LLama

“Llamas are showing up everywhere around us, so why not on our desktops too?” — Designed by Melissa Bogemans from Belgium.

The Colors Of Life

“The countenance of the clown is a reflection of our own feelings and emotions of life in the most colorful way portrayed with a deeper and stronger expression whether it is a happy clown or a sad clown. The actions of the clown signify your uninhibited nature — the faces of life in its crudest form — larger, louder, and in an undiluted way.” — Designed by Acowebs from India.

Hello August

“August brings me to summer, and summer brings me to fruit. In the hot weather there is nothing better than a fresh piece of fruit.” — Designed by Bram Wieringa from Belgium.

Exploring Thoughts

“Thoughts, planning, daydreams are simply what minds do. It’s following the human impulse to explore the unexplored, question what doesn’t ring true, dig beneath the surface of what you think you know to formulate your own reality, and embrace the inherent ‘now’ of life. The main character here has been created blending texture and composition. Thoughts will never have an end.” — Designed by Sweans from London.

Chilling At The Beach

“In August it’s Relaxation Day on the 15th so that’s why I decided to make a wallpaper in which I showcase my perspective of relaxing. It’s a wallpaper where you’re just chilling at the beach with a nice cocktail and just looking at the sea and looking how the waves move. That is what I find relaxing! I might even dip my feet in the water and go for a swim if I’m feeling adventurous!” — Designed by Senne Mommens from Belgium.

Let Peace Reign

“The freedom and independence sprouts from unbiased and educated individuals that build the nation for peace, prosperity and happiness to reign in the country for healthy growth.” — Designed by Admission Zone from India.

On The Ricefields Of Batad

“Somebody once told me that I should make the most out of vacation. So there I was, carefully walking on a stone ridge in the ricefields of Batad. This place is hidden high up in the mountains. Also August is harvesting season.” — Designed by Miguel Lammens from Belgium.

Fantasy

Designed by Ilse van den Boogaart from The Netherlands.

Oldies But Goodies

The past nine years have brought forth lots of inspiring wallpapers, and, well, it’d be a pity to let them gather dust somewhere down in the archives. That’s why we once again dug out some goodies from past August editions that are bound to make a great fit on your desktop still today. Please note that these wallpapers, thus, don’t come with a calendar.

Happiness Happens In August

“Many people find August one of the happiest months of the year because of holidays. You can spend days sunbathing, swimming, birdwatching, listening to their joyful chirping, and indulging in sheer summer bliss. August 8th is also known as the Happiness Happens Day, so make it worthwhile.” — Designed by PopArt Studio from Serbia.

Psst, It’s Camping Time...

“August is one of my favorite months, when the nights are long and deep and crackling fire makes you think of many things at once and nothing at all at the same time. It’s about these heat and cold which allow you to touch the eternity for a few moments.” — Designed by Igor Izhik from Canada.

Bee Happy!

“August means that fall is just around the corner, so I designed this wallpaper to remind everyone to ‘bee happy’ even though summer is almost over. Sweeter things are ahead!” — Designed by Emily Haines from the United States.

Hello Again

“In Melbourne it is the last month of quite a cool winter so we are looking forward to some warmer days to come.” — Designed by Tazi from Australia.

A Bloom Of Jellyfish

“I love going to aquariums – the colours, patterns and array of blue hues attract the nature lover in me while still appeasing my design eye. One of the highlights is always the jellyfish tanks. They usually have some kind of light show in them, which makes the jellyfish fade from an intense magenta to a deep purple – and it literally tickles me pink. On a recent trip to uShaka Marine World, we discovered that the collective noun for jellyfish is a bloom and, well, it was love-at-first-collective-noun all over again. I’ve used some intense colours to warm up your desktop and hopefully transport you into the depths of your own aquarium.” — Designed by Wonderland Collective from South Africa.

Let Us Save The Tigers

“Let us take a pledge to save these endangered species and create a world that is safe for them to live and perish just like all creatures.” — Designed by Acodez IT Solutions from India.

Shades

“It’s sunny outside (at least in the Northern Hemisphere!), so don’t forget your shades!” — Designed by James Mitchell from the United Kingdom.

Ahoy

Designed by Webshift 2.0 from South Africa.

About Everything

“I know what you’ll do this August. :) Because August is about holiday. It’s about exploring, hiking, biking, swimming, partying, feeling and laughing. August is about making awesome memories and enjoying the summer. August is about everything. An amazing August to all of you!” — Designed by Ioana Bitin from Bucharest, Romania.

Shrimp Party

“A nice summer shrimp party!” — Designed by Pedro Rolo from Portugal.

The Ocean Is Waiting

“In August, make sure you swim a lot. Be cautious though.” — Designed by Igor Izhik from Canada.

Oh La La… Paris Night

“I like the Paris night! All is very bright!” — Designed by Verónica Valenzuela from Spain.

World Alpinism Day

“International Day of Alpinism and Climbing.” Designed by cheloveche.ru from Russia.

Estonian Summer Sun

“This is a moment from Southern Estonia that shows amazing summer nights.” Designed by Erkki Pung / Sviiter from Estonia.

Aunt Toula At The Beach

“A memory from my childhood summer vacations.” — Designed by Poppie Papanastasiou from Greece.

Flowing Creativity

Designed by Creacill, Carole Meyer from Luxembourg.

Searching for Higgs Boson

Designed by Vlad Gerasimov from Russia.

Unforgettable Summer Night

Designed by BootstrapDash from India.

Join In Next Month!

Thank you to all designers for their participation. Join in next month!

Categories: Web Design

Pages