Bug description
The CP sidebar renders an <li> directly inside another <li> on every authenticated Control Panel page.
Nav.vue wraps each nav item in an <li>, then drops the item's Blade view HTML inside it:
https://github.com/statamic/cms/blob/v6.31.0/resources/js/components/nav/Nav.vue#L206
https://github.com/statamic/cms/blob/v6.31.0/resources/js/components/nav/Nav.vue#L207
Two core nav views open with their own <li>:
https://github.com/statamic/cms/blob/v6.31.0/resources/views/nav/updates.blade.php#L5
https://github.com/statamic/cms/blob/v6.31.0/resources/views/nav/duplicates.blade.php#L5
Rendered result:
main#main > nav.nav-main > div > ul > li > li
An <li> whose parent is an <li> is not part of any list, so the item drops out of the list structure. Screen readers announce the wrong item count for the navigation and may skip the affected entry when navigating by list.
axe-core reports listitem (serious) on 44 of 44 authenticated screens scanned.
WCAG 2.1 SC 1.3.1 Info and Relationships (Level A).
How to reproduce
composer create-project statamic/statamic, create a super user, log in
- On any CP page, run in the console:
[...document.querySelectorAll('li')].filter(li => li.parentElement.tagName === 'LI')
Returns the Updates nav item on every page.
Suggested fix
Remove the wrapping <li> from resources/views/nav/updates.blade.php and resources/views/nav/duplicates.blade.php, since Nav.vue already supplies one.
Two lines. This is the highest-reach single fix in the accessibility audit this came from: it clears a Level A violation on every page in the CP.
Worth documenting the contract for addon nav views too, so third-party ->view() items don't reintroduce it.
Environment
Environment
Laravel Version: 13.30.1
PHP Version: 8.4.23
Composer Version: 2.10.2
Environment: local
Debug Mode: ENABLED
Maintenance Mode: OFF
Timezone: UTC
Locale: en
Cache
Config: NOT CACHED
Events: NOT CACHED
Routes: NOT CACHED
Views: CACHED
Drivers
Broadcasting: log
Cache: file
Database: sqlite
Logs: stack / single
Mail: log
Queue: sync
Session: file
Storage
public/storage: NOT LINKED
Statamic
Addons: 0
License Key: Not set
Sites: 1
Stache Watcher: Enabled (auto)
Static Caching: Disabled
Version: 6.31.0 PRO
Installation
Fresh statamic/statamic site via CLI
Additional details
Found during a WCAG 2.1 AA audit of a vanilla composer create-project statamic/statamic install with no addons and no custom code. Tested with axe-core 4.x on Chromium 153 at 1440x1000, plus manual keyboard traversal. Source references point at v6.31.0.
Bug description
The CP sidebar renders an
<li>directly inside another<li>on every authenticated Control Panel page.Nav.vuewraps each nav item in an<li>, then drops the item's Blade view HTML inside it:https://github.com/statamic/cms/blob/v6.31.0/resources/js/components/nav/Nav.vue#L206
https://github.com/statamic/cms/blob/v6.31.0/resources/js/components/nav/Nav.vue#L207
Two core nav views open with their own
<li>:https://github.com/statamic/cms/blob/v6.31.0/resources/views/nav/updates.blade.php#L5
https://github.com/statamic/cms/blob/v6.31.0/resources/views/nav/duplicates.blade.php#L5
Rendered result:
An
<li>whose parent is an<li>is not part of any list, so the item drops out of the list structure. Screen readers announce the wrong item count for the navigation and may skip the affected entry when navigating by list.axe-core reports
listitem(serious) on 44 of 44 authenticated screens scanned.WCAG 2.1 SC 1.3.1 Info and Relationships (Level A).
How to reproduce
composer create-project statamic/statamic, create a super user, log inReturns the Updates nav item on every page.
Suggested fix
Remove the wrapping
<li>fromresources/views/nav/updates.blade.phpandresources/views/nav/duplicates.blade.php, sinceNav.vuealready supplies one.Two lines. This is the highest-reach single fix in the accessibility audit this came from: it clears a Level A violation on every page in the CP.
Worth documenting the contract for addon nav views too, so third-party
->view()items don't reintroduce it.Environment
Installation
Fresh statamic/statamic site via CLI
Additional details
Found during a WCAG 2.1 AA audit of a vanilla
composer create-project statamic/statamicinstall with no addons and no custom code. Tested with axe-core 4.x on Chromium 153 at 1440x1000, plus manual keyboard traversal. Source references point atv6.31.0.