Heim > Web-Frontend > CSS-Tutorial > Integrieren Sie Barrierefreiheitssemantik in Widgets – Web Accessibility Initiative

Integrieren Sie Barrierefreiheitssemantik in Widgets – Web Accessibility Initiative

Susan Sarandon
Freigeben: 2024-12-30 14:01:12
Original
473 Leute haben es durchsucht

Build Accessibility Semantics into Widgets - Web Accessibility Initiative

Die W3C Accessibility Working Group hat die Web Accessibility Initiative ins Leben gerufen, um Entwickler bei der Integration von Barrierefreiheitssemantik in Webmuster und Widgets zu unterstützen. Bei der Schaffung barrierefreier Erlebnisse stehen Widgets im Vordergrund. Designsysteme wie Material Design, Fluent UI und Human Interface UI sind Widget-basierte Designsysteme, die mit Webkomponenten auf der Browser-Plattform erstellt werden und sich bei der Übersetzung auf native Plattformen genau an die Web Accessibility Guidelines halten. Die Verwendung dieser Semantik verbessert nicht nur die Zugänglichkeit Ihrer Websites, sondern auch Ihre Entwicklungsgeschwindigkeit.

Hatten Sie jemals Probleme beim Erstellen eines Bildkarussells oder eines Warndialogs, sodass Sie dafür ein Paket von NPM heruntergeladen haben? Nicht mehr. Die Web Accessibility-Initiative steht Ihnen zur Seite. Sie verfügen über Beispiel-Widgets und Muster, die Sie mit CodePen anzeigen können. Lädt das Beispiel in Ihr Projekt herunter, ändert es und fertig. Sie wissen, wie Sie ein Bildkarussell erstellen, und Sie können darauf zugreifen, ohne ein Paket von NPM herunterladen zu müssen

Beispiel für ein Bildkarussell:

  • HTML
<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;
}
Nach dem Login kopieren
  • JS
/*
 *   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
);
Nach dem Login kopieren

Hier finden Sie Links zur Dokumentation:

https://www.w3.org/WAI/ARIA/apg/patterns/

https://www.w3.org/WAI/ARIA/apg/practices/

Hier ist die Dokumentation des Mozilla Developer Network:

https://developer.mozilla.org/en-US/docs/Web/API

Erstellen Sie mit der Browser-Plattform. Erstellen Sie mit Webstandards. Bauen Sie barrierefreie Erlebnisse auf. Erstellen Sie mit Webkomponenten. Erstellen Sie ohne Framework.

Das obige ist der detaillierte Inhalt vonIntegrieren Sie Barrierefreiheitssemantik in Widgets – Web Accessibility Initiative. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:dev.to
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage