Duyarlı ve Erişilebilir Markup

1.7k görüntülenme Markdown

Bir temanın markup'ının karşılaması gereken ölçülebilir sözleşme ve her kuralın nasıl kanıtlandığı.

Genel Bakış

Duyarlılık ve erişilebilirlik sonda yapılan bir gözden geçirme değildir. Kabukta birkaç bildirim ve canlı sayfada ölçülen birkaç kuraldır.

İki yükümlülük yalnız temaya aittir: her layout'taki viewport bildirimi ve kökteki dil ile yön öznitelikleri.

Ön Koşullar

  • En az bir layout'u olan bir tema; layout, kendi belge başlığını açan her şablondur.
  • Bootstrap 5 anlambilimi. Sürüm 4 sınıf adı hata değildir: sessizce stilsiz kalır.
  • İçinde ölçüm yapabileceğiniz bir tarayıcı.

Yapı

Layout Bildirimleri

Layout başına üç bildirim; motor hiçbirini eklemez.

  1. Viewport meta'sı, tam olarak width=device-width, initial-scale=1. Onsuz telefon masaüstü genişliğinde yerleştirir.
  2. Kök elemanda dil ve yazım yönü, motorun değişkenlerinden.
  3. İlk boyamadan önce yön farkındalıklı stil dosyası seçimi, head guard'ının içinde.

Tema başına denetim: grep -L 'name="viewport"' templates/website/<Tema>/layouts/*.tpl hiçbir şey göstermemeli.

Motor Değişkenleri

DeğişkenBiçimiNereden çözülür
$ui_lang en ya da tr gibi bir dil kodu. Seçili dil; her istekte yeniden çözülür.
$ui_dir Tam olarak ltr ya da rtl, başka hiçbir şey. Dil paketinin kendi yön işareti.
$setting Tema manifestindeki her alan, kayıtlı değerlerle birleşmiş. Temanın ayar şeması; yalnız operatöre ait yerleşim anahtarları için.

Referans

Tema API'si

imzalar
// coremio/classes/Theme.php
// {asset path='...'} bunu çağırır. YALNIZ css ve js'e dosyanın değişiklik zamanıyla ?v= ekler.
// Font ve görseller bilerek sorgusuz kalır: sürümlenmiş bir font preload'u, font stil dosyasının
// içindeki sorgusuz url() ile hiçbir zaman eşleşmez, preload boşa gider ve yüz ilk boyamayı kaçırır.
public function assetUrl(string $path = ''): string;

// {lang key='...' var='...'} bunu çağırır. 'key' ve 'g' dışındaki her adlandırılmış argüman
// değerde {var} yerine geçer; erişilebilir bir adın gerçek sayıyı taşıması böyle olur.
// Yalnız Smarty: Twig fonksiyonu tek başına anahtarı alır, hiçbir değişken iletmez; Twig
// kullanan bir tema yerine koymayı çağrının dışında yapar, okuyucuya ham {count} göndermez.
public function lang(string $key, array $vars = []): string;

// Bu temada views/<view> varsa true; bir kabuğu ona render etmeden önce kapı olarak kullanılır.
public function viewExists(string $view): bool;
yön kaynağı
// coremio/classes/Language.php
public static function selected(): string;
public static function g($key = '', $replaces = [], $slang = ''): array|string|int|bool;
her istekte çözülen
// Şablon yalnız sonucu basar; yönü kendisi hiç çözmez.
$ui_lang = Language::selected();
$ui_dir  = Language::g("package/rtl") ? 'rtl' : 'ltr';
Theme::assetUrl() Temanın varlıklarındaki yolu çözer ve sürümler. Elle yazılan bağlantıda cache buster olmaz.
Theme::lang() Görünür her dize ve görünmez olanların hepsi: aria etiketleri de metindir.
Language::selected() Kök dil özniteliğine giden kod. Ekran okuyucular telaffuzu ondan alır.

Kırılımlar

Dördüncü bir sorgu ayrıntı değil karardır.

SorguKademeBuraya ne girer
max-width: 575.98px Küçük kademenin altı Telefon sıkıştırması: bir etiketi gizlemek, bir araç çubuğunu toplamak.
max-width: 767.98px Orta kademenin altı Telefondan sonra da yaşayan yerleşim değişiklikleri.
min-width: 992px Büyük ve üstü Yalnız masaüstündeki kabuk öğeleri. Küçük ekran varsayılan olsun diye minimum yazılır.
print Yazdırma Kâğıtta anlamı olmayan kabuk öğeleri. Tek blok.

Punto Ölçeği

Var olanın yanına yeni bir boyut asla icat edilmez.

SınıfDeğer16px kökteNe için
fs-70.85rem13.6pxİkincil metin: kart gövdeleri, liste satırları, tablo hücreleri.
fs-80.8rem12.8pxBir kontrolün altındaki ipucu satırları.
fs-90.7rem11.2pxTaban. Yalnız rozetler ve mikro etiketler.
BaşlıklarBootstrap ölçeğiBeşinci başlık basamağı 20pxBölüm başlıkları. Yardım satırı etiketinden büyük olamaz.

Hareket ve Odak

TercihTemanın yaptığıNasıl kanıtlanır
Azaltılmış hareket Genel bir blok her animasyonu milisaniyenin yüzde birine kısar ve tek yinelemeye zorlar. Sıfır opaklıkta kalan elemanları sayın; cevap sıfır olmalı.
Klavye odağı Halkalar yalnız klavye gezinmesinde görünür. Sekmeyle gezin: her durak görünür olmalı. Sonra tıklayın: hiçbir halka kalmamalı.

Ekran Dışı Metin

İhtiyaçDoğru markupYanlışı ne yapar
Görünür metni olmayan bir kontrol Dil dosyasından gelen bir aria etiketi. Sabit yazılmış metin diğer her dilde İngilizce kalır.
Yalnız ekran okuyucu için metin visually-hidden sr-only Bootstrap 4 adıdır; Bootstrap 5 tanımlamaz. Onu bir ikon kütüphanesi ayakta tutar.
Klavye kullanıcısı için yer imi Aria etiketli bir nav elemanı ve işaretlenmiş mevcut sayfa. Adsız gezinme yer imleri, yer imi listesinde ayırt edilemez.

Geniş İçerik

İçerikSarmalayıcıOnsuz
Telefonun gösterebileceğinden çok kolonu olan tablo Tablo elemanının etrafında duyarlı tablo sarmalayıcısı. Sayfanın kendisi yana kayar ve üzerindeki her ekran bunu devralır.
Uzun, bölünmemiş bir dize (anahtar, jeton, alan adı) Kapsayıcıdan genişlik kaldırmak değil, hücrede sarma. Kapsayıcıyı genişletmek son kolonları kenarın dışına iter.
Bir kod bloğu ya da yük Kendi kaydırma kabı. Aynı sayfa seviyesinde yana kayma, uzun satır içeren sayfalarda.

Geniş içerik kendi kutusunun içinde kayar; sayfa gövdesi asla kaymaz.

Örnek

Yükümlülükler, layout başlığındaki sırayla.

layouts/default.tpl
<html lang="{$ui_lang|default:'en'}" dir="{$ui_dir|default:'ltr'}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    {* İlk boyamadan önce: saklı yönü çöz ve eşleşen Bootstrap dosyasını yaz, böylece ilk
       boyanan kare bir kare sonra çevrilmek yerine zaten doğru olsun. *}
    <script>
      var storedDir = localStorage.getItem('acme-dir');
      var rtl = storedDir ? storedDir === 'rtl' : document.documentElement.getAttribute('dir') === 'rtl';
      document.documentElement.setAttribute('dir', rtl ? 'rtl' : 'ltr');
      document.write('<link rel="stylesheet" href="' +
        (rtl ? '{asset path="css/bootstrap.rtl.min.css"}' : '{asset path="css/bootstrap.min.css"}') + '">');
    </script>

    <link rel="stylesheet" href="{asset path='css/default.css'}">
</head>

Müşteri panelindeki erişilebilirlik işinin çoğunu taşıyan iki markup kalıbı.

partials/client-subnav.tpl
<nav class="client-subnav" aria-label="{lang key='website/index/subnav-aria'}">
    <ul>
        <li>
            <a class="client-subnav-link{if $subnav == 'services'} active{/if}"
               {if $subnav == 'services'} aria-current="page"{/if}
               href="{link route='services'}">
                <i class="bi bi-hdd-stack"></i>{lang key='website/index/subnav-services'}
                {if $client_badges.services > 0}
                    {* Sayı tek başına bağlamdan koparsa anlamsızdır, bu yüzden rozet kendini adlandırır. *}
                    <span class="client-subnav-badge"
                          aria-label="{lang key='website/index/subnav-badge-services' count=$client_badges.services}">
                        {$client_badges_text.services}
                    </span>
                {/if}
            </a>
        </li>
    </ul>
</nav>

{* Bootstrap 5 adı. 'sr-only' bir Bootstrap 5 sınıfı değildir; ona güvenmeyin. *}
<span class="visually-hidden">{lang key='website/index/footer-payment-methods'}</span>

Bu iki değişken motordan değil, müşteri sayfa verisiyle gelir.

$client_badges services, domains, invoices, support anahtarlı tam sayılar. Bölüm kapalıysa anahtar kaybolmaz, sıfır olur.
$client_badges_text Aynı anahtarlar, gösterim dizisi olarak. Bunu rozetin içine, ham olanı etiketin içine yazın.

Kabul listesi; her satır canlı sayfada alınan bir ölçümdür.

Sayfada yana kayma yok 320 CSS piksel genişlikte belgenin kaydırma genişliği pencerenin iç genişliğini aşmamalı.
Dokunma hedefleri Kısa eksende en az 44 CSS piksel. İkonu değil kutuyu ölçün.
Klavyede görünür, işaretçide görünmez odak Sekmeyle gezin: her durak görünür. Tıklayın: hiçbir halka sağ çıkmaz.
Azaltılmış hareket hiçbir şeyi gizli bırakmaz Tercih açıkken sıfır opaklıkta kalan eleman sayısı sıfırdır.
Kontrast Gövde metninde 4.5'e 1, büyük metinde 3'e 1. Açık ve koyu modda ölçün.
Sağdan sola Kök yön özniteliğini çevirin ve yeniden gezin. Hiçbir şey üst üste binmez, kırpılmaz.

Tuzaklar

Bootstrap 4 sınıf adı sessizce stilsizdir

Kopyalanan markup, işi yapan sınıf eksik olana kadar çalışır. Önce o sınıfı biçimlendiren kuralı bulun.

Viewport meta'sı olmayan tek bir layout bütün bir akışı bozar

Yükümlülük tema başına değil layout başınadır. Bildirimsiz bir ödeme kabuğu akışı masaüstü genişliğinde açar.

Kapsayıcıyı genişletmek gösterdiğinden fazlasını gizler

Bir hücrenin genişlik sınırını kaldırmak son kolonları kenardan düşürür. Bunun yerine değerin hücre içinde sarmasına izin verin.

Görünmez metin de metindir

Aria etiketleri sabit yazılması en kolay dizelerdir, çünkü kimse onları gözden geçirmede görmez.

Bir temadaki düzeltme hepsinde düzeltmedir

Buradaki her şey görsel kimlik değil davranıştır. Tek temaya uygulanan düzeltme, aynı kusuru başka adla bırakır.

Faydalı oldu mu?

Geri bildiriminiz için teşekkürler!

Hâlâ Yardıma mı İhtiyacınız Var?

Yukarıda bulamadığınız her şey için destek ekibimiz her zaman yanınızda.