We want to hear from you!Take our 2021 Community Survey!

Erişilebilirlik

Niçin Erişilebilirlik?

(a11y) olarak da anılan web erişilebilirliği, herkes tarafından kullanılabilir web sitelerinin tasarımı ve oluşturulmasıdır. Erişilebilirlik desteği, yardımcı teknolojinin web sayfalarını yorumlamasına izin vermek için gereklidir.

React, sıklıkla standart HTML tekniklerini kullanarak, tamamen erişilebilir web siteleri oluşturmayı destekler.

Standartlar ve Yönergeler

WCAG

Web İçeriği Erişilebilirlik Yönergeleri, erişilebilir web siteleri oluşturmak için yönergeler sağlar.

Aşağıdaki WCAG kontrol listeleri genel bir bakış sağlar:

WAI-ARIA

Web Erişilebilirlik Girişimi - Erişilebilir Zengin İnternet Uygulamaları belgesi, tamamen erişilebilir JavaScript widgetleri oluşturmak için teknikler içerir.

Tüm aria- * HTML özelliklerinin, JSX’te tam olarak desteklendiğini unutmayın. React’teki çoğu DOM özellikleri ve nitelikleri camelCased iken, bu nitelikler düz HTML’de olduğu gibi hyphen-cased şeklinde olmalıdır (kebab-case, lisp-case, ve benzeri olarak da bilinir):

<input
  type="text"
  aria-label={labelText}  aria-required="true"  onChange={onchangeHandler}
  value={inputValue}
  name="name"
/>

Anlamsal HTML

Anlamsal HTML, bir web uygulamasında erişilebilirliğin temelidir. Web sitelerimizdeki bilginin anlamını pekiştirmek için, çeşitli HTML öğelerini kullanmak sıklıkla bize ücretsiz olarak erişilebilirlik sağlayacaktır.

Bazen, React kodumuzun çalışması için JSX’imize <div> öğeleri eklediğimizde, HTML’in anlamsallığını bozarız, özellikle listeler (<ol>, <ul> ve <dl>), ve HTML <table> ile çalışırken. Bu durumlarda, çoklu öğeleri gruplamak için React Fragmentleri kullanmayı tercih etmelisiniz.

Örneğin,

import React, { Fragment } from 'react';
function ListItem({ item }) {
  return (
    <Fragment>      <dt>{item.term}</dt>
      <dd>{item.description}</dd>
    </Fragment>  );
}

function Glossary(props) {
  return (
    <dl>
      {props.items.map(item => (
        <ListItem item={item} key={item.id} />
      ))}
    </dl>
  );
}

Başka herhangi bir öğe türünde yapacağınız gibi, bir öğe koleksiyonunu bir fragment dizisine (array’ine) eşleyebilirsiniz :

function Glossary(props) {
  return (
    <dl>
      {props.items.map(item => (// Kolleksiyonları eşleştirirken, fragmentler de bir `anahtar` prop'a sahip olmalıdır. 
        <Fragment key={item.id}>
          <dt>{item.term}</dt>          <dd>{item.description}</dd>
        </Fragment>
      ))}    </dl>
  );
}

Fragment etiketinde herhangi bir prop’a ihtiyacınız olmadığında, eğer araç gereçleriniz onu destekliyorsa kısa sözdizimi(syntax)‘ni kullanabilirsiniz:

function ListItem({ item }) {
  return (
    <>      <dt>{item.term}</dt>
      <dd>{item.description}</dd>
    </>  );
}

Daha fazla bilgi için, Fragmentler dokümantasyonu‘na bakınız.

Erişilebilir Formlar

Etiketlemek

<input> ve <textarea> gibi her HTML form kontrolunun (form control), erişilebilir halde etiketlenmiş olması gerekir. Ekran okuyucuları tarafndan da ortaya çıkan, açıklayıcı etiketler sağlamamız gerekir.

Aşağıdaki kaynaklar bize bunun nasıl yapılacağını gösterir:

Bu standart HTML uygulamaları doğrudan React’te kullanılabilmesine rağmen, for niteliğinin JSX’de htmlFor olarak yazıldığına dikkat edin:

<label htmlFor="namedInput">Name:</label><input id="namedInput" type="text" name="name"/>

Kullanıcı hatalarını bildirmek

Hata durumlarının tüm kullanıcılar tarafından anlaşılmış olması gerekir. Aşağıdaki link, hata metinlerinin de ekran okuyucuları tarafından nasıl algılandığını gösterir:

Odak Kontrolü

Web uygulamanızın yalnızca klavye ile tam olarak çalıştırılabildiğinden emin olun:

Klavye odağı ve odak ana hatları

Klavye odağı, klavyeden girişi kabul etmek için seçilen DOM’daki varolan öğeye başvurur. Bunu her yerde aşağıdaki resimde gösterilene benzer bir odak anahat olarak görürüz:

Mavi renk, seçilmiş bir link etrafindaki klavye odak anahattıdır

Eğer onu başka bir odak anahat uygulamasıyla değiştiriyorsanız, sadece bu anahattı kaldıran CSS’ini kullanın.

İstenilen içeriğe atlama mekanizmaları

Klavyede gezinmeye yardımcı olduğundan ve hızlandırdığından, kullanıcıların uygulamanızdaki geçmiş navigasyon bölümlerini atlamasına izin veren bir mekanizma sağlayın.

AtlamaLinkleri (Skiplinks) veya Navigasyon Linklerini Atlamak (Skip Navigation Links), klavye kullanıcıları, sadece sayfa ile etkileşimde bulundukları zaman görünür olan gizli navigasyon linkleridir. Bunların iç sayfa bağlantıları ve bazı stillerle uygulanması çok kolaydır:

Yardımcı teknoloji, kullanıcının bu bölümlere çabuk bir şekilde gezinmesine olanak tanıdığından, sayfa bölümlerini ayırmak için <main> ve <aside> gibi belirgin işaret (landmark) öğeleri ve rolleri de kullanın.

Erişilebilirliği geliştirmek için, bu öğelerin kullanımı hakkında daha fazlasını buradan okuyun

Programlayarak odağı yönetmek

React uygulamalarımız, çalışma süresinde, HTML DOM’u değiştirir, bazen klavye odağının kaybolmasına veya beklenmedik bir öğeye ayarlanmasına yol açar. Bunu düzeltmek amacıyla, klavye odağını programlı olarak doğru yönde itelemek gerekir. Örneğin, modal penceresi kapatıldıktan sonra, bir modal penceresi açan bir butona klavye odağını sıfırlatmak.

MDN Web Dokümanları buna bakar ve gezinilebilir-klavye JavaScript widgetleri‘ni nasıl inşa edebildiğimizi açıklar.

React’te odağı ayarlamak için DOM öğelerine Ref’ler‘i kullanabiliriz.

Bunu kullanarak, öncelikle, bir bileşen sınıfının JSX’indeki bir öğeye bir ref oluştururuz:

class CustomTextInput extends React.Component {
  constructor(props) {
    super(props);
    // textInput DOM öğesini depolamak için bir ref oluşturun    this.textInput = React.createRef();  }
  render() {
  // text input DOM'a bir referans depolamak için `ref` callback'i (geri çağrı) kullanın  // bir instance alanındaki öğe (örneğin, this.textInput).    return (
      <input
        type="text"
        ref={this.textInput}      />
    );
  }
}

Daha sonra, gerektiğinde bileşenimizde onu başka bir yere odaklayabiliriz:

focus() {
  // Açık bir şekilde, işlenmemiş DOM API'ı kullanarak metin girişine odaklanın
  // Not: DOM düğümünü almak için "current"e erişiyoruz
  this.textInput.current.focus();
}

Bazen bir üst bileşenin, bir alt bileşendeki bir öğeye odağının ayarlanması gerekir. Bunu DOM ref’lerini üst bileşenler de ortaya çıkartarak, üst öğenin ref’ini alt öğenin DOM düğümüne ileten alt bileşen üzerindeki özel bir prop yoluyla yapabiliriz.

function CustomTextInput(props) {
  return (
    <div>
      <input ref={props.inputRef} />    </div>
  );
}

class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.inputElement = React.createRef();  }
  render() {
    return (
      <CustomTextInput inputRef={this.inputElement} />    );
  }
}

// Simdi gerektiğinde odağı ayarlayabilirsiniz.
this.inputElement.current.focus();

Bileşenleri genişletmek için bir HOC kullanırken, React’in forwardRef fonksiyonu kullanılarak sarılmış bileşene ref’i iletmesi önerilir. Eğer üçüncü bir taraf HOC, ref iletmeyi uygulamazsa, yukarıdaki şablon yine de bir geri çekilme olarak kullanılabilir.

react-aria-modal, harika bir odak yönetimi örneğidir. Bu, tamamen erişilebilir bir modal penceresinin göreceli olarak nadir bir örneğidir.
Sadece ilk odağı iptal butonuna ayarlamak (klavye kullanıcısının başarılı eylemi yanlışlıkla etkinleştirmesini engeller) ve klavye odağını modal içinde hapsetmekle kalmaz, onu başlangıçta modalı tetikleyen öğeye geri odaklanarak sıfırlar.

Not:

Bu çok önemli bir erişilebilirlik özelliği iken, adilce kullanılması da gereken bir tekniktir. Nasıl yapılacağını tahmin etmek için değil, rahatsız edildiğinde klavye odak akışını onarmak için kullanın. kullanıcılar uygulamaları kullanmak ister.

Fare ve imleç olayları

Bir fare veya imleç olayı aracılığıyla açığa çıkan tüm fonksiyonların yalnızca klavye kullanılarak da erişilebildiğinden emin olun. Sadece imleç cihazına bağlı olarak, klavye kullanıcıları uygulamanızın kullanılamayacağı birçok duruma yönlendirilecektir.

Bunu göstermek için, tıklama olaylarının sebep olduğu bozuk erişilebilirliğin verimli bir örneğine bakalım. Bu, bir kullanıcının öğenin dışına tıklayarak, bir anda açılan pencereyi (popover) engellediği dış tıklama şablonudur.

A toggle button opening a popover list implemented with the click outside pattern and operated with a mouse showing that the close action works.

Bu genellikle popover’ı kapatan window nesnesine bir click olayının bağlanarak uygulanmasıdır.

class OuterClickExample extends React.Component {
  constructor(props) {
    super(props);

    this.state = { isOpen: false };
    this.toggleContainer = React.createRef();

    this.onClickHandler = this.onClickHandler.bind(this);
    this.onClickOutsideHandler = this.onClickOutsideHandler.bind(this);
  }

  componentDidMount() {    window.addEventListener('click', this.onClickOutsideHandler);  }
  componentWillUnmount() {
    window.removeEventListener('click', this.onClickOutsideHandler);
  }

  onClickHandler() {
    this.setState(currentState => ({
      isOpen: !currentState.isOpen
    }));
  }

  onClickOutsideHandler(event) {    if (this.state.isOpen && !this.toggleContainer.current.contains(event.target)) {      this.setState({ isOpen: false });    }  }
  render() {
    return (
      <div ref={this.toggleContainer}>
        <button onClick={this.onClickHandler}>Select an option</button>
        {this.state.isOpen && (
          <ul>
            <li>Option 1</li>
            <li>Option 2</li>
            <li>Option 3</li>
          </ul>
        )}
      </div>
    );
  }
}

Bu fare gibi imleçli cihaz kullanan kullanıcılar için iyi çalışabilir. Ama bunun tek olarak klavye ile çalıştırılması, sonraki öğeye sekme yapıldığında bozuk fonksiyonelliğe yol açar, çünkü window nesnesi asla click olayını almaz. Bu, kullanıcıların uygulamanızı kullanmasını engelleyen belirsiz fonksiyonellige yol açabilir.

A toggle button opening a popover list implemented with the click outside pattern and operated with the keyboard showing the popover not being closed on blur and it obscuring other screen elements.

Bunun yerine onBlur ve onFocus gibi, aynı fonksiyonellik, uygun olay yöneticilerini kullanarak ulaşılabilir:

class BlurExample extends React.Component {
  constructor(props) {
    super(props);

    this.state = { isOpen: false };
    this.timeOutId = null;

    this.onClickHandler = this.onClickHandler.bind(this);
    this.onBlurHandler = this.onBlurHandler.bind(this);
    this.onFocusHandler = this.onFocusHandler.bind(this);
  }

  onClickHandler() {
    this.setState(currentState => ({
      isOpen: !currentState.isOpen
    }));
  }

  // Bir sonraki tıklamada, setTimeout kullanarak açılır pencereyi (popover) kapatıyoruz.  // Bu gereklidir çünkü önce kontrol etmemiz gerekiyor, eğer  // öğenin başka bir alt öğesine odaklanılmışsa,   // bulanıklık olayı, yeni odak olayından önce tetiklendiği.  onBlurHandler() {    this.timeOutId = setTimeout(() => {      this.setState({        isOpen: false      });    });  }
  // Bir alt öğeye odaklanılırsa, açılır pencereyi (popover) kapatmayın  onFocusHandler() {    clearTimeout(this.timeOutId);  }
  render() {
    // React bulanıklığı köpürterek ve    // olayları üst öğeye odaklayarak bize yardımcı olur    return (
      <div onBlur={this.onBlurHandler}           onFocus={this.onFocusHandler}>        <button onClick={this.onClickHandler}
                aria-haspopup="true"
                aria-expanded={this.state.isOpen}>
          Select an option
        </button>
        {this.state.isOpen && (
          <ul>
            <li>Option 1</li>
            <li>Option 2</li>
            <li>Option 3</li>
          </ul>
        )}
      </div>
    );
  }
}

Bu kod, işlevselliği hem imlece hem de klavye kullanıcılarına sunar. Ekran-okuyucu kullanıcılarını desteklemek için eklenen aria-* prop’larına da dikkat edin. Basitlik adına, açılır pencere (popover) seçeneklerinin arrow key etkileşimini etkinleştirmek için klavye olayları uygulanmamıştır.

Hem fare hem de klavye kullanıcıları için doğru şekilde kapanan bir açılır (popover) liste.

Bu, sadece imleç ve fare olaylarına bağlı olan klavye kullanıcıları için, fonksiyonelliğin bozulduğu birçok duruma bir örnektir. Daima klavye ile test etmek, derhal klavyeye duyarlı olay yöneticilerini kullanarak düzeltilmiş olabilen sorunlu bölgeleri vurgular.

Daha Karmaşık Widgetler

Daha karmaşık bir kullanıcı deneyimi, daha az erişilebilir demek değildir. Erişilebilirlik en kolay şekilde mümkün olabildiğince HTML’ye yakın kodlama ile ulaşılabilir iken, en karmaşık widget bile erişilebilir şekilde kodlanmış olabilir.

Burada ARIA Durumları ve Özellikleri gibi ARIA Rolleri‘nin bilgisine gereksinim duyarız. Bunlar JSX’te tamamen desteklenmiş ve tamamen erişilebilir, yüksek dereceli fonksiyonel React bileşenleri inşa etmemize imkan veren HTML nitelikleriyle dolu araç kutularıdır.

Her çeşit widget öğesi türünün belirli bir tasarım deseni vardır ve hem kullanıcılar hem de kullanıcı ajansları gibi olanlar tarafından, belirli bir şekilde fonksiyon göstermesi beklenir:

Düşünülmesi Gereken Diğer Hususlar

Dili ayarlamak

Ekran okuyucu yazılımı, doğru ses ayarlarını seçmek için bunu kullandığından, sayfa metinlerinin insan dilini belirtin:

Doküman başlığını ayarlamak

Dokümanın <title>‘ını mevcut sayfa içeriğini doğru şekilde tanımlayarak ayarlayın, çünkü bu, kullanıcının mevcut sayfa içeriğinden emin olmasını sağlar:

Bunu React’te React Doküman Başlığı Bileşeni‘ni kullanarak ayarlayabiliriz.

Renk Kontrastı

Görme yetisi kısıtlı kullanıcılar tarafından, maksimum düzeyde okunabilmesi için web sitenizdeki tüm okunabilir metinlerin yeterli renk kontrastına sahip olduğundan emin olun:

Web sitenizdeki tüm durumlar için uygun renk kombinasyonlarını manuel olarak hesaplamak yorucu olabilir. Öyleyse, bunun yerine Colorable ile tüm erişilebilir bir renk paletini hesaplayın.

Aşağıda belirtilen hem aXe hem de WAVE araçları renk kontrast testlerini de içerir ve kontrast hatalarını rapor edecektir.

Kontrast testi becerilerinizi genişletmek istiyorsanız, bu araçları kullanabilirsiniz:

Geliştirme ve Test Etme Araçları

Erişilebilir web uygulamalarının oluşturulmasına yardımcı olmak için kullanabileceğimiz bir çok araç vardır.

Klavye

Şimdiye kadar en kolay ve aynı zamanda en önemli kontroller, tüm websitesinin sadece klavye ile ulaşalabilir ve kullanılabilir olduğunu test etmektir. Bunu şu şekilde yapın:

  1. Farenizin bağlantısını kesmek.
  2. Gözden geçirmek icin Tab ve Shift+Tab kullanmak.
  3. Öğeleri etkinleştirmek için Enter‘i kullanmak
  4. Gerektiğinde, menüler ve aşağı doğru açılan (dropdown) menüler gibi, bazı öğelerle etkileşim kurmak için klavye ok tuşlarınızı kullanmak.

Geliştirme asistanı

Bazı erişilebilirlik özelliklerini doğrudan JSX kodumuzda kontrol edebiliriz. Genellikle, ARIA rolleri, durumları ve özellikleri için Intellisense kontrolleri, JSX uyumlu IDE (Integrated Development Environment)‘lerde zaten sağlanmıştır. Aşağıdaki araca da erişimimiz vardir:

eslint-plugin-jsx-a11y

ESLint için eslint-plugin-jsx-a11y eklentisi, JSX’inizdeki erişilebilirlik sorunları ile ilgili AST linting geri bildirimini sağlar. Bir çok IDE, bu bulguları doğrudan kod analizi ve kaynak kodu pencereleri ile birlikte kullanmanıza izin verir.

Create React App, bir kural alt kümesinin etkinleştirildiği bu eklentiye sahiptir. Daha da fazla erişilebilirlik kurallarını etkinleştirmek istiyorsanız, bu içerikle projenizin root (kök) dizininde bir .eslintrc dosyası oluşturabilirsiniz:

{
  "extends": ["react-app", "plugin:jsx-a11y/recommended"],
  "plugins": ["jsx-a11y"]
}

Tarayıcıda erişilebilirliği test etme

Tarayıcınızda web sayfalarındaki erişilebilirlik denetimlerini çalıştırabilen bir dizi araçlar vardır. Onlar yalnızca HTML’nizin teknik erişilebilirliğini test edebildiği için, lütfen onları burada belirtilen diğer erişilebilirlik kontrolleriyle birlikte kullanın.

aXe, aXe-core ve react-axe

Deque Systemleri uygulamalarınızın otomatik ve uçtan-uça (end-to-end) erişilebilirlik testleri için aXe-core sunar. Bu modül Selenium için entegrasyonları içerir.

Erişilebilirlik Motoru veya aXe, aXe-core üzerine inşa edilmiş bir erişilebilirlik denetçisi tarayıcı uzantısı.

Geliştirme ve hata ayıklama sırasında, bu erişilebilirlik bulgularını doğrudan konsola bildirmek için react-axe modülünü de kullanabilirsiniz.

WebAIM WAVE

Web Erişilebilirlik Değerlendirme Aracı başka bir erişilebilirlik tarayıcı uzantısıdır.

Erişilebilirlik Denetçileri ve Erişilebilirlik Ağacı

Erişilebilirlik Ağacı, ekran okuyucuları gibi yardımcı teknolojilere maruz bırakılmış olması gereken, her DOM öğesi için erişilebilir nesneleri içeren DOM ağacının alt kümesidir.

Bazı tarayıcılarda, erişilebilirlik ağacındaki her öğe için erişilebilirlik bilgilerini kolayca görüntüleyebiliriz:

Ekran Okuyucuları

Bir ekran okuyucuyla test etmek, erişilebilirlik testlerinizin bir parçasını oluşturmalıdır.

Tarayıcı / ekran okuyucu kombinasyonlarının önemli olduğunu lütfen unutmayın. Uygulamanızı, seçtiğiniz ekran okuyucuya en uygun tarayıcıda test etmeniz önerilir.

Yaygın Kullanılan Ekran Okuyucuları

Firefox İçindeki NVDA

Görsel Olmayan Masaüstü Erişimi veya NVDA(NonVisual Desktop Access) yaygın olarak kullanılan açık kaynaklı bir Windows ekran okuyucudur.

NVDA’yı en iyi şekilde nasıl kullanacağınız konusunda aşağıdaki kılavuzlara basvurun:

Safari içindeki VoiceOver

VoiceOver, Apple cihazlara entegre edilmiş bir ekran okuyucudur.

VoiceOver’ı nasıl etkinleştireceğiniz ve kullanacağınız ile ilgili aşağıdaki rehberlere bakın:

Internet Explorer içindeki JAWS

Job Access With Speech (Konuşma ile İş Erişimi) veya JAWS, Windows üzerinde üretken olarak kullanılan ekran okuyucudur.

JAWS’ın en iyi nasıl kullanılacağına ilişkin aşağıdaki rehberlere başvurun:

Diğer Ekran Okuyucuları

Google Chrome içindeki ChromeVox

ChromeVox, Chromebooks’daki bir ekran okuyucudur ve Google Chrome için bir uzantı olarak vardır.

ChromeVox’un en iyi nasıl kullanılacağına ilişkin aşağıdaki rehberlere başvurun:

Bu sayfayı yararlı buldun mu?Bu sayfayı düzenle