mirror of
https://github.com/twbs/bootstrap.git
synced 2025-08-10 23:54:08 +02:00
Accessibility fixes to dynamic tabs (aria-selected
, remove dynamic tabs with dropdowns)
* Use `aria-selected` instead of `aria-expanded` * Change tab.js to use `aria-selected` rather than `aria-expanded` * Add `aria-orientation=vertical` to vertical tab list * Remove dynamic tabs with dropdowns * Fix non-interactive code examples * Only set `aria-selected` on the `role="tab"` trigger - this stops `aria-selected` being incorrectly added to the `role="tabpanel"` itself (probably harmless, but nonetheless incorrect)
This commit is contained in:
@@ -196,11 +196,15 @@ const Tab = (() => {
|
||||
$(dropdownChild).removeClass(ClassName.ACTIVE)
|
||||
}
|
||||
|
||||
active.setAttribute('aria-expanded', false)
|
||||
if (active.getAttribute('role') === 'tab') {
|
||||
active.setAttribute('aria-selected', false)
|
||||
}
|
||||
}
|
||||
|
||||
$(element).addClass(ClassName.ACTIVE)
|
||||
element.setAttribute('aria-expanded', true)
|
||||
if (element.getAttribute('role') === 'tab') {
|
||||
element.setAttribute('aria-selected', true)
|
||||
}
|
||||
|
||||
if (isTransitioning) {
|
||||
Util.reflow(element)
|
||||
|
@@ -287,29 +287,29 @@ $(function () {
|
||||
.bootstrapTab('show')
|
||||
})
|
||||
|
||||
QUnit.test('selected tab should have aria-expanded', function (assert) {
|
||||
QUnit.test('selected tab should have aria-selected', function (assert) {
|
||||
assert.expect(8)
|
||||
var tabsHTML = '<ul class="nav nav-tabs">'
|
||||
+ '<li><a class="nav-item active" href="#home" toggle="tab" aria-expanded="true">Home</a></li>'
|
||||
+ '<li><a class="nav-item" href="#profile" toggle="tab" aria-expanded="false">Profile</a></li>'
|
||||
+ '<li><a class="nav-item active" href="#home" toggle="tab" aria-selected="true">Home</a></li>'
|
||||
+ '<li><a class="nav-item" href="#profile" toggle="tab" aria-selected="false">Profile</a></li>'
|
||||
+ '</ul>'
|
||||
var $tabs = $(tabsHTML).appendTo('#qunit-fixture')
|
||||
|
||||
$tabs.find('li:first a').bootstrapTab('show')
|
||||
assert.strictEqual($tabs.find('.active').attr('aria-expanded'), 'true', 'shown tab has aria-expanded = true')
|
||||
assert.strictEqual($tabs.find('a:not(.active)').attr('aria-expanded'), 'false', 'hidden tab has aria-expanded = false')
|
||||
assert.strictEqual($tabs.find('.active').attr('aria-selected'), 'true', 'shown tab has aria-selected = true')
|
||||
assert.strictEqual($tabs.find('a:not(.active)').attr('aria-selected'), 'false', 'hidden tab has aria-selected = false')
|
||||
|
||||
$tabs.find('li:last a').trigger('click')
|
||||
assert.strictEqual($tabs.find('.active').attr('aria-expanded'), 'true', 'after click, shown tab has aria-expanded = true')
|
||||
assert.strictEqual($tabs.find('a:not(.active)').attr('aria-expanded'), 'false', 'after click, hidden tab has aria-expanded = false')
|
||||
assert.strictEqual($tabs.find('.active').attr('aria-selected'), 'true', 'after click, shown tab has aria-selected = true')
|
||||
assert.strictEqual($tabs.find('a:not(.active)').attr('aria-selected'), 'false', 'after click, hidden tab has aria-selected = false')
|
||||
|
||||
$tabs.find('li:first a').bootstrapTab('show')
|
||||
assert.strictEqual($tabs.find('.active').attr('aria-expanded'), 'true', 'shown tab has aria-expanded = true')
|
||||
assert.strictEqual($tabs.find('a:not(.active)').attr('aria-expanded'), 'false', 'hidden tab has aria-expanded = false')
|
||||
assert.strictEqual($tabs.find('.active').attr('aria-selected'), 'true', 'shown tab has aria-selected = true')
|
||||
assert.strictEqual($tabs.find('a:not(.active)').attr('aria-selected'), 'false', 'hidden tab has aria-selected = false')
|
||||
|
||||
$tabs.find('li:first a').trigger('click')
|
||||
assert.strictEqual($tabs.find('.active').attr('aria-expanded'), 'true', 'after second show event, shown tab still has aria-expanded = true')
|
||||
assert.strictEqual($tabs.find('a:not(.active)').attr('aria-expanded'), 'false', 'after second show event, hidden tab has aria-expanded = false')
|
||||
assert.strictEqual($tabs.find('.active').attr('aria-selected'), 'true', 'after second show event, shown tab still has aria-selected = true')
|
||||
assert.strictEqual($tabs.find('a:not(.active)').attr('aria-selected'), 'false', 'after second show event, hidden tab has aria-selected = false')
|
||||
})
|
||||
|
||||
QUnit.test('selected tab should deactivate previous selected tab', function (assert) {
|
||||
@@ -351,13 +351,13 @@ $(function () {
|
||||
var tabsHTML =
|
||||
'<nav class="nav nav-tabs" role="tablist">'
|
||||
+ ' <a id="tab1" href="#x-tab1" class="nav-item nav-link" data-toggle="tab" role="tab" aria-controls="x-tab1">Tab 1</a>'
|
||||
+ ' <a href="#x-tab2" class="nav-item nav-link active" data-toggle="tab" role="tab" aria-controls="x-tab2" aria-expanded="true">Tab 2</a>'
|
||||
+ ' <a href="#x-tab2" class="nav-item nav-link active" data-toggle="tab" role="tab" aria-controls="x-tab2" aria-selected="true">Tab 2</a>'
|
||||
+ ' <a href="#x-tab3" class="nav-item nav-link" data-toggle="tab" role="tab" aria-controls="x-tab3">Tab 3</a>'
|
||||
+ '</nav>'
|
||||
+ '<div class="tab-content">'
|
||||
+ ' <div class="tab-pane" id="x-tab1" role="tabpanel">'
|
||||
+ ' <nav class="nav nav-tabs" role="tablist">'
|
||||
+ ' <a href="#nested-tab1" class="nav-item nav-link active" data-toggle="tab" role="tab" aria-controls="x-tab1" aria-expanded="true">Nested Tab 1</a>'
|
||||
+ ' <a href="#nested-tab1" class="nav-item nav-link active" data-toggle="tab" role="tab" aria-controls="x-tab1" aria-selected="true">Nested Tab 1</a>'
|
||||
+ ' <a id="tabNested2" href="#nested-tab2" class="nav-item nav-link" data-toggle="tab" role="tab" aria-controls="x-profile">Nested Tab2</a>'
|
||||
+ ' </nav>'
|
||||
+ ' <div class="tab-content">'
|
||||
|
Reference in New Issue
Block a user