Kumpulan Kerja Kebolehcapaian W3C memulakan Inisiatif Kebolehcapaian Web untuk membantu pembangun membina semantik kebolehaksesan ke dalam corak dan widget web. Widget ditekankan dalam penciptaan pengalaman yang boleh diakses. Sistem Reka Bentuk seperti Reka Bentuk Bahan, UI Fasih dan UI Antara Muka Manusia, ialah Sistem Reka Bentuk Berasaskan Widget yang dibina dengan Komponen Web pada platform Penyemak Imbas dan mereka mematuhi Garis Panduan Kebolehcapaian Web apabila diterjemahkan ke platform Asli. Menggunakan semantik ini bukan sahaja akan meningkatkan kebolehcapaian tapak web anda tetapi juga kelajuan pembangunan anda.
Pernahkah anda menghadapi masalah membina dan Karusel Imej atau Dialog Makluman sehingga anda memuat turun pakej daripada NPM untuk melakukannya? Tidak lagi. Inisiatif Kebolehcapaian Web menyokong anda. Mereka mempunyai widget sampel dan corak yang boleh anda lihat dengan CodePen. Memuat turun sampel ke dalam projek anda, ubah suainya dan anda selesai. Anda akan tahu cara membina Karusel Imej dan ia boleh diakses, tanpa memuat turun pakej daripada NPM
Contoh Karusel Imej:
<section> <ul> <li>CSS </li> </ul> <pre class="brush:php;toolbar:false">/* .carousel */ img.reload { padding: 0.25em; display: block-inline; position: relative; top: 6px; height: 0.9em; } .carousel { background-color: #eee; max-width: 900px; } .carousel .carousel-inner { position: relative; } .carousel .carousel-items { padding: 5px; } .carousel .carousel-items.focus { padding: 2px; border: solid 3px #005a9c; } .carousel .carousel-item { display: none; max-height: 400px; max-width: 900px; position: relative; overflow: hidden; width: 100%; } .carousel .carousel-item.active { display: block; } /* More like bootstrap, less accessible */ .carousel .carousel-item .carousel-image a img { height: 100%; width: 100%; } .carousel .carousel-item .carousel-caption a { cursor: pointer; text-decoration: underline; color: #fff; font-weight: 600; } .carousel .carousel-item .carousel-caption a, .carousel .carousel-item .carousel-caption span.contrast { display: inline-block; margin: 0; padding: 6px; background-color: rgb(0 0 0 / 65%); border-radius: 5px; border: 0 solid transparent; } .carousel-moreaccessible .carousel-items .carousel-image a { display: block; margin: 0; padding: 5px; text-decoration: none; border: none; } .carousel-moreaccessible .carousel-item .carousel-caption a { display: inline-block; margin: 0; padding: 6px; color: black; background-color: transparent; border: none; border-radius: 5px; } .carousel-moreaccessible .carousel-item .carousel-caption span.contrast, .carousel-moreaccessible .carousel-item .carousel-caption span.contrast:hover { background-color: transparent; } .carousel .carousel-item .carousel-caption a:hover, .carousel .carousel-item .carousel-caption span.contrast:hover { background-color: rgb(0 0 0 / 100%); } .carousel .carousel-item .carousel-caption a:focus { padding: 4px; border: 2px solid #fff; background-color: rgb(0 0 0 / 100%); outline: none; border-width: 2px solid #fff; color: #fff; } .carousel .carousel-item .carousel-caption p { font-size: 1em; line-height: 1.5; margin-bottom: 0; } .carousel .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, Previous and Next Buttons */ .carousel .controls { box-sizing: border-box; position: absolute; top: 1em; z-index: 10; display: flex; width: 100%; padding: 0.25em 1.25em 0; } .carousel .controls button { position: absolute; z-index: 10; flex: 0 0 auto; margin: 0; padding: 0; border: none; background: transparent; outline: none; } .carousel .controls button.previous { right: 70px; } .carousel .controls button.next { right: 18px; } /* SVG Controls */ .carousel .controls svg .background { stroke: black; fill: black; stroke-width: 1px; opacity: 0.6; } .carousel .controls svg .border { fill: transparent; stroke: transparent; stroke-width: 2px; } .carousel .controls svg .pause { stroke-width: 4; fill: transparent; stroke: transparent; } .carousel .controls svg .play { stroke-width: 1; fill: transparent; stroke: transparent; } .carousel .controls .pause svg .pause { fill: white; stroke: white; } .carousel .controls .play svg .play { fill: white; stroke: white; } .carousel .controls svg polygon { fill: white; stroke: white; } .carousel .controls button:focus svg .background, .carousel .controls button:hover svg .background, .carousel .controls button:hover svg .border { fill: #005a9c; stroke: #005a9c; opacity: 1; } .carousel .controls button:focus svg .border { stroke: white; } /* More accessible carousel styles, with caption and controls above/below image */ .carousel-moreaccessible { padding: 0; margin: 0; position: relative; border: #eee solid 4px; border-radius: 5px; } /* Shared CSS for Pause and Tab Controls */ .carousel-moreaccessible .controls { position: relative; top: 0; left: 0; padding: 0.25em 0.25em 0; } .carousel.carousel-moreaccessible .controls { position: static; height: 36px; } .carousel.carousel-moreaccessible .controls button.previous { right: 60px; } .carousel.carousel-moreaccessible .controls button.next { right: 6px; } .carousel-moreaccessible .carousel-items, .carousel-moreaccessible .carousel-items.focus { padding: 0; border: none; } .carousel-moreaccessible .carousel-items.focus .carousel-image a { padding: 2px; border: 3px solid #005a9c; } /* More accessible caption styling */ .carousel-moreaccessible .carousel-item { padding: 0; margin: 0; max-height: none; } .carousel-moreaccessible .carousel-item .carousel-caption { position: static; padding: 0; margin: 0; height: 60px; color: black; } .carousel-moreaccessible .carousel-item .carousel-caption p { padding: 0; margin: 0; } .carousel-moreaccessible .carousel-item .carousel-caption h3 { font-size: 1.1em; padding: 0; margin: 0; } .carousel-moreaccessible .carousel-item .carousel-caption a:hover { background-color: rgb(0 0 0 / 20%); } .carousel-moreaccessible .carousel-item .carousel-caption a:focus { padding: 4px; border: 2px solid #005a9c; background-color: transparent; color: black; outline: none; }
/* * File: carousel-prev-next.js * * Desc: Carousel widget with Previous and Next Buttons that implements ARIA Authoring Practices * */ 'use strict'; var CarouselPreviousNext = 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.carouselItemNodes = node.querySelectorAll('.carousel-item'); this.containerNode = node.querySelector('.carousel-items'); this.liveRegionNode = node.querySelector('.carousel-items'); this.pausePlayButtonNode = null; this.previousButtonNode = null; this.nextButtonNode = null; 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 // Pause Button var elem = document.querySelector('.carousel .controls button.rotation'); if (elem) { this.pausePlayButtonNode = elem; this.pausePlayButtonNode.addEventListener( 'click', this.handlePausePlayButtonClick.bind(this) ); } // Previous Button elem = document.querySelector('.carousel .controls button.previous'); if (elem) { this.previousButtonNode = elem; this.previousButtonNode.addEventListener( 'click', this.handlePreviousButtonClick.bind(this) ); this.previousButtonNode.addEventListener( 'focus', this.handleFocusIn.bind(this) ); this.previousButtonNode.addEventListener( 'blur', this.handleFocusOut.bind(this) ); } // Next Button elem = document.querySelector('.carousel .controls button.next'); if (elem) { this.nextButtonNode = elem; this.nextButtonNode.addEventListener( 'click', this.handleNextButtonClick.bind(this) ); this.nextButtonNode.addEventListener( 'focus', this.handleFocusIn.bind(this) ); this.nextButtonNode.addEventListener( 'blur', this.handleFocusOut.bind(this) ); } // Carousel item events for (var i = 0; i < this.carouselItemNodes.length; i++) { var carouselItemNode = this.carouselItemNodes[i]; // support stopping rotation when any element receives focus in the tabpanel carouselItemNode.addEventListener('focusin', this.handleFocusIn.bind(this)); carouselItemNode.addEventListener( 'focusout', this.handleFocusOut.bind(this) ); var imageLinkNode = carouselItemNode.querySelector('.carousel-image a'); if (imageLinkNode) { imageLinkNode.addEventListener( 'focus', this.handleImageLinkFocus.bind(this) ); imageLinkNode.addEventListener( 'blur', this.handleImageLinkBlur.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*/ CarouselPreviousNext.prototype.enableOrDisableAutoRotation = function ( disable ) { this.isAutoRotationDisabled = disable; this.pausePlayButtonNode.hidden = disable; }; /* Public function to update controls/caption styling */ CarouselPreviousNext.prototype.setAccessibleStyling = function (accessible) { if (accessible) { this.domNode.classList.add('carousel-moreaccessible'); } else { this.domNode.classList.remove('carousel-moreaccessible'); } }; CarouselPreviousNext.prototype.showCarouselItem = function (index) { this.currentIndex = index; for (var i = 0; i < this.carouselItemNodes.length; i++) { var carouselItemNode = this.carouselItemNodes[i]; if (index === i) { carouselItemNode.classList.add('active'); } else { carouselItemNode.classList.remove('active'); } } }; CarouselPreviousNext.prototype.previousCarouselItem = function () { var nextIndex = this.currentIndex - 1; if (nextIndex < 0) { nextIndex = this.carouselItemNodes.length - 1; } this.showCarouselItem(nextIndex); }; CarouselPreviousNext.prototype.nextCarouselItem = function () { var nextIndex = this.currentIndex + 1; if (nextIndex >= this.carouselItemNodes.length) { nextIndex = 0; } this.showCarouselItem(nextIndex); }; CarouselPreviousNext.prototype.rotateSlides = function () { if (!this.isAutoRotationDisabled) { if ( (!this.hasFocus && !this.hasHover && this.isPlayingEnabled) || this.hasUserActivatedPlay ) { this.nextCarouselItem(); } } this.slideTimeout = setTimeout( this.rotateSlides.bind(this), this.timeInterval ); }; CarouselPreviousNext.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 */ CarouselPreviousNext.prototype.handleImageLinkFocus = function () { this.liveRegionNode.classList.add('focus'); }; CarouselPreviousNext.prototype.handleImageLinkBlur = function () { this.liveRegionNode.classList.remove('focus'); }; CarouselPreviousNext.prototype.handleMouseOver = function (event) { if (!this.pausePlayButtonNode.contains(event.target)) { this.hasHover = true; } }; CarouselPreviousNext.prototype.handleMouseOut = function () { this.hasHover = false; }; /* EVENT HANDLERS */ CarouselPreviousNext.prototype.handlePausePlayButtonClick = function () { this.hasUserActivatedPlay = !this.isPlayingEnabled; this.updatePlaying(!this.isPlayingEnabled); }; CarouselPreviousNext.prototype.handlePreviousButtonClick = function () { this.previousCarouselItem(); }; CarouselPreviousNext.prototype.handleNextButtonClick = function () { this.nextCarouselItem(); }; /* Event Handlers for carousel items*/ CarouselPreviousNext.prototype.handleFocusIn = function () { this.liveRegionNode.setAttribute('aria-live', 'polite'); this.hasFocus = true; }; CarouselPreviousNext.prototype.handleFocusOut = function () { if (this.isPlayingEnabled) { this.liveRegionNode.setAttribute('aria-live', 'off'); } this.hasFocus = false; }; /* Initialize Carousel and options */ window.addEventListener( 'load', function () { var carouselEls = document.querySelectorAll('.carousel'); 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 CarouselPreviousNext(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 );
Berikut ialah pautan kepada dokumentasi:
https://www.w3.org/WAI/ARIA/apg/patterns/
https://www.w3.org/WAI/ARIA/apg/practices/
Berikut ialah dokumentasi Rangkaian Pembangun Mozilla:
https://developer.mozilla.org/en-US/docs/Web/API
Bina dengan Platform Penyemak Imbas. Bina Dengan Piawaian Web. Bina pengalaman yang boleh diakses. Bina dengan Komponen Web. Bina tanpa rangka kerja.
Atas ialah kandungan terperinci Bina Semantik Kebolehcapaian ke dalam Widget - Inisiatif Kebolehcapaian Web. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!