When you update the page you should think about placing the focus.
Changing the focus will generally make a screen reader start reading from the focused position. Placing the focus on new content can help make your app accessible to users with vision or motor impairments, or to users that prefer the keyboard over the mouse.
When updating a fragment you may control how Unpoly moves focus by passing
a { focus }
option or [up-focus]
attribute.
When you don't pass a { focus }
option or set an [up-focus]
attribute, Unpoly has some defaults:
{ focus: 'keep' }
. This will preserve focus in updated fragments.{ focus: 'auto' }
. In most cases this focuses the new fragment.Pass { focus: 'target' }
to focus the new fragment.
Pass { focus: 'layer' }
to focus the layer of the updated fragment.
Pass a CSS selector string to focus a matching element:https://en.wikipedia.org/wiki/Focus_(computing)
up.render({
target: '.content',
url: '/advanced-search',
focus: 'input[type=search]'
})
From JavaScript you may also pass the Element
object that should be focused.
If the element isn't already focusable, Unpoly will give it an [tabindex=-1]
attribute.
Pass { focus: 'keep' }
to preserve focus-related state through a fragment update.
For instance, when a focused <input>
element is swapped out with a new fragment,
{ focus: 'keep' }
will cause the same input to be focused after the update.
The following properties are preserved:
Pass { focus: 'restore' }
to restore an previously saved focus state
for the updated layer's URL.
Unpoly will automatically save focus-related state before a fragment update.
You may disable this behavior with { saveFocus: false }
.
#hash
targetPass { focus: 'hash' }
to focus the element matching the #hash
in the URL.
Pass { focus: 'main' }
to reveal the updated layer's main element.
Pass { focus: false }
to not actively manipulate focus.
Note that even with { focus: false }
the focus may change during a fragment update. For instance, when a fragment contains focus and is then swapped, focus will revert to the <body>
element.
To actively try and preserve focus, use { focus: 'keep' }
instead.
To only focus when a main target is updated,
you may append -if-main
to any of the string options in this list.
E.g. { focus: 'reset-if-main' }
will reset focus positions, but only if a main target is updated.
To only focus when the focus was lost with the old fragment,
you may append -if-lost
to any of the string options in this list.
E.g. { focus: 'target-if-lost' }
will focus the new fragment, but only if the update caused focus
to be lost.
To implement other conditions, pass a function instead.
Pass an array of focus option and Unpoly will use the first applicable value.
E.g. { focus: ['hash', 'reset'] }
will first try to an element mathing the #hash
in the URL.
If the URL has no #hash
, focus positions will be reset.
In an [up-focus]
attribute you may separate scroll options with an or
:
<a href="/path#section" up-follow up-focus="hash or reset">Link label</a>
Pass { focus: 'auto' }
to try a sequence of focus strategies that works for most cases.
This is the default when navigating.
#hash
in the URL.[autofocus]
element in the new fragment.You may configure this logic in up.fragment.config.autoFocus
.
You may also pass a function with your custom focusing logic.
The function will be called with the updated fragment and an options object. The function is expected to either:
{ scroll }
option.
Both Element#focus()
and up.focus()
accept a { preventScroll: true }
option to prevent scrolling.Unpoly lets you control whether a fragment shows a visible focus ring.
When opening an overlay the first applicable strategy will be used:
[autofocus]
element in the new overlay.By default focus is trapped for all overlays except popups. Moving a trapped focus outside the overlay will immediately re-focus it. This prevents keyboard users from accidentally skipping to content from other layers.
Occasionally the focus trap may conflict with overlays opened by overlays opened by other JavaScript libraries. You can address this by configuring up.layer.config.foreignOverlaySelectors
.
To disable focus trapping entirely, configure up.layer.config.overlay.trapFocus = false
or open the overlay with { trapFocus: false }
.
When updating a fragment within an existing overlay, all focus strategies above can be used.
When an overlay is closed, the link that originally opened the overlay is re-focused.
Ihe layer was opened programmatically without an { origin }
option, the origin link is unknown. In that case the the parent layer is focused.