A non-exhaustive list of details that make a good web interface.
See the codeThis document outlines a non-exhaustive list of details that make a good (web) interface. It is a living document, periodically updated based on learnings. Some of these may be subjective, but most apply to all websites.
The WAI-ARIA spec is deliberately not duplicated in this document. However, some accessibility guidelines may be pointed out. Contributions are welcome. Edit this file and submit a pull request.
<form> to submit by pressing Entertype like password, email, etcspellcheck and autocomplete attributes most of the timerequired attribute when appropriateuser-select for inner contentpointer-events to not hijack eventspadding-webkit-font-smoothing: antialiased applied for better legibilitytext-rendering: optimizeLegibility applied for better legibilityclamp(), e.g. clamp(48px, 5vw, 72px) for the font-size of a headingfont-variant-numeric: tabular-nums, particularly in tables or when layout shifts are undesirable, like in timers-webkit-text-size-adjust: 100%scroll-behavior: smooth for navigating to in-page anchors, with an appropriate offset@media (hover: hover) 3muted and playsinline to <video /> tags to auto play on iOStouch-action for custom components that implement pan and zoom gestures to prevent interference from native behavior like zooming and scrolling-webkit-tap-highlight-color: rgba(0,0,0,0), but always replace it with an appropriate alternativeblur() values for filter and backdrop-filter may be slowtransform: translateZ(0) for unperformant animationswill-change on unperformant scroll animations for the duration of the animation 4mousedown, not clickprefers-color-schemearia-label<img> for screen readers and ease of copying from the right click menuaria-label instead of announcing the raw DOM tree to people using screen readers::selection state::selectionSwitching between dark mode or light mode will trigger transitions on elements that are meant for explicit interactions like hover. We can disable transitions temporarily to prevent this. For Next.js, use next-themes which prevents transitions out of the box. ↩
This is a matter of taste but some interactions just feel better with no motion. For example, the native macOS right click menu only animates out, not in, due to the frequent usage of it. ↩
Most touch devices on press will temporarily flash the hover state, unless explicitly only defined for pointer devices with @media (hover: hover). ↩
Use will-change as a last resort to improve performance. Pre-emptively throwing it on elements for better performance may have the opposite effect. ↩
This might be controversial but sometimes it can be beneficial to manipulate the DOM directly. For example, instead of relying on React re-rendering on every wheel event, we can track the delta in a ref and update relevant elements directly in the callback. ↩
Disabled buttons do not appear in tab order in the DOM so the tooltip will never be announced for keyboard users and they won't know why the button is disabled. ↩
As of 2023, Safari will not take the border radius of an element into account when defining custom outline styles. Safari 16.4 has added support for outline following the curve of border radius. However, keep in mind that not everyone updates their OS immediately. ↩
(top 24 of 33)
660 followers · starred May 2023
11,374 followers · starred May 2023
11,582 followers · starred May 2023
138 followers · starred Nov 2023
A non-exhaustive list of details that make a good web interface.
See the codeThis document outlines a non-exhaustive list of details that make a good (web) interface. It is a living document, periodically updated based on learnings. Some of these may be subjective, but most apply to all websites.
The WAI-ARIA spec is deliberately not duplicated in this document. However, some accessibility guidelines may be pointed out. Contributions are welcome. Edit this file and submit a pull request.
<form> to submit by pressing Entertype like password, email, etcspellcheck and autocomplete attributes most of the timerequired attribute when appropriateuser-select for inner contentpointer-events to not hijack eventspadding-webkit-font-smoothing: antialiased applied for better legibilitytext-rendering: optimizeLegibility applied for better legibilityclamp(), e.g. clamp(48px, 5vw, 72px) for the font-size of a headingfont-variant-numeric: tabular-nums, particularly in tables or when layout shifts are undesirable, like in timers-webkit-text-size-adjust: 100%scroll-behavior: smooth for navigating to in-page anchors, with an appropriate offset@media (hover: hover) 3muted and playsinline to <video /> tags to auto play on iOStouch-action for custom components that implement pan and zoom gestures to prevent interference from native behavior like zooming and scrolling-webkit-tap-highlight-color: rgba(0,0,0,0), but always replace it with an appropriate alternativeblur() values for filter and backdrop-filter may be slowtransform: translateZ(0) for unperformant animationswill-change on unperformant scroll animations for the duration of the animation 4mousedown, not clickprefers-color-schemearia-label<img> for screen readers and ease of copying from the right click menuaria-label instead of announcing the raw DOM tree to people using screen readers::selection state::selectionSwitching between dark mode or light mode will trigger transitions on elements that are meant for explicit interactions like hover. We can disable transitions temporarily to prevent this. For Next.js, use next-themes which prevents transitions out of the box. ↩
This is a matter of taste but some interactions just feel better with no motion. For example, the native macOS right click menu only animates out, not in, due to the frequent usage of it. ↩
Most touch devices on press will temporarily flash the hover state, unless explicitly only defined for pointer devices with @media (hover: hover). ↩
Use will-change as a last resort to improve performance. Pre-emptively throwing it on elements for better performance may have the opposite effect. ↩
This might be controversial but sometimes it can be beneficial to manipulate the DOM directly. For example, instead of relying on React re-rendering on every wheel event, we can track the delta in a ref and update relevant elements directly in the callback. ↩
Disabled buttons do not appear in tab order in the DOM so the tooltip will never be announced for keyboard users and they won't know why the button is disabled. ↩
As of 2023, Safari will not take the border radius of an element into account when defining custom outline styles. Safari 16.4 has added support for outline following the curve of border radius. However, keep in mind that not everyone updates their OS immediately. ↩
(top 24 of 33)
660 followers · starred May 2023
11,374 followers · starred May 2023
11,582 followers · starred May 2023
138 followers · starred Nov 2023