Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Focus management

Focus determines which view receives keyboard input. Vizia tracks focus in the window event system and exposes the result through pseudo-classes such as :focus, :focus-visible, and :focus-within.

Styling focused views

Use CSS pseudo-classes to make focus obvious:

textbox:focus-visible,
button:focus-visible {
	outline-width: 2px;
	outline-color: dodgerblue;
	outline-offset: 2px;
}

.form-row:focus-within {
	background-color: rgba(30, 144, 255, 0.08);
}

focus-visible is the most useful default for keyboard users because it avoids showing a focus ring on every pointer interaction.

Moving focus programmatically

Inside an event handler, call cx.focus() to move focus to the current view. If you need to control whether the focused view should also appear :focus-visible, use cx.focus_with_visibility(...).

Element::new(cx)
	.role(Role::Button)
	.navigable(true)
	.on_press(|cx| {
		cx.focus_with_visibility(true);
		cx.emit(AppEvent::OpenPalette);
	});

Trapping focus inside a subtree

Modal interfaces should stop Tab from escaping into the background UI. Use lock_focus_to_within() on the root of the modal subtree.

Window::popup(cx, true, |cx| {
	VStack::new(cx, |cx| {
		Label::new(cx, "Save changes?");
		Button::new(cx, |cx| Label::new(cx, "Confirm"));
		Button::new(cx, |cx| Label::new(cx, "Cancel"));
	})
	.lock_focus_to_within();
});

This keeps keyboard navigation contained until the modal closes.

Common mistakes

  • Moving focus without also exposing a visible focus style.
  • Leaving focus on background content when opening a popup or dialog.

For tab-order behavior and keyboard activation patterns, see Keyboard navigation.