Passer au contenu

DDEHTML

Rethinking the Interactive Web

This document is a draft and does not constitute a final specification in any way.
   
       

DARIA Extension Documentation: Declarative Accessible Rich Internet Applications

   
   

This documentation presents the initial specification of the DARIA language, a behavior sheet language designed to separate basic Web interactivity from JavaScript, thus making documents more robust and accessible by default.

   
   
       

Fundamental Principles of DARIA

       
               
  • Declarative: Behavior is defined by rules and selectors, similar to CSS, describing how elements should interact.
  •            
  • Accessibility by Default: The goal is to natively solve the ARIA Authoring Practices Guide patterns without relying on JavaScript.
  •            
  • Separation of Concerns: DARIA is strictly limited to DOM manipulation (Attributes, Classes, ARIA). It does not handle style (domain of CSS) or complex application logic (domain of JavaScript).
  •        
   
   
   
       

Structure of a DARIA Behavior Sheet

       

A behavior sheet is composed of rules. Each rule begins with a selector (identical to CSS selectors) defining the targeted elements, followed by a block of declarations between curly braces.

       

There are mainly two types of rules: relations, prefixed by rel- and events, prefixed by on- or by kb- in the case of defining keyboard interactions.

       

The naming of relations can be arbitrary. It is recommended to choose a clear name (example: rel-controlled or rel-group).

       
selector {
    rel-my-relationX: "my-selector"; /* Definition of relations */
    rel-my-relationY: "my-other-selector";
    on-eventName: micro-action1(my-relationX, param) micro-action2(my-relationY, param); /* Definition of behaviors */
    kb-key1-key2: micro-action(my-relationY); /* Keyboard interactions */
    /* ... */
}

Some special properties are under consideration. For example, the order property accepting an integer parameter. Unlike its CSS counterpart, this will involve actually moving the DOM elements based on the display context (media queries, breakpoints)

   
   
   
       

Declarative Relations

       

Relations are the key to DARIA; they allow linking the selected element to other target elements to apply actions. They are defined by the prefix rel-, followed by a name chosen by the integrator (e.g., rel-controlled, rel-button).

       

Relation Syntax

       

The value of a relation must be a string describing a selector, potentially prefixed by an initial point of view in parentheses.

       

By default, the initial point of view is the element captured by the selector. However, one may sometimes wish to establish a relation starting from one of its ancestors, or its direct ancestor.

                
rel-name: "selector-or-function";
        Or:        
rel-name: "(initial-pov) selector-or-function";
                

Predefined Initial Points of View (POV)

       

These keywords define the element from which the relation selector will be applied.

                                                                                                                                                                                                                                                               
POVDescription
rootDocument root (<html>).
selfThe element selected by the DARIA rule.
parentThe direct parent element.
nextThe next sibling.
prevThe previous sibling.
branchAll children of the parent element.
firstThe first child of the parent element.
lastThe last child of the parent element.
siblingsAll siblings of the selected element (excluding the element itself).
siblings: selectorSiblings matching the specified selector (excluding the element itself).
closest: selectorThe closest ancestor (or the element itself) matching the selector.
                

Finally, the relation string can be calculated from one or more of its attributes in the same way as with CSS, using the attr() function.

                

Relation Examples:

        
#parent {
	rel-relation: "#selector";
}

This relation is very simple. Note: its point of view is (by default) the "#parent" element. This means that #selector is assumed to be a descendant of #parent.

        
rel-controlled: "#" attr(aria-controls);

This relation is arbitrarily named "controlled". Its value is not immediately a string (presence of the attr() function) and must therefore be calculated. It will be defined by the content of the aria-controls attribute prefixed with "#".

rel-button: "(closest: #navigation) button[aria-controls=menu-principal]";

This last relation is a little more complex than the other two. Indeed, it does not start directly from the element captured by the selector, because it is prefixed by an initial point of view in parentheses which announces the first ancestor corresponding to "#navigation" as the starting point of the selection. Finally, the descendant(s) of "#navigation" that satisfy "button[aria-controls=menu-principal]" will be the element(s) ultimately targeted by the relation named "button".

Once the relations are defined, we will be able to apply behaviors to the elements targeted by these relations. This is the role of events and their micro-actions.

   
   
   
       

Micro-Actions and Events

       

The behavior of elements is defined via event properties (e.g., on-click) which contain a sequence of micro-actions executed synchronously.

       

Micro-Action Targeting

       

The target of a micro-action is the name of a relation or self, followed by the prefix @ for an attribute or a dot . for a class.

                                                                                                                               
TargetingDescriptionExample
relation@attributeTargets an attribute on the elements linked by the relation.set(controlled@hidden)
relation.classTargets a class on the elements linked by the relation.rm(controlled.mobile)
self@attributeTargets an attribute on the selected element.toggle(self@aria-expanded)
       

Events

                                                                                                                                               
EventDescription
initExecuted once during the initial DOM parsing by the browser, or when the element (satisfying the selector) is inserted into the DOM.
on-eventRefers to any user event (click, hover, etc.), except key presses.
on-click-outSynthetic event fired on a click outside the selected element and all elements linked by relations.
kb-key(s)Refers to the press of a key or a combination of keys (e.g., kb-escape, kb-shift-tab).
       

List of Micro-Actions

       

These micro-actions form the basic vocabulary of DARIA.

       

They are the delicate boundary between a declarative language and a programming language. Their evolution must be strictly governed by a clear specification:

         

They will always be limited to a few basic DOM actions,         whose implementation outside of JavaScript will allow for optimal and secure execution.         They must never allow the execution of complex operations (loops, large calculations, or sending data outwards).

                                                                                                                                                                                                                                                                                                               
Micro-ActionSyntaxDescription
setset(target@boolean-attr)

set(target@attr, "value")

set(target.class)
Sets the value of an attribute or adds a class.
rmrm(target@attr)

rm(target.class)
Removes an attribute or a class.
toggletoggle(target@attr)

toggle(target@attr, "v1", "v2", "v3")

toggle(target.class)
Inverts the state of an attribute/class or cycles through a list of values for an attribute.
waitwait(ms)Pauses the execution of subsequent micro-actions for a number of milliseconds.
cancelcancel()Prevents the default behavior of the event (equivalent to event.preventDefault()).
triggertrigger(target, "event-name")Fires a custom DOM event (which can be listened to by JavaScript).
openopen(target)Opens an element (e.g., for <dialog>, JS equivalent: show()).
open-modalopen-modal(target)Opens an element in modal mode (e.g., for <dialog>, JS equivalent: showModal()).
closeclose(target)Closes an element (e.g., for <dialog>, JS equivalent: close()).
start-loopstart-loop(target, "name")Starts a loop defined by the integrator (used for carousels, etc.).
stop-loopstop-loop(target, "name")Stops an ongoing loop.
prependprepend(parent-target, child-target)Inserts an element as the first child.
appendappend(parent-target, child-target)Inserts an element as the last child.
scroll-toscroll-to(viewport, target)Scrolls an element (viewport) until the target is visible.
   
   
   
       

Media Queries and Supports

       

DARIA rules can be conditioned by media queries or the native support for certain features.

       

Standard Media Queries

       

Standard media queries (such as @media (max-width: 1200px) or @media (prefers-reduced-motion: reduce)) are fully supported, allowing declarative behavior to adapt to user or device conditions.

       

@supports Rules

       

The @supports rule allows defining a declarative polyfill behavior if a native HTML feature is missing.

       

This feature will allow the browser to benefit from polyfills for possible recent HTML elements (e.g., invokers) even if JavaScript is disabled.

       
@supports not (details) {
    /* DARIA rules to apply if the <details> tag is not supported */
}
       
@supports not (button[commandfor]) {
    /* DARIA rules to apply if the <commandfor> attribute is not supported on buttons */
}
   
   
   
       

Example: Responsive Navigation Menu

       

Here is an example implementation of a navigation menu (with a button for mobile) that uses the ARIA attribute aria-expanded to indicate its state.

       

Default Behavior (Opening)

       
button[aria-expanded][aria-controls] {
    rel-controlled: "#" attr(aria-controls); /* Links the button to the controlled menu */
    init: set(self@hidden) rm(controlled@hidden) rm(controlled.mobile); /* Hides the button by default if the menu is visible (desktop state) */
}
       

Mobile Behavior (Reduced Screen)

       
@media (max-width: 1200px) {

    button[aria-expanded][aria-controls] {
        /* Initialization in mobile mode: the menu is hidden and the button is shown */
        init: set(controlled@hidden) set(controlled.mobile) set(self@aria-expanded, "false") rm(self@hidden);
        
        /* Click on the button: toggles the ARIA state and the hidden attribute of the menu */
        on-click: toggle(self@aria-expanded, "true", "false") toggle(controlled@hidden);
        
        /* Click outside the button/menu: closes the menu */
        on-click-out: set(self@aria-expanded, "false") set(controlled@hidden);
        
        /* Escape key (focus on the button): closes the menu */
        kb-escape: set(self@aria-expanded, "false") set(controlled@hidden); 
    }

    #menu-principal a {
        rel-controlled: "(closest: #menu-principal)"; /* The anchor controls its parent menu */
        rel-button: "(closest: #navigation) button[aria-controls=menu-principal]"; /* The anchor has a relation to the menu button */
        
        /* Escape key (focus on an anchor in the menu): closes the menu */
        kb-escape: set(button@aria-expanded, "false") set(controlled@hidden);
    }
}
   
   
    

Roadmap

  1. Propose a specification draft as a starting point and subject for discussion (Drafting of this document is underway)
  2. Develop a JS polyfill of this specification to allow this language to exist independently of its adoption. This implementation will serve as an experimental basis. It is currently under development.
    It will come in a dual form:
    • A JS polyfill to embed DARIA support into HTML pages.
    • A WebExtension allowing the user to disable JavaScript execution from visited pages ("Secured mode") while maintaining the experience offered by this implementation
    Although this first implementation is in JS, let's keep in mind that its goal is to establish and offer a language whose objective is to be totally independent of JavaScript. 
  3. During the development of the DARIA language, new HTML tags based on the ARIA APG will undoubtedly be proposed. Furthermore, this language will also be used for the elaboration (outside of JavaScript) of polyfills for modern HTML elements (e.g., invokers). This is an argument in favor of secure navigation and the principle of progressive enhancement.
  4. After numerous discussions and sufficient coverage of the ARIA Authoring Practices Guide patterns, it will be time to encourage web developers as well as popular browser implementers to adopt DARIA.
        
   
    

Conclusion

Currently, the DARIA language is at an experimental stage.

Its definitive elaboration and standardization will have to rely on the approval of an open community: the DDEHTML working group of the W3C.

Its adoption will depend on its popularity among developers, and the goodwill of the implementers of each browser.

However, a JS implementation currently under development will by default allow this initiative to exist independently of its adoption.

If you wish to support this initiative, or simply wish to receive information on the evolution of this project, you can join this community.

A mailing list will soon be created, write to us to subscribe.