Interaction

Small screen devices like mobile phones often have touchscreens. Large screen devices like laptops and desktop computers often come with hardware like a mouse or a trackpad. It’s tempting to equate small screens with touch and large screens with pointers.

But the reality is more nuanced. Some laptops have touch screen capabilities. Users can interact with either a touchscreen or a trackpad or both. Likewise it’s possible to use an external keyboard or mouse with a touchscreen device like a tablet.

Instead of trying to infer the input mechanism from screen size, use media features in CSS.

Pointer

You can test for three possible values with the pointer media feature: none, coarse, and fine.

If a browser reports a pointer value of none the user might be using a keyboard to interact with your website.

If a browser reports a pointer value of coarse it means the primary input mechanism isn’t very accurate. A finger on a touchscreen is a coarse pointer.

If a browser reports a pointer value of fine it means the primary input mechanism is capable of fine-grained control. A mouse or stylus is a fine pointer.

You can adjust the size of your interface elements to suit the pointer value. Try visiting this website in different kinds of devices to see how the interface adapts.

In this example, buttons are made larger for coarse pointers:

button {
  padding: 0.5em 1em;
}
@media (pointer: coarse) {
  button {
    padding: 1em 2em;
  }
}

It’s possible to also make elements smaller for fine pointers but be careful about doing this:

Don't
@media (pointer: fine) {
  button {
    padding: 0.25em 0.5em;
  }
}

Even if someone has a primary input mechanism capable of fine-grained control, think twice before reducing the size of interactive elements. Fitts’s Law still applies. A smaller target requires more concentration even with a fine pointer. A larger target area benefits everyone regardless of pointing device.

Any pointer

The pointer media feature reports the fineness of the primary input mechanism. But many devices have more than one input mechanism. It’s possible that someone is interacting with your website using both a touchscreen and a mouse at the same time.

The any-pointer differs from the pointer media feature in that it reports if any pointing device passes the test.

An any-pointer value of none means that no pointing device is available.

An any-pointer value of coarse means that at least one pointing device is not very accurate. But that might not be the primary input mechanism.

An any-pointer value of fine means that at least one pointing device is capable of fine-grained control. But again, this might not be the primary input mechanism.

Because the any-pointer media query will report a positive result if any of the input mechanisms pass the test, it’s possible for a browser to report a result for any-pointer: fine and also report a result for any-pointer: coarse. In that case the order of your media queries matters. The last one will take precedence.

In this example, if the device has both a fine and a coarse input mechanism, the coarse styles are applied.

@media (any-pointer: fine) {
  button {
    padding: 0.5em 1em;
  }
}
@media (any-pointer: coarse) {
  button {
    padding: 1em 2em;
  }
}

Hover

The hover media feature reports on whether the primary input mechanism can hover over elements. This usually means there’s some kind of cursor on the screen being controlled by a mouse or a trackpad.

Unlike the pointer media feature which differentiates between fine and coarse pointers, the hover media feature is binary. If the primary input device is capable of hovering over elements it will report a value of hover. Otherwise the value is none.

In this example, some supplementary icon is available on hover but only if the primary input device is capable of hovering over an element.

button .extra {
  visibility: visible;
}
@media (hover: hover) {
  button .extra {
    visibility: hidden;
  }
  button:hover .extra {
    visibility: visible;
  }
}

If you use your mouse to hover over that button, the icon will appear. But if you use your keyboard to tab to the button, the icon remains invisible. When you use the keyboard, you’re focusing rather than hovering. A desktop device with a mouse attached will report that the primary input mechanism is capable of hovering, which is true. But anyone using a keyboard while a mouse is attached won’t get the benefit of the :hover styles. So it’s a good idea to combine :hover and :focus styles to cover both interactions.

button .extra {
  visibility: visible;
}
@media (hover: hover) {
  button .extra {
    visibility: hidden;
  }
  button:is(:hover, :focus) .extra {
    visibility: visible;
  }
}

Even if the primary input device is capable of hovering over elements, be careful about hiding information behind a hover interaction. The information becomes less discoverable. Don’t use hover to hide important information or an important interface element.

Any hover

The hover media query only reports on the primary input mechanism. Some devices have multiple input mechanisms: touchscreen, mouse, keyboard, trackpad.

Just as any-pointer reports on any of the input mechanisms, any-hover will be true if any of the available input mechanisms are capable of hovering over elements.

If you decided to reverse the logic in the previous example, you could make the hover styles the default and then remove them if any-hover has a value of none.

button .extra {
  visibility: hidden;
}
button:hover .extra,
button:focus .extra {
  visibility: visible;
}
@media (any-hover: none) {
  button .extra {
    visibility: visible;
  }
}

On a device that has no input mechanism capable of hovering, the extra icon is always visible.

Virtual keyboards

People use cursors and fingers to explore interfaces but when it comes time to enter information, they need a keyboard. That’s fine if there’s a physical keyboard attached to their device, but if they’re using a touchscreen device it’s a little more complicated. These devices provide on-screen virtual keyboards.

Input types

Unlike a physical keyboard, virtual keyboards can be tailored to match the expected input. If you provide information about the expected input, devices can serve up the most appropriate virtual keyboard.

HTML5 input types are a great way of describing your input elements. The type attribute accepts values such as email, number, tel, url, and more.

  <label for="email">Email</label>
  <input type="email" id="email">
  <label for="number">Number</label>
  <input type="number" id="number">
  <label for="tel">Tel</label>
  <input type="tel" id="tel">
  <label for="url">URL</label>
  <input type="url" id="url">

Input modes

Browser Support

  • Chrome: 66.
  • Edge: 79.
  • Firefox: 95.
  • Safari: 12.1.

Source

The inputmode attribute gives you fine-grained control over virtual keyboards. For example, whereas there’s one input type with a value of number, you can use the inputmode attribute to differentiate between whole numbers and decimals.

If you’re asking for a whole number, like somebody’s age, use inputmode="numeric".

<label for="age">Age</label>
<input type="number" id="age" inputmode="numeric">

If you’re asking for a number that includes decimal places, like a price, use inputmode="decimal".

<label for="price">Price</label>
<input type="number" id="price" inputmode="decimal">

Autocomplete

Nobody likes filling in forms. As a designer, you can improve the experience for your users by enabling them to automatically fill in form fields. The autocomplete attribute provides you with a host of options for improving contact forms, log-in forms, and checkout forms.

<label for="name">Name</label>
<input type="text" id="name" autocomplete="name">
<label for="country">Country</label>
<input type="text" id="country" autocomplete="country">
<label for="email">Email</label>
<input type="email" id="email" autocomplete="email">

These HTML attributes—type, inputmode, and autocomplete—are small additions to your form fields, but they can make a big difference to the user experience. By anticipating and responding to your user’s device capabilities, you are empowering your users. For more in-depth information, there’s a course dedicated to helping you learn forms.

Next up in this course, it’s time to examine some common interface patterns.

Check your understanding

Test your knowledge of interactions

Which feature should you use rather than trying to infer a user's input type from screen size?

CSS media features
Like @media (pointer: coarse) or @media (-any-pointer: coarse)
Ask the user with JavaScript's prompt()
Not ideal to ask directly.
CSS media type handheld
This has been deprecated in Media Queries 4.

What is the difference between @media (pointer) and @media (any-pointer)?

Any pointer includes things like your finger as a pointer.
Pointer already includes touch as an input type.
Pointers don't include things like a mouse.
Pointers do include a mouse as an input device.
Any pointer will report true when additional, non-primary inputs, like a stylus, pass the test.
any-pointer queries all device input types for any match.

Which input types show a more appropriate virtual keyboard for users?

type="url"
Keyboard will offer buttons to support typing URLs.
type="tel"
Keyboard will offer buttons to support typing phone numbers.
type="number"
Keyboard will offer buttons to support typing only numbers.
type="email"
Keyboard will offer buttons to support typing email addresses.