DEV Community

Cover image for 7 Easy UX Improvements for your Webapp
Andrew K
Andrew K

Posted on

7 Easy UX Improvements for your Webapp

Introduction

Finishing my series of articles, I decided to wrap it up with a list of simpler tricks from my experience spanning across different aspects of web development, tricks not big enough for a separate article. With their own caveats, these are generally safe to just slap with a few lines of code and a little familiarization of said caveats.
As always, the topics cover the gap designers usually don't cover and developers usually don't notice.


Transitions with AutoAnimate

One of the harder things to animate are lists of items, especially when they are spanning across 2 axes. That's where @formkit/auto-animate shines the most - with a single line of code you can add some much-needed transitions to when an item gets moved, added, or deleted. Transitions that will help in visually indicating to users what exactly has changed.

Simple example of AutoAnimation motion

With only 2.9kB gzipped, it offers a zero-config, drop-in animation utility that has many use cases, such as animating accordions and input errors, and bundles support not only for Native JS but for React, Solid, Vue, Preact, Svelte, and Angular as well. The transition animation is customizable and respects the prefers-reduced-motion setting. You can find more on it in the docs.

<script type="module">
  import autoAnimate from './js/autoAnimate.js'
  const dropdown = document.getElementById('list-container')
  autoAnimate(dropdown)
</script>

Enter fullscreen mode Exit fullscreen mode

I personally used it in a few production React apps for accordions, input errors, and lists, and it worked 9/10 times (due to layout specifics).

Target size

A topic I have a whole article about is a practice to make interactive elements easy enough to click/touch by increasing their size. There's a WCAG standard, and a good size to aim for is 44x44 CSS pixels. There are a number of situations, and in the simplest case with single elements, you can just add necessary extra padding to them, and to counteract the layout shift, you can apply a similar negative margin. With Tailwind it will look like just -m-4 p-4, and with CSS:

.target-element {
  margin: -16px;
  padding: 16px;
}

Enter fullscreen mode Exit fullscreen mode

Comparing default and increased target size without affecting the outside layout

In other cases, you might want to include other elements with your target element by using <label>. A situation I've seen many times neglected, leaving tiny checkboxes the only part that can be clicked to toggle them.

Comparing input's target area without and with labels

Why is it important? Because accessibility is all about making interfaces usable in a wider range of conditions, and these can be not only health-related specifics but also an inconvenient environment, like shaking transport or malfunctioning touch devices.
With just a few lines of code, we can expand the accessibility of our app in these conditions. And of course, it will be just a little more pleasant to use for everyone else.

Virtual keyboard shapes

Just like there are multiple types of inputs for collecting different types of data, there are different shapes a virtual keyboard can take to assist in entering this data. Virtual keyboards are used not only on mobile phones and tablets but also on laptops equipped with touchscreens.
Now there are 3 attributes that can actually affect the virtual keyboard presented to the user, and 2 of them are specifically meant for this.

  • Input's type attribute defines the shape of the input and what type of value it expects. While user agents may assume appropriate inputmode based on that with values like tel, url, and email, sometimes it may not be exactly what you want. And at least on iOS it handles numeric values differently (notice the lack of emoji button at the bottom).

iOS keyboard with type=

iOS keyboard with type="number"
  • inputmode attribute is exactly for this, with values like "tel" | "url" | "email" | "numeric" | "decimal" | "search" it allows you to specify the appropriate virtual keyboard without affecting anything else.
  • enterkeyhint defines what action label (or icon) to present for the enter key on virtual keyboards. It accepts only predefined values like 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send', and the actual displayed result depends on user agent implementation. Keep in mind that just like inputmode this is only a hint - the actual logic for something like next and previous will have to be implemented separately.

iOS keyboard with inputmode=

inputmode="email" + enterkeyhint="search"

Keyboard shortcuts

If your interface involves a sequence of repetitive actions, shortcuts are a great way to speed things up. With a lack of standards, it might be a little hard to come up with a combination that would be intuitive to use and easy to remember. With the amount of browsers and OSs, it might be hard to find a combination that hasn't already been taken. Ideally, we would need to match a hotkey that will already be associated with the corresponding action from the previous user's experience. After all, your users are also interacting with dozens of other interfaces besides yours. That is, it seems to be acceptable to override browser/system shortcuts, but with a lot of considerations (to allow remapping or disabling them).

Notion's list of keyboard shortcuts

Notion's list of keyboard shortcuts

Let's try to cover the most common and generally safe ones:
Esc - Close modal/dialog, cancel action. <dialog> supports it out of the box.
Enter, Ctrl + Enter / Cmd + Enter – Submit (send message, submit form, etc.). With the <form> element, you can get submit on Enter automatically inside inputs, but you might want to add this manually for <textarea>.
↑↓ - a little special usecase built in <input type="number" />, make sure you don't lose it if you are handling numbers.
Ctrl + K / Cmd + K - becomes more common to use for search or command palette, seemingly started by Slack. There are libraries for components that come with this shortcut now.
Ctrl + / – Also command palette or help menu.
Formatting hotkeys (Ctrl + B, Ctrl + I, Ctrl + U) - some text editor libraries already come with them. Usually these are okay to override reserved combinations, assuming that the user easily unfocuses the editor to lose the override.

Now you can actually add event listeners to the whole page or just to the element you want your shortcuts to take effect in. Make sure to handle both Windows and macOS special keys. e.preventDefault() here is to stop the default behavior of the hotkey.

document.addEventListener('keydown', (e) => {
  if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {
    e.preventDefault();
    openSearchBar();
  }
});
Enter fullscreen mode Exit fullscreen mode
<form
  onKeyDown={(e) => {
    if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {
      e.preventDefault();
      openSearchBar();
    }
  }}
>
  {...}
</form>
Enter fullscreen mode Exit fullscreen mode

View Transitions

With hardware advancement and increasing internet speed, web apps are also bulkier and can still have a noticeable loading process for switching between pages, usually accompanied by an empty screen. To reduce perceived loading latency, we can add a smooth transition there, and to do that, the easiest way would be to use the View Transitions API.
View Transitions can be used for both MPA to transition between pages and SPA for changes to parts of the DOM. It ensures that any element that’s getting unchanged stays exactly in place, with no blinks, and the changing elements transition in a crossfade.

Page navigation with View Transitions

View Transitions are supported by most of the browsers (82% at the time), and you can start using them for page navigation today as progressive enhancement. These 2 lines of code are all you need for a start, before you decide to customize the transition animation and manipulate the view transition itself which the API also allows.

@view-transition {
  navigation: auto;
}
Enter fullscreen mode Exit fullscreen mode

Skip links

The standard way of putting navigation links on the web is at the very top of every page, right before the main content. Where a mouse or touchscreen user could just point straight down, a keyboard user has to grind through this repeated content that can have dozens of entries before they can get to the primary part. For the purpose of getting straight to the main part, a lot of pages have Skip Links placed before the header (dev.to also has a skip link, try reloading the page and pressing tab). It makes sense to add it if your header has, say, 4+ elements in it.

Focused Skip Link on dev.to

A Skip Link is just an anchor tag visually hidden that targets an existing ID on the current page. It should be positioned as the first focusable element inside the body and header.

You can even have more than one Skip Link positioned one after another if you have a particularly lengthy content.

Corresponding WCAG rule - 2.4.1 Bypass Blocks.

For correct visual hiding, there are a few catches that are explained here, and with the recommended pattern at the end, it will be more robust than simple absolute positioning with offsetting.

Tailwind offers the sr-only class implementing this pattern (with the name being a little off since it's not only for screen readers) that you would need to prepend with focus:, or you can use the plain CSS version below.

<header>
  <a href="#main" class="skip-link">
    Skip to main content
  </a>
  <!-- Other header content -->
</header>
<main id="main">
  <!-- Main page content -->
</main>
Enter fullscreen mode Exit fullscreen mode
.skip-link:not(:focus):not(:active) {
  clip-path: inset(50%);
  height: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}
Enter fullscreen mode Exit fullscreen mode

PWA Shortcuts

Just like native apps, PWAs can be installed on mobile and desktop devices, which will give the app access to more device-specific APIs and the users a way to use it quicker with fewer browser distractions. Converting to PWA is as easy as adding a manifest.json file with a few necessary fields. With one single addition, we can go a little further and give our users a way to quickly jump to the most commonly used screens.

Shortcuts list on Windows and Android

This list of shortcuts is only displayed by right-clicking or long-pressing the app icon, meaning they're only available once the PWA is installed on the user's device.

To define shortcuts for your PWA, use the shortcuts property of your app's manifest.json. This property is an array of objects defining each shortcut's name and URL, as well as the optional short name, description, and icons. For example, here's the web app manifest of a calendar app that defines two shortcuts:

{
  "name": "Calendar",
  "start_url": "/",
  "display": "standalone",
  "icons": [...],
  "shortcuts": [
    {
      "name": "New event",
      "url": "/new-event"
    },
    {
      "name": "View today's events",
      "url": "/today"
    }
  ]
}

Enter fullscreen mode Exit fullscreen mode

Wrap up

Applying even all of these points won't really cost you anything. So if we can make our apps a little more pleasant, why not do it?
If you feel like something could be presented better, feel free to reach out!

Resources

https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/inputmode
https://www.tempertemper.net/blog/skip-links-what-why-and-how?ref=dailydev#main
https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/How_to/Expose_common_actions_as_shortcuts

Top comments (0)