Skip to content

Instantly share code, notes, and snippets.

@ionutale
Created March 2, 2023 13:16
Show Gist options
  • Save ionutale/d0f65bd5f4b07065d747bb6b61d0b565 to your computer and use it in GitHub Desktop.
Save ionutale/d0f65bd5f4b07065d747bb6b61d0b565 to your computer and use it in GitHub Desktop.
accessible carousel
<section id="myCarousel" class="carousel-tablist" aria-roledescription="carousel" aria-label="Highlighted television shows">
<div class="carousel-inner">
<div class="controls">
<button class="rotation" type="button">
<svg width="42" height="34" version="1.1" xmlns="http://www.w3.org/2000/svg" class="svg-play">
<rect class="background" x="2" y="2" rx="5" ry="5" width="38" height="24"></rect>
<rect class="border" x="4" y="4" rx="5" ry="5" width="34" height="20"></rect>
<polygon class="pause" points="17 8 17 20"></polygon>
<polygon class="pause" points="24 8 24 20"></polygon>
<polygon class="play" points="15 8 15 20 27 14"></polygon>
</svg>
</button>
<div class="tab-wrapper">
<div role="tablist" aria-label="Slides">
<button id="carousel-tab-1" type="button" role="tab" aria-label="Slide 1" aria-selected="true" aria-controls="carousel-item-1">
<svg width="34" height="34" version="1.1" xmlns="http://www.w3.org/2000/svg">
<circle class="border" cx="16" cy="15" r="10"></circle>
<circle class="tab-background" cx="16" cy="15" r="8"></circle>
<circle class="tab" cx="16" cy="15" r="6"></circle>
</svg>
</button>
<button id="carousel-tab-2" type="button" role="tab" tabindex="-1" aria-label="Slide 2" aria-selected="false" aria-controls="carousel-item-2">
<svg width="34" height="34" version="1.1" xmlns="http://www.w3.org/2000/svg">
<circle class="border" cx="16" cy="15" r="10"></circle>
<circle class="tab-background" cx="16" cy="15" r="8"></circle>
<circle class="tab" cx="16" cy="15" r="6"></circle>
</svg>
</button>
<button id="carousel-tab-3" type="button" role="tab" tabindex="-1" aria-label="Slide 3" aria-selected="false" aria-controls="carousel-item-3">
<svg width="34" height="34" version="1.1" xmlns="http://www.w3.org/2000/svg">
<circle class="border" cx="16" cy="15" r="10"></circle>
<circle class="tab-background" cx="16" cy="15" r="8"></circle>
<circle class="tab" cx="16" cy="15" r="6"></circle>
</svg>
</button>
<button id="carousel-tab-4" type="button" role="tab" tabindex="-1" aria-label="Slide 4" aria-selected="false" aria-controls="carousel-item-4">
<svg width="34" height="34" version="1.1" xmlns="http://www.w3.org/2000/svg">
<circle class="border" cx="16" cy="15" r="10"></circle>
<circle class="tab-background" cx="16" cy="15" r="8"></circle>
<circle class="tab" cx="16" cy="15" r="6"></circle>
</svg>
</button>
<button id="carousel-tab-5" type="button" role="tab" tabindex="-1" aria-label="Slide 5" aria-selected="false" aria-controls="carousel-item-5">
<svg width="34" height="34" version="1.1" xmlns="http://www.w3.org/2000/svg">
<circle class="border" cx="16" cy="15" r="10"></circle>
<circle class="tab-background" cx="16" cy="15" r="8"></circle>
<circle class="tab" cx="16" cy="15" r="6"></circle>
</svg>
</button>
<button id="carousel-tab-6" type="button" role="tab" tabindex="-1" aria-label="Slide 6" aria-selected="false" aria-controls="carousel-item-6">
<svg width="34" height="34" version="1.1" xmlns="http://www.w3.org/2000/svg">
<circle class="border" cx="16" cy="15" r="10"></circle>
<circle class="tab-background" cx="16" cy="15" r="8"></circle>
<circle class="tab" cx="16" cy="15" r="6"></circle>
</svg>
</button>
</div>
</div>
</div>
<div id="myCarousel-items" class="carousel-items playing" aria-live="off">
<div class="carousel-item active" id="carousel-item-1" role="tabpanel" aria-roledescription="slide" aria-label="1 of 6">
<div class="carousel-image">
<a href="#" id="carousel-image-1">
<img src="../../../../../../content-images/wai-aria-practices/patterns/carousel/examples/images/amsterdamslide__800x600.jpg" alt="Walking Tour in Amsterdam">
</a>
</div>
<div class="carousel-caption">
<h3>
<a href="#"> Dynamic Europe: Amsterdam, Prague, Berlin </a>
</h3>
<div class="hidden-xs hidden-sm">
<p><span class="contrast">7 pm Tuesday, March 3, on TV</span></p>
</div>
</div>
</div>
<div class="carousel-item" id="carousel-item-2" role="tabpanel" aria-roledescription="slide" aria-label="2 of 6">
<div class="carousel-image">
<a href="#" id="carousel-image-2">
<img src="../../../../../../content-images/wai-aria-practices/patterns/carousel/examples/images/lands-endslide__800x600.jpg" alt="Land's End in Cornwall">
</a>
</div>
<div class="carousel-caption">
<h3>
<a href="#"> Travel to Southwest England and Paris </a>
</h3>
<div>
<p><span class="contrast">Sept. 14 to Sept. 24 or 27</span></p>
</div>
</div>
</div>
<div class="carousel-item" id="carousel-item-3" role="tabpanel" aria-roledescription="slide" aria-label="3 of 6">
<div class="carousel-image">
<a href="#!" id="carousel-image-3">
<img src="../../../../../../content-images/wai-aria-practices/patterns/carousel/examples/images/trustslide-2__800x600.jpg" alt="Mom and daughter play Daniel Tiger game on notebook computer.">
</a>
</div>
<div class="carousel-caption">
<h3>
<a href="#"> Great Children's Programming on Public TV </a>
</h3>
<div></div>
</div>
</div>
<div class="carousel-item" id="carousel-item-4" role="tabpanel" aria-roledescription="slide" aria-label="4 of 6">
<div class="carousel-image">
<a href="#" id="carousel-image-4">
<img src="../../../../../../content-images/wai-aria-practices/patterns/carousel/examples/images/foyleswarslide__800x600.jpg" alt="A man in a suit and fedora and a woman with coiffed hair look sternly into the camera.">
</a>
</div>
<div class="carousel-caption">
<h3>
<a href="#"> Foyle’s War Revisited </a>
</h3>
<div>
<p><span class="contrast">8 pm Sunday, March 8, on TV: Sneak peek at the final season.</span></p>
</div>
</div>
</div>
<div class="carousel-item" id="carousel-item-5" role="tabpanel" aria-roledescription="slide" aria-label="5 of 6">
<div class="carousel-image">
<a href="#" id="carousel-image-5">
<img src="../../../../../../content-images/wai-aria-practices/patterns/carousel/examples/images/britcomdavidslide__800x600.jpg" alt="British flag with WILL-TV host David Thiel.">
</a>
</div>
<div class="carousel-caption">
<h3>
<a href="#"> Great Britain Vote: 7 pm Sat. </a>
</h3>
<div></div>
</div>
</div>
<div class="carousel-item" id="carousel-item-6" role="tabpanel" aria-roledescription="slide" aria-label="6 of 6">
<div class="carousel-image">
<a href="#" id="carousel-image-6">
<img src="../../../../../../content-images/wai-aria-practices/patterns/carousel/examples/images/mag800-2__800x600.jpg" alt="Mid-American Gardener panelists on the set">
</a>
</div>
<div class="carousel-caption">
<h3>
<a href="#"> Mid-American Gardener: Thursdays at 7 pm </a>
</h3>
<div class="hidden-xs hidden-sm">
<p><span class="contrast">Watch the latest episodes.</span></p>
</div>
</div>
</div>
</div>
</div>
</section>
<div class="col-sm-1"></div>
/*
* File: carousel-tablist.js
*
* Desc: Carousel Tablist widget that implements ARIA Authoring Practices
*
*/
'use strict';
// takes options object: { accessibleCaptions: boolean, autoplay: boolean, playButton: boolean }
// defaults are: { accessibleCaptions: true, autoplay: false, playButton: true }
var CarouselTablist = function (node, options) {
// merge passed options with defaults
options = Object.assign(
{ moreaccessible: false, paused: false, norotate: false },
options || {}
);
// a prefers-reduced-motion user setting must always override autoplay
var hasReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)');
if (hasReducedMotion.matches) {
options.paused = true;
}
/* DOM properties */
this.domNode = node;
this.tablistNode = node.querySelector('[role=tablist]');
this.containerNode = node.querySelector('.carousel-items');
this.tabNodes = [];
this.tabpanelNodes = [];
this.liveRegionNode = node.querySelector('.carousel-items');
this.pausePlayButtonNode = document.querySelector(
'.carousel-tablist .controls button.rotation'
);
this.playLabel = 'Start automatic slide show';
this.pauseLabel = 'Stop automatic slide show';
/* State properties */
this.hasUserActivatedPlay = false; // set when the user activates the play/pause button
this.isAutoRotationDisabled = options.norotate; // This property for disabling auto rotation
this.isPlayingEnabled = !options.paused; // This property is also set in updatePlaying method
this.timeInterval = 5000; // length of slide rotation in ms
this.currentIndex = 0; // index of current slide
this.slideTimeout = null; // save reference to setTimeout
// initialize tabs
this.tablistNode.addEventListener('focusin', this.handleTabFocus.bind(this));
this.tablistNode.addEventListener('focusout', this.handleTabBlur.bind(this));
var nodes = node.querySelectorAll('[role="tab"]');
for (var i = 0; i < nodes.length; i++) {
var n = nodes[i];
this.tabNodes.push(n);
n.addEventListener('keydown', this.handleTabKeydown.bind(this));
n.addEventListener('click', this.handleTabClick.bind(this));
// initialize tabpanels
var tabpanelNode = document.getElementById(n.getAttribute('aria-controls'));
if (tabpanelNode) {
this.tabpanelNodes.push(tabpanelNode);
// support stopping rotation when any element receives focus in the tabpanel
tabpanelNode.addEventListener(
'focusin',
this.handleTabpanelFocusIn.bind(this)
);
tabpanelNode.addEventListener(
'focusout',
this.handleTabpanelFocusOut.bind(this)
);
var imageLink = tabpanelNode.querySelector('.carousel-image a');
if (imageLink) {
imageLink.addEventListener(
'focus',
this.handleImageLinkFocus.bind(this)
);
imageLink.addEventListener('blur', this.handleImageLinkBlur.bind(this));
}
} else {
this.tabpanelNodes.push(null);
}
}
// Pause Button
if (this.pausePlayButtonNode) {
this.pausePlayButtonNode.addEventListener(
'click',
this.handlePausePlayButtonClick.bind(this)
);
}
// Handle hover events
this.domNode.addEventListener('mouseover', this.handleMouseOver.bind(this));
this.domNode.addEventListener('mouseout', this.handleMouseOut.bind(this));
// initialize behavior based on options
this.enableOrDisableAutoRotation(options.norotate);
this.updatePlaying(!options.paused && !options.norotate);
this.setAccessibleStyling(options.moreaccessible);
this.rotateSlides();
};
/* Public function to disable/enable rotation and if false, hide pause/play button*/
CarouselTablist.prototype.enableOrDisableAutoRotation = function (disable) {
this.isAutoRotationDisabled = disable;
this.pausePlayButtonNode.hidden = disable;
};
/* Public function to update controls/caption styling */
CarouselTablist.prototype.setAccessibleStyling = function (accessible) {
if (accessible) {
this.domNode.classList.add('carousel-tablist-moreaccessible');
} else {
this.domNode.classList.remove('carousel-tablist-moreaccessible');
}
};
CarouselTablist.prototype.hideTabpanel = function (index) {
var tabNode = this.tabNodes[index];
var panelNode = this.tabpanelNodes[index];
tabNode.setAttribute('aria-selected', 'false');
tabNode.setAttribute('tabindex', '-1');
if (panelNode) {
panelNode.classList.remove('active');
}
};
CarouselTablist.prototype.showTabpanel = function (index, moveFocus) {
var tabNode = this.tabNodes[index];
var panelNode = this.tabpanelNodes[index];
tabNode.setAttribute('aria-selected', 'true');
tabNode.removeAttribute('tabindex');
if (panelNode) {
panelNode.classList.add('active');
}
if (moveFocus) {
tabNode.focus();
}
};
CarouselTablist.prototype.setSelectedTab = function (index, moveFocus) {
if (index === this.currentIndex) {
return;
}
this.currentIndex = index;
for (var i = 0; i < this.tabNodes.length; i++) {
this.hideTabpanel(i);
}
this.showTabpanel(index, moveFocus);
};
CarouselTablist.prototype.setSelectedToPreviousTab = function (moveFocus) {
var nextIndex = this.currentIndex - 1;
if (nextIndex < 0) {
nextIndex = this.tabNodes.length - 1;
}
this.setSelectedTab(nextIndex, moveFocus);
};
CarouselTablist.prototype.setSelectedToNextTab = function (moveFocus) {
var nextIndex = this.currentIndex + 1;
if (nextIndex >= this.tabNodes.length) {
nextIndex = 0;
}
this.setSelectedTab(nextIndex, moveFocus);
};
CarouselTablist.prototype.rotateSlides = function () {
if (!this.isAutoRotationDisabled) {
if (
(!this.hasFocus && !this.hasHover && this.isPlayingEnabled) ||
this.hasUserActivatedPlay
) {
this.setSelectedToNextTab(false);
}
}
this.slideTimeout = setTimeout(
this.rotateSlides.bind(this),
this.timeInterval
);
};
CarouselTablist.prototype.updatePlaying = function (play) {
this.isPlayingEnabled = play;
if (play) {
this.pausePlayButtonNode.setAttribute('aria-label', this.pauseLabel);
this.pausePlayButtonNode.classList.remove('play');
this.pausePlayButtonNode.classList.add('pause');
this.liveRegionNode.setAttribute('aria-live', 'off');
} else {
this.pausePlayButtonNode.setAttribute('aria-label', this.playLabel);
this.pausePlayButtonNode.classList.remove('pause');
this.pausePlayButtonNode.classList.add('play');
this.liveRegionNode.setAttribute('aria-live', 'polite');
}
};
/* Event Handlers */
CarouselTablist.prototype.handleImageLinkFocus = function () {
this.liveRegionNode.classList.add('focus');
};
CarouselTablist.prototype.handleImageLinkBlur = function () {
this.liveRegionNode.classList.remove('focus');
};
CarouselTablist.prototype.handleMouseOver = function (event) {
if (!this.pausePlayButtonNode.contains(event.target)) {
this.hasHover = true;
}
};
CarouselTablist.prototype.handleMouseOut = function () {
this.hasHover = false;
};
/* EVENT HANDLERS */
CarouselTablist.prototype.handlePausePlayButtonClick = function () {
this.hasUserActivatedPlay = !this.isPlayingEnabled;
this.updatePlaying(!this.isPlayingEnabled);
};
/* Event Handlers for Tabs*/
CarouselTablist.prototype.handleTabKeydown = function (event) {
var flag = false;
switch (event.key) {
case 'ArrowRight':
this.setSelectedToNextTab(true);
flag = true;
break;
case 'ArrowLeft':
this.setSelectedToPreviousTab(true);
flag = true;
break;
case 'Home':
this.setSelectedTab(0, true);
flag = true;
break;
case 'End':
this.setSelectedTab(this.tabNodes.length - 1, true);
flag = true;
break;
default:
break;
}
if (flag) {
event.stopPropagation();
event.preventDefault();
}
};
CarouselTablist.prototype.handleTabClick = function (event) {
var index = this.tabNodes.indexOf(event.currentTarget);
this.setSelectedTab(index, true);
};
CarouselTablist.prototype.handleTabFocus = function () {
this.tablistNode.classList.add('focus');
this.liveRegionNode.setAttribute('aria-live', 'polite');
this.hasFocus = true;
};
CarouselTablist.prototype.handleTabBlur = function () {
this.tablistNode.classList.remove('focus');
if (this.playState) {
this.liveRegionNode.setAttribute('aria-live', 'off');
}
this.hasFocus = false;
};
/* Event Handlers for Tabpanels*/
CarouselTablist.prototype.handleTabpanelFocusIn = function () {
this.hasFocus = true;
};
CarouselTablist.prototype.handleTabpanelFocusOut = function () {
this.hasFocus = false;
};
/* Initialize Carousel Tablists and options */
window.addEventListener(
'load',
function () {
var carouselEls = document.querySelectorAll('.carousel-tablist');
var carousels = [];
// set example behavior based on
// default setting of the checkboxes and the parameters in the URL
// update checkboxes based on any corresponding URL parameters
var checkboxes = document.querySelectorAll(
'.carousel-options input[type=checkbox]'
);
var urlParams = new URLSearchParams(location.search);
var carouselOptions = {};
// initialize example features based on
// default setting of the checkboxes and the parameters in the URL
// update checkboxes based on any corresponding URL parameters
checkboxes.forEach(function (checkbox) {
var checked = checkbox.checked;
if (urlParams.has(checkbox.value)) {
var urlParam = urlParams.get(checkbox.value);
if (typeof urlParam === 'string') {
checked = urlParam === 'true';
checkbox.checked = checked;
}
}
carouselOptions[checkbox.value] = checkbox.checked;
});
carouselEls.forEach(function (node) {
carousels.push(new CarouselTablist(node, carouselOptions));
});
// add change event to checkboxes
checkboxes.forEach(function (checkbox) {
var updateEvent;
switch (checkbox.value) {
case 'moreaccessible':
updateEvent = 'setAccessibleStyling';
break;
case 'norotate':
updateEvent = 'enableOrDisableAutoRotation';
break;
}
// update the carousel behavior and URL when a checkbox state changes
checkbox.addEventListener('change', function (event) {
urlParams.set(event.target.value, event.target.checked + '');
window.history.replaceState(
null,
'',
window.location.pathname + '?' + urlParams
);
if (updateEvent) {
carousels.forEach(function (carousel) {
carousel[updateEvent](event.target.checked);
});
}
});
});
},
false
);
<script src="https://www.w3.orgcontent/shared/js/utils.js"></script>
/* .carousel-tablist */
img.reload {
padding: 0.25em;
display: block-inline;
position: relative;
top: 6px;
height: 0.9em;
}
.carousel-tablist {
background-color: #eee;
max-width: 900px;
}
.carousel-tablist .carousel-inner {
position: relative;
}
.carousel-tablist .carousel-items {
padding: 5px;
}
.carousel-tablist .carousel-items.focus {
padding: 2px;
border: solid 3px #005a9c;
}
.carousel-tablist .carousel-item {
display: none;
max-height: 400px;
max-width: 900px;
position: relative;
overflow: hidden;
width: 100%;
}
.carousel-tablist .carousel-item.active {
display: block;
}
/* More like bootstrap, less accessible */
.carousel-tablist .carousel-item .carousel-image a img {
height: 100%;
width: 100%;
}
.carousel-tablist .carousel-item .carousel-caption a {
cursor: pointer;
text-decoration: underline;
color: #fff;
font-weight: 600;
}
.carousel-tablist .carousel-item .carousel-caption a,
.carousel-tablist .carousel-item .carousel-caption span.contrast {
margin: 0;
padding: 6px;
display: inline-block;
background-color: rgb(0 0 0 / 65%);
border-radius: 5px;
border: 0 solid transparent;
}
.carousel-tablist-moreaccessible .carousel-items .carousel-image a {
display: block;
margin: 0;
padding: 5px;
text-decoration: none;
border: none;
}
.carousel-tablist-moreaccessible .carousel-item .carousel-caption a {
display: inline-block;
margin: 0;
padding: 6px;
color: black;
background-color: transparent;
border: none;
border-radius: 5px;
}
.carousel-tablist-moreaccessible .carousel-item .carousel-caption span.contrast,
.carousel-tablist-moreaccessible
.carousel-item
.carousel-caption
span.contrast:hover {
background-color: transparent;
}
.carousel-tablist .carousel-item .carousel-caption a:hover,
.carousel-tablist .carousel-item .carousel-caption span.contrast:hover {
background-color: rgb(0 0 0 / 100%);
}
.carousel-tablist .carousel-item .carousel-caption a:focus {
padding: 4px;
border: 2px solid #eee;
background-color: rgb(0 0 0 / 100%);
outline: none;
border-width: 2px solid #fff;
color: #fff;
}
.carousel-tablist .carousel-item .carousel-caption p {
font-size: 1em;
line-height: 1.5;
margin-bottom: 0;
}
.carousel-tablist .carousel-item .carousel-caption {
position: absolute;
right: 15%;
bottom: 0;
left: 15%;
padding-top: 20px;
padding-bottom: 20px;
color: #fff;
text-align: center;
}
/* Shared CSS for Pause and Tab Controls */
.carousel-tablist .controls {
box-sizing: border-box;
position: absolute;
top: 1em;
z-index: 10;
display: flex;
width: 100%;
padding: 0.25em 1.25em 0;
}
.carousel-tablist .tab-wrapper {
flex: 1 1 auto;
height: 30px;
text-align: center;
}
/* SVG Controls */
.carousel-tablist .rotation {
flex: 0 0 auto;
height: 30px;
padding: 0;
background-color: transparent;
border: none;
outline: none;
z-index: 10;
}
.carousel-tablist .svg-play .background {
stroke: black;
fill: black;
stroke-width: 1px;
opacity: 0.6;
}
.carousel-tablist .svg-play .border {
fill: transparent;
stroke: transparent;
stroke-width: 2px;
}
.carousel-tablist .svg-play .pause {
stroke-width: 4;
fill: transparent;
stroke: transparent;
}
.carousel-tablist .svg-play .play {
stroke-width: 1;
fill: transparent;
stroke: transparent;
}
.carousel-tablist .pause .svg-play .pause,
.carousel-tablist .play .svg-play .play {
fill: white;
stroke: white;
}
.carousel-tablist .rotation:focus .svg-play .background,
.carousel-tablist .rotation:hover .svg-play .background,
.carousel-tablist .rotation:hover .svg-play .border {
fill: #005a9c;
stroke: #005a9c;
opacity: 1;
}
.carousel-tablist .rotation:focus .svg-play .border {
stroke: white;
}
/* Shared CSS for Tabs */
.carousel-tablist [role="tablist"] {
box-sizing: border-box;
border: 0 transparent solid;
border-radius: 13px;
display: inline-block;
padding-top: 2px;
height: 30px;
background-color: rgb(0 0 0 / 65%);
}
.carousel-tablist [role="tablist"].focus {
border-width: 2px;
border-color: white;
padding-top: 0;
background-color: #005a9c;
}
.carousel-tablist [role="tab"] {
position: relative;
top: -2px;
padding: 0;
margin: 0;
background-color: transparent;
border: none;
outline: none;
width: 34px;
}
.carousel-tablist [role="tab"] circle.border {
display: none;
z-index: 12;
}
.carousel-tablist [role="tab"] circle.tab {
z-index: 16;
}
.carousel-tablist [role="tab"] circle.tab-background {
stroke: black;
fill: black;
stroke-width: 2px;
opacity: 0.6;
z-index: 14;
}
.carousel-tablist [role="tab"] circle.tab,
.carousel-tablist [role="tab"] circle.border {
stroke: white;
fill: transparent;
stroke-width: 2px;
}
.carousel-tablist-moreaccessible [role="tab"] circle.tab-background {
z-index: 16;
}
.carousel-tablist-moreaccessible [role="tab"] circle.tab {
z-index: 18;
}
.carousel-tablist [role="tab"][aria-selected="true"] circle.tab {
fill: white;
}
.carousel-tablist-moreaccessible [role="tab"] circle.border {
z-index: 14;
}
.carousel-tablist [role="tab"]:focus circle.border {
display: block;
fill: #005a9c;
stroke: #fff;
}
.carousel-tablist [role="tablist"].focus circle.tab-background {
stroke: #005a9c;
fill: #005a9c;
}
.carousel-tablist [role="tab"]:hover circle.tab-background {
fill: white;
stroke: white;
opacity: 1;
}
.carousel-tablist [role="tab"]:hover circle.border,
.carousel-tablist [role="tab"]:hover circle.tab {
fill: #005a9c;
stroke: #005a9c;
opacity: 1;
}
.carousel-tablist [role="tab"][aria-selected="true"]:hover circle.tab {
fill: white;
}
/* More accessible carousel styles, with caption and controls above/below image */
.carousel-tablist-moreaccessible {
padding: 0;
margin: 0;
position: relative;
border: #eee solid 4px;
border-radius: 5px;
}
.carousel-tablist-moreaccessible .carousel-items,
.carousel-tablist-moreaccessible .carousel-items.focus {
padding: 0;
border: none;
}
.carousel-tablist-moreaccessible .carousel-items.focus .carousel-image a {
padding: 2px;
border: 3px solid #005a9c;
}
/* More accessible caption styling */
.carousel-tablist-moreaccessible .carousel-item {
padding: 0;
margin: 0;
max-height: none;
}
.carousel-tablist-moreaccessible .carousel-item .carousel-caption {
position: static;
padding: 0;
margin: 0;
height: 60px;
color: black;
}
.carousel-tablist-moreaccessible .carousel-item .carousel-caption p {
padding: 0;
margin: 0;
}
.carousel-tablist-moreaccessible .carousel-item .carousel-caption h3 {
font-size: 1.1em;
padding: 0;
margin: 0;
}
.carousel-tablist-moreaccessible .carousel-item .carousel-caption a:hover {
background-color: rgb(0 0 0 / 20%);
}
.carousel-tablist-moreaccessible .carousel-item .carousel-caption a:focus {
padding: 4px;
border: 2px solid #005a9c;
background-color: transparent;
color: black;
outline: none;
}
/* Shared CSS for Pause and Tab Controls */
.carousel-tablist-moreaccessible .controls {
position: relative;
top: 0;
left: 0;
padding: 0.25em 0.25em 0;
}
/* Shared CSS for Tabs */
.carousel-tablist-moreaccessible [role="tab"] {
z-index: 20;
}
<link href="https://www.w3.org/content/shared/css/core.css" rel="stylesheet" />
<link href="https://www.w3.org/StyleSheets/TR/2016/base.css" rel="stylesheet" />
<link href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment