SkillAgentSearch skills...

Bones

Accessible HTML code patterns for common UI widgets such as tabs, menus, dialogs, etc.

Install / Use

/learn @ianmcburnie/Bones
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

BONES

Widgets are stronger with bones. Does your widget have bones?

Contents

  1. Introduction
  2. Accordion
  3. Alert Dialog
  4. Breadcrumbs
  5. Carousel
  6. Checkbox
  7. Combobox
  8. Confirm Dialog
  9. Details
  10. Fake Menu
  11. Fake Tabs
  12. Icon Button
  13. Infotip
  14. Inline Notice
  15. Input Dialog
  16. Input Validation
  17. Lightbox Dialog
  18. Listbox
  19. Listbox Button
  20. Menu
  21. Menu Button
  22. Page Notice
  23. Pagination
  24. Panel Dialog
  25. Popover
  26. Radio
  27. Select
  28. Switch
  29. Tabs
  30. Toast Dialog
  31. Tooltip
  32. Tourtip

Introduction

Bones provides lean, mean, semantic HTML markup for widgets; ensuring maximum Accessibility, SEO and Site Speed performance. Bones markup uses ARIA only where strictly necessary.

Bones is not intended to be an exhaustive set of instructions for creating accessible components. The primary intention of bones is to detail the structural and semantic markup requirements. For further guidance, please visit eBay MIND Patterns and/or WAI-ARIA Authoring Practices.

Bones advocates the Progressive Enhancement web-design strategy; building the web in a layered fashion that allows everyone to access the most important content and functionality.

Bones favors the the BEM (block, element, modifier) methodology and naming convention.

Accordion

The accordion is simply a list of details widgets. Each details summary should include a relevant heading-level tag.

<ul class="accordion" role="list" aria-roledescription="accordion">
    <li>
        <details class="details">
            <summary><h3>Panel 1</h3></summary>
            <ul>
                <li><a href="http://www.ebay.com">Item 1</a></li>
                <li><a href="http://www.ebay.com">Item 2</a></li>
                <li><a href="http://www.ebay.com">Item 3</a></li>
            </ul>
        </details>
    </li>
    <li>
        <details class="details">
            <summary><h3>Panel 2</h3></summary>
            <ul>
                <li><a href="http://www.ebay.com">Item 1</a></li>
                <li><a href="http://www.ebay.com">Item 2</a></li>
                <li><a href="http://www.ebay.com">Item 3</a></li>
            </ul>
        </details>
    </li>
</ul>

Alert Dialog

A lightbox dialog with a single button to acknowledge the alert content.

Try to bucket the main page content in an element that is not an ancestor of the dialog. This will vastly simplify the amount of DOM manipulation when implementing modal behaviour.

<body>
    <div>
        <!-- main page content -->
    </div>
    <div class="alert-dialog" role="alertdialog" aria-labelledby="alert-dialog-title" aria-modal="true" hidden>
        <div class="alert-dialog__window">
            <div class="alert-dialog__header">
                <h2 class="alert-dialog__title" id="dialog-title">Alert Dialog Title</h2>
            </div>
            <div class="alert-dialog__main">
                <!-- alert dialog content goes here -->
            </div>
            <div class="alert-dialog__footer">
                <button class="alert-dialog__acknowledge" type="button">OK</button>
            </div>
        </div>
    </div>
</body>

Breadcrumbs

The content is an ordered list of links inside a navigation landmark region.

<nav class="breadcrumbs" aria-labelledby="breadcrumbs_heading" role="navigation">
    <h2 class="clipped" id="breadcrumbs_heading">You are here</h2>
    <ol>
        <li>
            <a href="http://www.ebay.com">Great Grandparent Page</a>
            <svg focusable="false" height="10" width="10" aria-hidden="true">
                <use xlink:href="#icon-breadcrumb"></use>
            </svg>
        </li>
        <li>
            <a href="http://www.ebay.com">Grandparent Page</a>
            <svg focusable="false" height="10" width="10" aria-hidden="true">
                <use xlink:href="#icon-breadcrumb"></use>
            </svg>
        </li>
        <li>
            <a href="http://www.ebay.com">Parent Page</a>
            <svg focusable="false" height="10" width="10" aria-hidden="true">
                <use xlink:href="#icon-breadcrumb"></use>
            </svg>
        </li>
        <li>
            <a aria-current="page">Current Page</a>
        </li>
    </ol>
</nav>

While CSS can be used to generate a separator image or glyph using the ::after pseudo element, we find that inline SVG offers a more accessible and flexible approach.

Carousel

A carousel is a list of items. These items may contain anything - text, images, links, tiles, cards, etc. - but each item is responsible for managing its own markup and accessibility (e.g. tab-order, semantics, etc).

<div class="carousel" role="group" aria-labelledby="carousel-title" aria-roledescription="carousel">
    <button aria-label="Previous slide">
        <!-- SVG icon -->
    </button>
    <ul>
        <!-- onscreen items -->
        <li aria-hidden="false">...</li>
        <li aria-hidden="false">...</li>
        <li aria-hidden="false">...</li>
        <li aria-hidden="false">...</li>
        <li aria-hidden="false">...</li>
        <!-- offscreen items -->
        <li aria-hidden="true">...</li>
        <li aria-hidden="true">...</li>
        <li aria-hidden="true">...</li>
        <li aria-hidden="true">...</li>
        <li aria-hidden="true">...</li>
    </ul>
    <button aria-label="Next slide">
        <!-- SVG icon -->
    </button>
</div>

JavaScript must maintain the tabindex and aria-hidden state of items as they scroll in and out of view.

Checkbox

Native HTML checkboxes are 100% accessible by default.

To ensure correct grouping semantics, checkboxes should be placed inside of a fieldset with legend.

<fieldset>
    <legend>Auction Type</legend>
    <span>
        <input id="freeshipping" type="checkbox" name="freeshipping" />
        <label for="freeshipping">Free Shipping</label>
    </span>
    <span>
        <input id="endssoon" type="checkbox" name="endssoon" />
        <label for="endssoon">Ends soon</label>
    </span>
    <span>
        <input id="zerobids" type="checkbox" name="zerobids" />
        <label for="zerobids">Zero bids</label>
    </span>
</fieldset>

For vertically stacked checkboxes, simply switch the spans to divs.

Custom Checkbox Icon

A foreground SVG, combined with CSS, can be used as a facade over the real checkbox.

<span class="checkbox">
    <input class="checkbox__control" id="freeshipping" type="checkbox" name="freeshipping" />
    <span class="checkbox__icon" hidden>
        <svg aria-hidden="true" class="checkbox__unchecked" focusable="false">
            <use xlink:href="#icon-checkbox-unchecked"></use>
        </svg>
        <svg aria-hidden="true" class="checkbox__checked" focusable="false">
            <use xlink:href="#icon-checkbox-checked"></use>
        </svg>
    </span>
</span>

This markup assumes that the symbol definitions for #icon-checkbox-unchecked and #icon-checkbox-checked exist on the page. The hidden property ensures that the SVG icon is not visible alongside the native icon when the page is in a non-CSS state. This hidden property should be over-ridden by CSS.

Combobox

A textbox plus listbox combination.

Collapsed State

<div class="combobox" id="combobox-1">
    <span class="combobox__control">
        <input name="combobox-1-name" type="text" role="combobox" autocomplete="off" aria-expanded="false" aria-owns="combobox-1-listbox" />
    </span>
    <div class="combobox__overlay">
        <ul id="combobox-1-listbox" role="listbox">
            <li role="option" id="combobox-1-option-1">Option 1</li>
            <li role="option" id="combobox-1-option-2">Option 2</li>
            <li role="option" id="combobox-1-option-3">Option 3</li>
            ...
        </ul>
    </div>
</div>

Expanded State

<div class="combobox combobox--expanded" id="combobox-1">
    <span class="combobox__control">
        <input name="combobox-1-name" type="text" role="combobox" autocomplete="off" aria-expanded="true" aria-owns="combobox-1-listbox" />
    </span>
    <div class="combobox__overlay">
        <ul id="combobox-1-listbox" role="listbox">
            <li role="option" id="combobox-1-option-1">Option 1</li>
            <li role="option" id="combobox-1-option-2">Option 2</li>
            <li role="option" id="combobox-1-option-3">Option 3</li>
        

Related Skills

View on GitHub
GitHub Stars94
CategoryDevelopment
Updated1mo ago
Forks31

Security Score

100/100

Audited on Feb 4, 2026

No findings