Accessible accordion roles (tab and tablist) - html

I'm working on an accessible accordion and I'm not quite sure why the following code does not work properly with VoiceOver:
<ul class="accordion" role="tablist">
<li class="accordion__item">
<h3 class="accordion__head" id="tab1" tabindex="0" role="tab" aria-controls="panel1">Headline</h3>
<div class="accordion__content" id="panel1" role="tabpanel" aria-labelledby="tab1" aria-hidden="true">
Content
</div>
</li>
<li class="accordion__item">
<h3 class="accordion__head" id="tab2" tabindex="0" role="tab" aria-controls="panel2">Headline</h3>
<div class="accordion__content" id="panel2" role="tabpanel" aria-labelledby="tab2" aria-hidden="true">
Content
</div>
</li>
VoiceOver always says something like "tab 1 of 1 Heading 1...", although there clearly are two different role="tab" inside my .accordion. So i tried removing each .accordion__item and ended up with something like that:
<div class="accordion" role="tablist">
<h3 class="accordion__head" id="tab1" tabindex="0" role="tab" aria-controls="panel1">Headline 1</h3>
<div class="accordion__content" id="panel1" role="tabpanel" aria-labelledby="tab1" aria-hidden="true">
Content 1
</div>
<h3 class="accordion__head" id="tab2" tabindex="0" role="tab" aria-controls="panel2">Headline 2</h3>
<div class="accordion__content" id="panel2" role="tabpanel" aria-labelledby="tab2" aria-hidden="true">
Content 2
</div>
</div>
While this works (VoiceOver says "tab 1 of 2 ...") I really need the .accordion__item around my actual content for styling. Although there is only very little difference between the two I'm not sure why only the second code really works with Screen Readers. So I'm asking you if there is any way to have both my surrounding .accordion__item and a correct VoiceOver text?
Thanks in advance.
Also I know that there is more than just that to make an accordion accessible, but that is currently the only issue I really don't know why it doesn't work.

What you need to do is set role="presentation" on all the structures that are not one of the tablist specific roles.

Related

Bootstrap 4 tab-panes. Change two panes with one nav-link

I'm trying to get two different cards to update their active tab-pane using one nav-link.
Here is my code. As you can see, I have one card that has act info and one that has the corresponding video in it. When I click to see the other act info, I want the video to also change (at the moment there is no second video - it just says 'stuff number 2'
<div class="row pt-5" id="acts">
<div class="col-md-4 offset-md-1">
<div class="card">
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item">
<a class="nav-link active" data-toggle="tab" href="#act1" role="tab">Take Five</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#act2" role="tab">Thank You For Your Consideration</a>
</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div class="tab-pane active" id="act1" role="tabpanel">
<div class="card-block">
<h3 class="card-title">Take Five</h3>
<p class="card-text">Do you also have trouble getting out of bed? Working 9 to 5, the same routine every day.. “Take Five” is about one of those days, a light hearted piece full of absurdness and acrobatics. People of all ages can enjoy the 7- minute act, let Ida surprise you!</p>
</div>
</div>
<div class="tab-pane" id="act2" role="tabpanel">
<div class="card-block">
<div class="container">
<div class="row">
<div class="col-md-9">
<h3 class="card-title">Thank You For Your Consideration</h3>
<p class="card-text">What do you write in a letter when you apply for a job? Everybody has been there, behind a computer screen, mind blank. It sounds too pretentious or too insecure. If only they would see the real you. But if that’s a good idea.. An act about struggles that everyone has experienced, brought with humour, brutal honesty and creativity in movement. Ida’s genuine story is a 6 minute text-based circus performance.</p>
</div>
<div class="col-md-3">
<img src="" alt="TYFYC" class="img-fluid img-rounded">
</div>
</div>j
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-5 offset-md-2">
<div class="card">
<div class="tab-content">
<div class="tab-pane active" id="act1" role="tabpanel">
<div class="card-block">
<div class="embed-responsive embed-responsive-16by9">
<iframe class="embed-responsive-item" src="https://player.vimeo.com/video/220114759" allowfullscreen></iframe>
</div>
</div>
</div>
<div class="tab-pane" id="act2" role="tabpanel">
Stuff number 2
</div>
</div>
</div>
</div>
</div>
Is there a way to do this without using a javascript .addClass('active')?

Bootstrap Accordions - How to keep only 1 panel open when using a Dropdown?

Couldn't find anything that addressed this exact issue; it seems simple enough but I haven't been able to get it to work.
Basically, I just want a normal accordion except that instead of a series of buttons to press to expand panels of text, I want the options to be selectable from a single dropdown. I already have that working, but now I can't figure out how to apply the data-parent attribute so only 1 panel is open at a time.
I've been looking at working normal accordion code and trying to apply the same concept to my dropdown, but the different structure means I can't just copy and paste the relevant code and I'm not sure of the fine details of how data-parent is meant to work with accordions.
This is what I have so far:
<div class="container">
<div class="col-md-12">
<div class="col-md-3"></div>
<div class="panel-group col-md-6 text-center" id="accordion">
<div class="col-md-12 text-center">
<div class="dropdown btn-group">
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Choose a Section
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a data-toggle="collapse" data-parent="#accordion" href="#collapse1">Section A</a></li>
<li><a data-toggle="collapse" data-parent="#accordion" href="#collapse2">Section B</a></li>
<li><a data-toggle="collapse" data-parent="#accordion" href="#collapse3">Section C</a></li>
</ul>
</div>
</div>
<div id="collapse1" class="panel-collapse collapse">
<div class="panel-body">
Text A
</div>
</div>
<div id="collapse2" class="panel-collapse collapse">
<div class="panel-body">
Text B
</div>
</div>
<div id="collapse3" class="panel-collapse collapse">
<div class="panel-body">
Text C
</div>
</div>
</div>
<div class="col-md-3"></div>
</div>
</div>
(I hope the divs are nested correctly... I think they are but it's hard to follow at times...)
As you can see, it's all inside of a div with an id of "accordion". The dropdown selections open and close the text sections below it properly, but even though I have their data-parent set to "#accordion", they don't close unless closed manually. I've tried putting data-parent in the text blocks' divs too but that didn't work either. It looks very similar to my normal working accordion but grouped differently, which it obviously has to be when I'm using a dropdown instead of separate buttons.
I assume it's probably a matter of reorganizing the divs a bit, or moving the id or data-parent around but I haven't been able to make any progress. Unless custom Javascript would be required to get this working? It seemed like quite a minor change to use a dropdown instead of a series of buttons, but maybe it's more complicated than it seems...
This is similar to my answer here: https://stackoverflow.com/a/19426220/171456
The accordion behavior depends on the panel class, and the panel must be the direct child of the data-parent element.
Applying these rules to your scenario would look like this...
<div class="panel-group row text-center">
<div class="col-md-12 text-center" id="accordion">
<div class="panel">
<div class="dropdown btn-group">
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Choose a Section
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a data-toggle="collapse" data-parent="#accordion" href="#collapse1">Section A</a></li>
<li><a data-toggle="collapse" data-parent="#accordion" href="#collapse2">Section B</a></li>
<li><a data-toggle="collapse" data-parent="#accordion" href="#collapse3">Section C</a></li>
</ul>
</div>
<div id="collapse1" class="panel-collapse collapse">
<div class="panel-body">
Text A
</div>
</div>
<div id="collapse2" class="panel-collapse collapse">
<div class="panel-body">
Text B
</div>
</div>
<div id="collapse3" class="panel-collapse collapse">
<div class="panel-body">
Text C
</div>
</div>
</div>
</div>
</div>
http://www.codeply.com/go/cPGVLuAh4j
On a separate note, in the Bootstrap grid col-* should always be the immediate child of a row.

Extending LeftAndMain and Add Tabs

I'm taking a long shot at trying to get tabs functional in my LeftAndMain Extension.
I couldn't find any documentation on how one would achieve this so I was just looking at the "Settings" tab setup in the Admin panel.
As I said, long shot :P
This makes them appear beautifully as tabs, however the toggle-between functionality isn't working due to a JS error:
jquery.js:551 Uncaught Error: jQuery UI Tabs: Mismatching fragment identifier.
/mymodule/templates/MyAdmin_Content.ss
<div class="cms-content center $BaseCSSClasses" data-layout-type="border" data-pjax-fragment="Content">
<div class="cms-content-header north">
<div class="cms-content-header-info">
<% include CMSBreadcrumbs %>
</div>
<div class="cms-content-header-tabs cms-tabset-nav-primary ss-ui-tabs-nav ss-tabset">
<ul class="cms-tabset-nav-primary ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"
role="tablist">
<li class="ui-state-default ui-corner-top ui-tabs-active ui-state-active" role="tab" tabindex="0"
aria-controls="Root_Servers" aria-labelledby="ui-id-1" aria-selected="true"><a
href="#Root_Servers" class="ui-tabs-anchor" role="presentation"
tabindex="-1">Main</a></li>
<li class="ui-state-default ui-corner-top" role="tab" tabindex="-1" aria-controls="Root_Settings"
aria-labelledby="ui-id-2" aria-selected="false"><a
href="#Root_Settings" class="ui-tabs-anchor"
role="presentation" tabindex="-1" id="ui-id-2">Access</a></li>
</ul>
</div>
</div>
<div class="cms-content-fields cms-panel-padded center">
<fieldset>
<div id="Root" class="field CompositeField tabset">
<div id="Root_Servers" class="tab ui-tabs-panel ui-widget-content ui-corner-bottom"
aria-labelledby="ui-id-1" role="tabpanel" aria-expanded="true" aria-hidden="false"
style="display: none;">
TAB 1
</div>
<div id="Root_Settings" class="tab ui-tabs-panel ui-widget-content ui-corner-bottom"
aria-labelledby="ui-id-2" role="tabpanel" aria-expanded="false" aria-hidden="true"
style="display: block;">
TAB 2
</div>
</div>
</fieldset>
</div>
<div class="cms-content-actions cms-content-controls south text-center">
Footer
</div>
</div>
I'm aware that majority of the tabs classes are added by jQuery UI however I'm yet to discover how these tabs are instantiated for me to trim off what isn't initially required.
I was hoping to simply access updateCMSFields() but method does not exist on LeftAndMain
Hoping for a pointer, thanks
Old question but I got stuck on this as well.
The tabs and the tabbed content need to be in the same "tabs" container. In the case of Silverstripe that container is .cms-tabset so moving that class up to the .cms-content div at the top accomplishes that. Here's the modified code from the question (trimmed some of the fat to make it more legible):
<!-- Add .cms-tabset class here -->
<div class="cms-content center cms-tabset $BaseCSSClasses" data-layout-type="border" data-pjax-fragment="Content" data-ignore-tab-state="true">
<!-- Start north -->
<div class="cms-content-header north">
<div class="cms-content-header-info">
<% include CMSBreadcrumbs %>
</div>
<div class="cms-content-header-tabs cms-tabset-nav-primary ss-ui-tabs-nav">
<ul class="cms-tabset-nav-primary">
<li class="ui-state-default ui-corner-top ui-tabs-active ui-state-active">
<a href="#Root_Servers" class="ui-tabs-anchor" role="presentation" tabindex="-1">
Testing
</a>
</li>
<li class="ui-state-default ui-corner-top">
<a href="#Root_Settings" class="ui-tabs-anchor" role="presentation" tabindex="-1">
Settings
</a>
</li>
</ul>
</div>
<!-- End north -->
</div>
<!-- Start center -->
<div class="cms-content-fields cms-panel-padded center">
<div id="Root" class="field CompositeField tabset">
<div id="Root_Servers" class="tab ui-tabs-panel ui-widget-content ui-corner-bottom">
TAB 1 Content
</div>
<div id="Root_Settings" class="tab ui-tabs-panel ui-widget-content ui-corner-bottom">
TAB 2 Content
</div>
</div>
<!-- End center -->
</div>

Changing background image bootstrap nav-pills

I've been asked by a friend to create a website.
I've used bootstrap 3 as a framework for the website and have hit a bit of a stumbling block.
My friend wanted a tabbed section where the background image of the section changes depending on which tab is active. I've been able to make it work for just the tab-pane using css, but I need to be able to change the entire section background and not just the tab pane.
I think it will require some JavaScript, but unfortunately my skills in that area a still a bit too weak to know how to do this, and google has been about as helpful as a hole in the head.
below is the section of html that i need the background image to change with each tab
<section id="about" class="content-section text-center">
<div class="row">
<div class="tab-content vertical-center">
<div id="aboutus" class="tab-pane fade in active">
<h2>...</h2>
<p>...</p>
</div>
<div id="history" class="tab-pane fade">
<h2>...</h2>
<p>...</p>
</div>
<div id="chef" class="tab-pane fade">
<h2>...</h2>
<p>...</p>
</div>
</div>
</div>
</section>
<div class="row">
<div class="col-lg-12 nav-pills-bg">
<ul class="nav nav-pills nav-justified">
<li class="active">
<a data-toggle="pill" href="#aboutus">...</a>
</li>
<li>
<a data-toggle="pill" href="#history">...</a>
</li>
<li>
<a data-toggle="pill" href="#chef">...</a>
</li>
</ul>
</div>
</div>
Any help is appreciated
Put your separate css background images on these:
#aboutus {
background-image:.....
}
#history {
background-image:.....
}
#chef {
background-image:.....
}
I checked your code, all works fine and if you want change only contents background, Carol McKay wrote what you have to add in your code. You don't need in this case any javascript code.
I created small example with your code and bootsrap classes: jsfiddle-link
All gaps you can see depends bootstrap classes, for example, by default class .alert has:
.alert {
padding: 15px;
margin-bottom: 20px;
...
}
And one more example with content below pills and looks more familiar): jsfiddle-link2

How to make bootstrap 3 tab nav active by default?

Using bootstrap 3 I am trying this exameple, using class="active" in the li element. Unfortunatelly when the page initially shows up neither tab pane is shown, the whole tab content is empty. The tab navs displayed correctly and when I explicitly click on a tab, the correct pane show up.
What I am missing?
Thanks in advance.
<ul class="nav nav-tabs">
<li class="active">graduation</li>
<li>graduate</li>
<li>extension</li>
</ul>
<div class="tab-content" id="TabContent">
<div class="tab-pane fade" id="graduation">
<p>
anything
</p>
</div>
<div class="tab-pane fade" id="graduate">
<p>
graduate
</p>
</div>
<div class="tab-pane fade" id="extension">
<p>
extension
</p>
</div>
</div>
You also need to specify the active class on the default tab-pane (and for fading tabs you need to add the in class), thus you should change
<div class="tab-pane fade" id="graduation">
to
Bootstrap 3
<div class="tab-pane fade in active" id="graduation">
Bootstrap 4
<div class="tab-pane fade show active" id="graduation">
Bootstrap 4
<div class="tab-pane fade show active" id="graduation">
<div class="tab-pane fade" id="graduation">
Bootstrap 3
<div class="tab-pane fade in active" id="graduation">
<div class="tab-pane fade in" id="graduation">
In case someone was here looking for a solution for react-bootstrap (like I was). There's a defaultActiveKey attribute you can specify on the Tab component. Reference