Building accessible web applications shouldn't be an afterthought. Oorian provides a suite of built-in accessibility components that make WCAG compliance straightforward. These components handle the complex accessibility patterns so you can focus on your application logic.
Skip Links for Keyboard Navigation
Skip links allow keyboard users to bypass repetitive content like navigation menus and jump directly to the main content. The SkipLink component implements this WCAG 2.0 requirement automatically:
@Override
protected void createBody(Body body)
{
// Skip link appears first, hidden until focused
body.addElement(new SkipLink("main-content", "Skip to main content"));
// Navigation and other content...
body.addElement(navigation);
// Main content with matching ID
Div main = new Div();
main.setId("main-content");
main.setTabIndex(-1); // Allow programmatic focus
body.addElement(main);
}
The SkipLink is visually hidden by default but becomes visible when focused via keyboard navigation. When activated, it moves focus to the target element, allowing screen reader users and keyboard users to skip past navigation quickly.
Live Regions for Dynamic Announcements
When content changes dynamically, screen reader users need to be informed. The LiveRegion component creates an ARIA live region that announces changes to assistive technology:
// Create a polite announcement region (waits for current speech to finish)
LiveRegion statusRegion = LiveRegion.polite();
body.addElement(statusRegion);
// Later, announce a status update
statusRegion.announce("Your changes have been saved successfully.");
// For urgent announcements, use assertive mode
LiveRegion alertRegion = LiveRegion.assertive();
body.addElement(alertRegion);
// This interrupts current speech immediately
alertRegion.announce("Error: Connection lost. Please check your network.");
The component supports two politeness modes:
- Polite (default): Waits for current speech to finish before announcing
- Assertive: Interrupts immediately for urgent notifications
Use polite mode for status updates and assertive mode for critical alerts that require immediate attention.
Visually Hidden Content for Screen Readers
Sometimes you need content that is invisible to sighted users but available to screen readers. The VisuallyHidden component provides this accessibility pattern:
// Add context for screen readers without visual clutter
Button deleteButton = new Button();
deleteButton.addElement(new FontAwesomeIcon("trash"));
deleteButton.addElement(new VisuallyHidden("Delete this item"));
// Provide additional context for icons
Span rating = new Span();
rating.addElement(new FontAwesomeIcon("star"));
rating.addElement(new FontAwesomeIcon("star"));
rating.addElement(new FontAwesomeIcon("star"));
rating.addElement(new VisuallyHidden("3 out of 5 stars"));
Unlike display: none or visibility: hidden, VisuallyHidden uses CSS techniques that keep the content in the accessibility tree while hiding it visually. This ensures screen readers can announce the content.
Focus Trapping for Modal Dialogs
Modal dialogs must trap keyboard focus to prevent users from tabbing outside the dialog. The FocusTrap component handles this complex accessibility requirement:
public class ConfirmDialog extends Div
{
private FocusTrap focusTrap;
public ConfirmDialog()
{
setRole(AriaRole.DIALOG);
setAriaModal(true);
// Wrap dialog content in focus trap
focusTrap = new FocusTrap();
H2 title = new H2("Confirm Action");
focusTrap.addElement(title);
P message = new P("Are you sure you want to proceed?");
focusTrap.addElement(message);
Button cancelBtn = new Button("Cancel");
Button confirmBtn = new Button("Confirm");
focusTrap.addElement(cancelBtn);
focusTrap.addElement(confirmBtn);
addElement(focusTrap);
}
public void show()
{
setDisplay(Display.BLOCK);
focusTrap.activate(); // Trap focus within dialog
}
public void hide()
{
focusTrap.deactivate(); // Release focus trap
setDisplay(Display.NONE);
}
}
When activated, FocusTrap creates invisible sentinel elements at the start and end of the content. When focus reaches these sentinels, it wraps around to the other end, keeping the user within the dialog.
Comprehensive ARIA Role Support
Oorian includes a complete AriaRole enum covering all ARIA landmark, widget, document structure, and live region roles:
// Landmark roles for page structure
nav.setRole(AriaRole.NAVIGATION);
main.setRole(AriaRole.MAIN);
footer.setRole(AriaRole.CONTENTINFO);
aside.setRole(AriaRole.COMPLEMENTARY);
// Widget roles for interactive components
tabList.setRole(AriaRole.TABLIST);
tab.setRole(AriaRole.TAB);
tabPanel.setRole(AriaRole.TABPANEL);
// Document structure roles
list.setRole(AriaRole.LIST);
listItem.setRole(AriaRole.LISTITEM);
heading.setRole(AriaRole.HEADING);
// Live region roles
alert.setRole(AriaRole.ALERT);
status.setRole(AriaRole.STATUS);
log.setRole(AriaRole.LOG);
The AriaRole enum includes over 60 roles organized by category, ensuring you always use valid ARIA values with IDE autocomplete support.
Built-In ARIA Attribute Methods
Every Oorian element includes methods for common ARIA attributes:
// Labels and descriptions
element.setAriaLabel("Close dialog");
element.setAriaLabelledBy("title-id");
element.setAriaDescribedBy("description-id");
// State indicators
button.setAriaPressed(true);
checkbox.setAriaChecked(true);
menu.setAriaExpanded(false);
option.setAriaSelected(true);
// Relationships
tab.setAriaControls("panel-id");
input.setAriaErrorMessage("error-id");
// Live regions (on any element)
element.setAriaLive(AriaLive.POLITE);
element.setAriaAtomic(true);
Keyboard Navigation Support
Use setTabIndex() to control keyboard navigation order:
// Include in tab order (natural order)
button.setTabIndex(0);
// Allow programmatic focus but exclude from tab order
container.setTabIndex(-1);
// Custom tab order (use sparingly)
firstField.setTabIndex(1);
secondField.setTabIndex(2);
Conclusion
Oorian's accessibility components make building WCAG-compliant applications straightforward. From skip links and live regions to focus trapping and comprehensive ARIA support, these tools handle the complex accessibility patterns while you focus on your application's functionality. Accessibility isn't just about compliance—it's about building applications that everyone can use.