برنامه های Angular در دسترس تر بسازید

1. قبل از شروع

لوگوی مشکی انگولار

دسترسی بخشی حیاتی از توسعه وب است و تضمین می کند که کاربران می توانند برنامه ها را درک کنند، درک کنند، پیمایش کنند و با آنها تعامل داشته باشند. در واقع، از هر 4 بزرگسال آمریکایی، 1 نفر دارای معلولیتی است که بر فعالیت های اصلی زندگی آنها تأثیر می گذارد. در سراسر جهان، حدود 15 درصد از جمعیت جهان - بیش از 1 میلیارد نفر - نوعی ناتوانی دارند که حدود 2 تا 4 درصد با مشکلات قابل توجهی روبرو هستند.

شرایط رایجی که بر استفاده شخص از وب تأثیر می گذارد شامل نابینایی یا کم بینایی، ناشنوایی یا اختلال در شنوایی، محدودیت مهارت های حرکتی، ناتوانی های شناختی، و کوررنگی است - و این فقط یک لیست جزئی است.

در این دوره، a11y مخفف دسترسی است. توجه کنید که a با 11 کاراکتر و یک y دنبال می شود.

برای آشنایی عمیق با مسائل و تکنیک‌های طراحی برنامه‌های قابل دسترس، دسترسی را ببینید.

چیزی که خواهی ساخت

  • از بهترین شیوه‌ها و تکنیک‌های داخلی برای رسیدگی به مشکلات رایج دسترسی به وب در یک برنامه آزمایشی Dumpling Shop Angular استفاده کنید.
  • تمام دستورالعمل‌های دسترسی، WCAG 2.0 و ARIA 1.2 را رعایت کنید و ممیزی‌های دسترسی تبر و فانوس دریایی را بگذرانید.

وب سایت فروشگاه دامپلینگ تایم با تم صورتی و قرمزوب سایت فروشگاه دامپلینگ تایم با تم بنفش و سبز

چیزی که یاد خواهید گرفت

با هشت مشکل رایج دسترسی در برنامه های Angular آشنا می شوید که بر روی کاربران تأثیر می گذارد، چگونه آنها را شناسایی کنید و چگونه آنها را برطرف کنید. به طور دقیق تر، شما:

  • از ابزارهای توسعه‌دهنده Google Chrome، Lighthouse، و تبر برای بررسی قابلیت دسترسی برنامه خود استفاده کنید
  • مشکلات برنامه تک صفحه ای (SPA) را با عناوین صفحات منحصر به فرد حل کنید
  • مشکلات کنتراست کم رنگ را برای کاربران کم بینا برطرف کنید
  • از HTML معنایی استفاده کنید تا مطمئن شوید صفحه خوان ها به درستی صفحه را هدایت می کنند
  • از کنترل‌های Angular Material و unnest استفاده کنید تا مطمئن شوید که صفحه‌خوان‌ها می‌توانند به همه کنترل‌ها دسترسی داشته باشند
  • پشتیبانی ARIA را برای صفحه‌خوان‌ها اضافه کنید
  • بسته Angular CDK a11y را وارد کنید و از آن استفاده کنید
  • از FocusTrap برای پیمایش صفحه‌خوان کامپوننت سفارشی استفاده کنید
  • اعلان‌ها را با CDK LiveAnnouncer اعلام کنید
  • شناسایی کاربران با حالت HighContrast و پیاده سازی موضوع با کنتراست بالا

آنچه شما نیاز دارید

2. راه اندازی شوید

کد را دریافت کنید

هر آنچه برای این پروژه نیاز دارید در یک مخزن GitHub است. برای شروع، کد را شبیه سازی کنید و آن را در محیط برنامه نویس مورد علاقه خود باز کنید.

مخزن را کلون کنید و برنامه را ارائه دهید

VSCode یا یک IDE محلی روش توصیه شده برای کار از طریق این کد لبه است.

  1. یک برگه مرورگر جدید باز کنید و به https://github.com/googlecodelabs/angular-accessibility بروید.
  2. Repository را Fork و کلون کنید و cd angular-accessibility/ در مخزن قرار دهید.
  3. git checkout get-started بررسی کنید.
  4. کد را در VSCode یا IDE دلخواه خود باز کنید.
  5. برای نصب وابستگی های مورد نیاز برای اجرای سرور npm install اجرا کنید.
  6. ng serve برای اجرای سرور اجرا کنید.
  7. یک برگه مرورگر را به http://localhost:4200 باز کنید.

3. یک خط پایه ایجاد کنید

نقطه شروع شما چیست؟

نقطه شروع شما یک برنامه رستوران اصلی است که برای این کد لبه طراحی شده است. کد برای نشان دادن مفاهیم در این Codelab ساده شده است و عملکرد کمی دارد.

وب سایت فروشگاه دامپلینگ تایم با تم بنفش و سبز

نسخه ی نمایشی را کاوش کنید

برای شروع، از سه ویژگی برنامه خود استفاده کنید:

  1. از نوار پیمایش برای مشاهده مسیرهای فروشگاه ما ، داستان ما ، و یافتن ما استفاده کنید و جزئیات مربوط به شرکت دامپلینگ را ببینید.
  2. تم ها را به تغییر حالت روشن و تاریک تغییر دهید.
  3. پر کردن پیراشکی، تعداد و رنگ سفارش خود را سفارشی کنید.
  4. خرید را انتخاب کنید تا سفارش سفارشی خود را در کنسول ثبت کنید.

از Angular برای رسیدگی به مشکلات رایج دسترسی به وب استفاده کنید

در این کد لبه، شما بر دسترسی به ویژگی های موجود این برنامه تمرکز می کنید. شما با شناسایی مشکلات a11y در برنامه خود شروع می کنید، سپس با پیاده سازی یک راه حل، 🛑 را به یک ✅ تبدیل می کنید.

چگونه می دانید چه چیزی را اصلاح کنید؟

هر مثال را با تشخیص مشکل دسترسی با استفاده از ترکیبی از آزمایش دستی و خودکار شروع کنید.

در وضعیت فعلی وب، آزمایش دستی دسترسی اجباری است.

شما ابزارهایی دارید که می توانند مشکلات دسترسی را شناسایی کنند، اما هیچ ابزاری نمی تواند تأیید کند که یک برنامه کاملاً در دسترس است. آزمایش دستی تضمین می کند که شما برای وسعت مفاهیم a11y که شامل ترتیب منطقی محتوا و برابری ویژگی ها هستند، آزمایش می کنید.

تست دستی

برای آزمایش دستی دسترس‌پذیری در این دوره، صفحه‌خوان داخلی رایانه ما را روشن می‌کنید و با پیمایش صفحه‌کلید در برنامه خود پیمایش می‌کنید. برای اطلاعات بیشتر، به Semantics and screen readers مراجعه کنید.

با روشن کردن صفحه‌خوان و پیمایش روی صفحه تمرین کنید.

می توانید از VoiceOver داخلی MacOS استفاده کنید. روی تنظیمات برگزیده سیستم > دسترسی > VoiceOver > فعال کردن VoiceOver کلیک کنید تا آن را روشن کنید . برای تغییر وضعیت VoiceOver، در حالی که کلید Command را نگه داشته اید، به سرعت TouchID را سه بار فشار دهید.

در این دوره، شما در درجه اول مسائل را به صورت دستی آزمایش می‌کنید و از ابزارهای خودکار برای کمک به بررسی ویژگی‌های قابل خودکارسازی خاص استفاده می‌کنید.

تست خودکار

شما همچنین از چند ابزار توسعه برای خودکارسازی و ممیزی اپلیکیشن خود استفاده می کنید. این ابزارها به شما امکان می دهند مواردی مانند وجود متن جایگزین روی یک تصویر یا نسبت کنتراست رنگ متن را بررسی کنید. شما می توانید این ابزار را به عنوان لنگر در نظر بگیرید. آنها می توانند تشخیص دهند که متن جایگزین وجود دارد، اما شما باید به صورت دستی بررسی کنید که محتوا منطقی است و ارزش ارائه می دهد.

Lighthouse و Chrome Developer Tools

  1. Chrome Developer Tools را باز کنید.
  2. تب Lighthouse را انتخاب کرده و کادر Accessibility را انتخاب کنید.
  3. برای اجرای a11y Lighthouse ممیزی روی Generate report کلیک کنید.

برگه مثال Lighthouse با دکمه ایجاد گزارش در برگه ابزار توسعه کروم

تبر

  1. پسوند ax DevTools را نصب کنید. ممکن است لازم باشد مرورگر خود را مجددا راه اندازی کنید تا افزونه را ببینید.
  2. Chrome Developer Tools را باز کنید.
  3. تب DevTools را انتخاب کنید و Scan all of my page را انتخاب کنید تا اسکن ابزار DevTools را اجرا کنید.

پرز زدن

می توانید از قوانین Angular ESLint برای پر کردن کد خود برای ویژگی های خودکار a11y استفاده کنید.

در eslint.json موارد زیر را اضافه کنید که در مورد دسترسی اعمال می شود:

"@angular-eslint/template/accessibility-alt-text": 2,
"@angular-eslint/template/accessibility-elements-content": 2,
"@angular-eslint/template/accessibility-label-for": 2,
"@angular-eslint/template/no-positive-tabindex": 2,
"@angular-eslint/template/accessibility-table-scope": 2,
"@angular-eslint/template/accessibility-valid-aria": 2,
"@angular-eslint/template/click-events-have-key-events": 2,
"@angular-eslint/template/mouse-events-have-key-events": 2,
"@angular-eslint/template/no-autofocus": 2,
"@angular-eslint/template/no-distracting-elements": 2

برای اطلاعات بیشتر، آخرین قوانین ESLint در GitHub را ببینید.

نقطه شروع شما

با استفاده از روش‌های تست جدید خود، می‌توانید با استفاده از ممیزی Lighthouse و تبر و VoiceOver دستی، مشکلات زیر را در برنامه خود شناسایی کنید:

Chrome DevTools Lighthouse ممیزی با امتیاز 82

ممیزی دسترسی:

  • 🛑 همه صفحات عنوان صفحه یکسانی دارند
  • 🛑 عناصر باید تضاد رنگی کافی داشته باشند
  • 🛑 HTML باید ترتیب، نام و نقش منطقی داشته باشد
  • 🛑 چک باکس های تودرتو برای صفحه خوان ها قابل انتخاب نیستند
  • 🛑 صفحه خوان مقادیر لغزنده را نمی خواند
  • 🛑 فوکوس صفحه خوان در انتخابگر رنگ از گفتگو خارج می شود
  • 🛑 تغییرات، خطاها و اعلان ها اعلام نمی شود
  • 🛑 حالت High Contrast فعال نیست

4. عناوین صفحات منحصر به فرد را تعریف کنید

ارائه عناوین منحصر به فرد و مختصر صفحه به کاربرانی که از خدمات a11y استفاده می کنند کمک می کند تا به سرعت محتوا و هدف یک صفحه وب را درک کنند. عناوین صفحات برای کاربران دارای ناتوانی بینایی بسیار مهم هستند زیرا آنها اولین عنصر صفحه هستند که توسط نرم افزارهای صفحه نمایش اعلام می شوند.

Angular یک برنامه تک صفحه ای است و در نتیجه اکثر انتقال ها، مانند انتقال به صفحه جدید، شامل بارگذاری مجدد صفحه نمی شود. تا همین اواخر، این بدان معنی بود که هر صفحه عنوان صفحه یکسانی داشت و هیچ ارزشی برای درک محتوا یا هدف صفحه ارائه نمی کرد.

در Angular v14، روتر یک روش داخلی برای تعریف عناوین صفحات منحصر به فرد از جعبه اضافه کرد. این یک رویکرد ساده برای اطمینان از اینکه توسعه‌دهندگان از بهترین شیوه‌های عنوان صفحه پیروی می‌کنند، فراهم می‌کند.

در پایان این بخش، برنامه شما ممیزی زیر را پشت سر می گذارد:

  • 🛑 همه صفحات عنوان صفحه یکسانی دارند

شما می توانید هر یک از این مراحل را زیر نظر پیدا کنید: TODO: #4. Define unique page titles.

موضوع را شناسایی کنید

برای شناسایی این مشکل، صفحه‌خوان خود را روشن کنید و بین برگه‌های فروشگاه ما ، داستان ما ، و یافتن ما پیمایش کنید تا عناوین صفحه را ببینید:

  1. VoiceOver را روشن کنید.
  2. برای پیمایش بین صفحات از پیمایش تب استفاده کنید.
  3. بررسی کنید که عنوان صفحه در Angular همیشه a11y باشد.

این یک مشکل است زیرا عنوان صفحه شما باید منحصر به فرد باشد تا کاربر بتواند بدون نیاز به پیمایش در آن به سرعت بفهمد که صفحه در مورد چیست.

مرورگر کروم با سه برگه باز با عنوان صفحه یکسان: 'a11y در Angular'

عنوان صفحات معنی دار را اضافه کنید

اگر صفحه یا نما تغییر کرد، می خواهید عنوان صفحه را به درستی مدیریت کنید. برای رفع این مشکل، از ویژگی Router.title داخلی Angular برای تعریف عناوین منحصر به فرد برای هر یک از صفحات خود استفاده می کنید.

  1. یک عنوان منحصر به فرد به هر یک از سه مسیر تعریف شده اضافه کنید:

src/app/app-routing.module.ts

const routes: Routes = [
  { path: 'shop', component: ShopComponent, title: 'Our Shop – a11y in Angular' },
  { path: 'about', component: AboutComponent, title: 'Our Story - a11y in Angular' },
  { path: 'locate', component: LocationComponent, title: 'Find Us - a11y in Angular' },
  { path: '',   redirectTo: '/shop', pathMatch: 'full' },
  { path: '**', component: ShopComponent },
];

این به طور خودکار Router's Title Service در زیر هود وارد کرده و از آن برای مدیریت تغییر عنوان صفحه در مسیریابی برای مطابقت با ویژگی عنوان تعریف شده در مسیرهای ما استفاده می کند. همچنین می توانید عناوین صفحات پیچیده تر را با استفاده از یک TitleStrategy سفارشی مدیریت کنید.

بررسی تغییرات

صفحه خوان خود را دوباره روشن کنید و تغییرات خود را تأیید کنید. اکنون صفحات باید عناوین منحصر به فرد داشته باشند!

مرورگر کروم با سه تب باز شده با عنوان صفحه منحصر به فرد: «فروشگاه ما - a11y در انگولار»، «داستان ما - a11y در انگولار»، «ما را پیدا کنید - a11y در انگولار»

ممیزی دسترسی:

  • تمامی صفحات دارای عناوین منحصربفرد هستند
  • 🛑 عناصر باید تضاد رنگی کافی داشته باشند
  • 🛑 HTML باید ترتیب، نام و نقش منطقی داشته باشد
  • 🛑 چک باکس های تودرتو برای صفحه خوان ها قابل انتخاب نیستند
  • 🛑 صفحه خوان مقادیر لغزنده را نمی خواند
  • 🛑 فوکوس صفحه خوان در انتخابگر رنگ از گفتگو خارج می شود
  • 🛑 تغییرات، خطاها و اعلان ها اعلام نمی شود
  • 🛑 حالت High Contrast فعال نیست

5. از کنتراست رنگ کافی اطمینان حاصل کنید

طراحی شما ممکن است جالب به نظر برسد، اما اینطور نیست که افراد دارای اختلالات بینایی مانند کوررنگی نتوانند محتوای شما را بخوانند. دستورالعمل‌های دسترسی به محتوای وب (WCAG 2.0) مجموعه‌ای از نسبت‌های کنتراست رنگ را تعریف می‌کنند که دسترسی به محتوا را تضمین می‌کند. در Angular و در وب، می‌توانید پالت‌های رنگی را تعریف کنید که اطمینان حاصل شود که اجزای شما با این استانداردها مطابقت دارند و برای کاربرانی با دید کم و کوررنگی قابل مشاهده هستند.

در پایان این بخش، برنامه شما ممیزی زیر را پشت سر می گذارد:

  • 🛑 عناصر باید تضاد رنگی کافی داشته باشند

شما می توانید هر یک از این مراحل را در نظرات پیدا کنید: TODO: #5. Ensure adequate color contrast.

از ابزارهای برنامه‌نویس Chrome برای شناسایی مشکلات کم کنتراست استفاده کنید

برای شناسایی این مشکل، از ابزارهای برنامه‌نویس Chrome برای بررسی عناصر موجود در برنامه خود استفاده کنید.

  1. از ابزار بازرسی برای مشاهده دکمه های نماد منو استفاده کنید. می توانید ببینید که کنتراست 1.85 است، بسیار کمتر از الزامات WCAG .

Chrome DevTools عنصر دکمه صفحه اصلی را با کنتراست کم بررسی می کند

  1. برای مشاهده این مشکلات نسبت کنتراست، ممیزی دسترسی را در اسکن Lighthouse یا تبر اجرا کنید.

نتایج بررسی Chrome DevTools Lighthouse با خطا: «رنگ‌های پس‌زمینه و پیش‌زمینه نسبت کنتراست کافی ندارند»

رنگ تم Material را تغییر دهید

طرح رنگ کامپوننت شما در تم متریال سفارشی شما تعریف شده است. شما ارزش طرح زمینه خود را به روز می کنید تا دستورالعمل های نسبت رنگ را رعایت کنید.

تم Material خود را به‌روزرسانی کنید تا از رنگ متن تیره‌تر استفاده کنید و نسبت کنتراست نمادهایتان را افزایش دهید:

src/styles.scss

$light-primary: mat.define-palette(mat.$pink-palette, $default: A100, $lighter: 100, $text: 900);

همچنین می‌توانید از ابزارهای دسترس‌پذیری داخلی Chrome Developer Tools برای پیدا کردن رنگی مطابق با استانداردها یا به‌روزرسانی مقادیر رنگ‌های فردی در Sass استفاده کنید.

بررسی تغییرات

عناصر خود را دوباره بررسی کنید و تغییرات خود را تأیید کنید، موضوع ما اکنون باید نسبت کنتراست رنگ کافی داشته باشد!

Chrome DevTools عنصر دکمه Home را با کنتراست کافی بررسی می کند

حسابرسی دسترسی

  • تمامی صفحات دارای عناوین منحصربفرد هستند
  • رنگ ها نسبت کنتراست کافی دارند
  • 🛑 HTML باید ترتیب، نام و نقش منطقی داشته باشد
  • 🛑 چک باکس های تودرتو برای صفحه خوان ها قابل انتخاب نیستند
  • 🛑 صفحه خوان مقادیر لغزنده را نمی خواند
  • 🛑 فوکوس صفحه خوان در انتخابگر رنگ از گفتگو خارج می شود
  • 🛑 تغییرات، خطاها و اعلان ها اعلام نمی شود
  • 🛑 حالت High Contrast فعال نیست

6. از Semantic HTML استفاده کنید

عناصر HTML بومی تعدادی از الگوهای تعامل استاندارد را که برای دسترسی مهم هستند، ثبت می‌کنند. در حالی که یک پاراگراف را می توان به عنوان یک span و یک div را می توان به عنوان یک دکمه استایل کرد، عنصر معنایی HTML تضمین می کند که خوانندگان صفحه و ناوبری صفحه کلید تعاملات و کنترل های HTML شما را درک می کنند.

هنگام نوشتن کامپوننت‌های Angular، باید در صورت امکان مستقیماً از این عناصر بومی دوباره استفاده کنید، نه اینکه رفتارهای پشتیبانی شده را دوباره پیاده‌سازی کنید. این تضمین می‌کند که صفحه دارای ساختار محتوایی خوب و جریان محتوای طبیعی است، و این برگه در یک نظم منطقی برای کمک به کاربران در جهت‌یابی وب‌سایت با استفاده مؤثر از صفحه کلید است.

در پایان این بخش، برنامه شما ممیزی زیر را پشت سر می گذارد:

  • 🛑 HTML باید ترتیب، نام و نقش منطقی داشته باشد

شما می توانید هر یک از این مراحل را در نظرات پیدا کنید: TODO: #6. Use Semantic HTML.

موضوع را شناسایی کنید

  1. VoiceOver را روشن کنید.
  2. از پیمایش برگه برای کلیک کردن به برگه داستان ما استفاده کنید.
  3. توجه داشته باشید که ترتیب برگه ها متوالی نیست.
  4. روی خریدهای الکترونیکی کلیک کنید.
  5. توجه داشته باشید که دکمه به عنوان یک دکمه شناخته نمی شود.

نتایج ممیزی Lighthouse Chrome DevTools با خطا: عناصر عنوان به ترتیب نزولی نیستند. سرفصل‌های مرتب شده به‌درستی که سطوح را رد نمی‌کنند، ساختار معنایی صفحه را منتقل می‌کنند و در هنگام استفاده از فناوری‌های کمکی، پیمایش و درک آن را آسان‌تر می‌کنند. بیشتر بدانید.

تغییر <div> به <button>

<div> سفارشی را با دکمه Material جایگزین کنید:

src/app/shop/shop.component.html

<button mat-flat-button 
  color="primary" 
  class="purchase-button"
  (click)="fauxPurchase()">
  Purchase
</button>

از عناصر عنوان به صورت متوالی استفاده کنید

ترتیب متن را برای استفاده از HTML معنایی تغییر دهید و با استفاده از تایپوگرافی Angular Material یک ظاهر طراحی کنید:

src/app/about/about.component.html

<h2>Who are we?</h2>
<p class="mat-subheading-2">Have you ever thought, "wow, I love dumplings"?</p>
<p class="right mat-subheading-1">Who hasn't.</p>
<p class="center mat-subheading-1">We took it one step further and created Dumpling Dumpling,</p> 
<p class="center mat-subheading-1">double the dumpling, double the fun.</p>
<div class="spacer"></div>
<h2>How are we different?</h2>
<p class="mat-subheading-2">Handmade in San Francisco, California, we craft fully customizable dumplings. Glitter? Rainbows? Vegan? We do it all.</p>
<p class="right mat-subheading-2">This shop is concept only.</p>

بررسی تغییرات

صفحه خوان خود را دوباره روشن کنید و تغییرات خود را تأیید کنید. VoiceOver اکنون دکمه را تشخیص می دهد و متن به ترتیب منطقی خوانده می شود!

ممیزی دسترسی:

  • تمامی صفحات دارای عناوین منحصربفرد هستند
  • رنگ ها نسبت کنتراست کافی دارند
  • HTML معنایی تعامل منطقی را تضمین می کند
  • 🛑 چک باکس های تودرتو برای صفحه خوان ها قابل انتخاب نیستند
  • 🛑 صفحه خوان مقادیر لغزنده را نمی خواند
  • 🛑 فوکوس صفحه خوان در انتخابگر رنگ از گفتگو خارج می شود
  • 🛑 تغییرات، خطاها و اعلان ها اعلام نمی شود
  • 🛑 حالت High Contrast فعال نیست

7. کنترل های قابل انتخاب را با Angular Material ایجاد کنید

یک الگوی تعامل پیچیده برای خدمات دسترسی، کنترل‌های تودرتو است. به موارد فرعی منو یا چک باکس های تودرتو فکر کنید. چگونه به کاربر نشان می‌دهید که می‌توانید زیر گروهی از گزینه‌ها را انتخاب کنید یا به یک آیتم منوی والد بروید؟

در Angular، منوها و کنترل ها را برای ایجاد اجزای قابل پیمایش با ساده کردن کنترل ها تا حد امکان، ساده کنید. در این مثال، شما از لیست باکس Angular Material برای ساختن نمونه ای از این الگوی تعامل استفاده می کنید.

در پایان این بخش، برنامه شما ممیزی زیر را پشت سر می گذارد:

  • 🛑 چک باکس های تودرتو برای صفحه خوان ها قابل انتخاب نیستند

شما می توانید هر یک از این مراحل را در نظرات پیدا کنید: TODO: #7. Create selectable controls with Angular Material.

موضوع را شناسایی کنید

برای شناسایی این مشکل، صفحه خوان خود را روشن می کنیم و سعی می کنیم یک چک باکس تودرتو را انتخاب کنیم.

  1. VoiceOver را روشن کنید.
  2. طعم های پرکننده مختلف را انتخاب کنید.
  3. توجه داشته باشید که چک باکس های والدین هنگام خواندن توسط VoiceOver فرزندان را مشخص نمی کنند. اکنون که چک باکس Bok Choy را لغو انتخاب کرده اید، چگونه می دانید که چک باکس Vegan لغو انتخاب شده است؟

منوی کادر انتخاب پر کردن با گزینه‌ها: پر کردن وگان بوک چوی توفو و گوشت شیتاکه گوشت مرغ غیرممکن

A11y در مواد زاویه ای

شما چک باکس معنایی را با چک باکس Angular Material جایگزین می کنید که حاوی دانش داخلی این الگوی تعامل است. توجه به این نکته مهم است که جایگزینی اجزا با Material تضمینی برای دسترسی نیست. مانند هر مؤلفه دیگری، شما باید به صورت دستی آزمایش کنید زیرا راه های زیادی برای پیاده سازی مواد به صورت غیرقابل دسترس وجود دارد.

چک باکس ها را با چک باکس های Material جایگزین کنید

  1. ابتدا لیست جدید پرکننده ها و یک متغیر برای ذخیره طعم های پرکننده انتخابی خود اضافه کنید:

src/app/shop/shop.component.ts

@Component(...)
export class ShopComponent implements OnInit {
  fillings: string[] = ['Bok Choy & Chili Crunch', 'Tofu & Mushroom', 'Chicken & Ginger', 'Impossible Meat & Spinach'];
  selectedFillings: string[] = [];

  fauxPurchase(): void {
    let flavor = '';
    this.selectedFillings.forEach(filling => {
      flavor = flavor + " " + filling
    })
  }
}
  1. یک <mat-selection-list> برای جایگزینی این دسته بندی نامرتب چک باکس های HTML اضافه کنید:

src/app/shop/shop.component.html

<mat-selection-list [(ngModel)]="selectedFillings" 
  aria-label="Dumpling fillings">
  <mat-list-option *ngFor="let flavor of fillings" 
    [value]="flavor" 
    color="primary">
    {{ flavor }}
  </mat-list-option>
</mat-selection-list>

نظرات TODO شما همچنین نشان می دهد که در کجا می توانید برخی از Sass استفاده نشده را در src/app/shop/shop.component.scss حذف کنید تا استایل خود را تمیز کنید.

بررسی تغییرات

صفحه خوان خود را دوباره روشن کنید و تغییرات خود را تأیید کنید. چک باکس های شما اکنون قابل انتخاب هستند و با یک صفحه خوان به طور مستقیم تر پیمایش می شوند!

منوی چک باکس پر کردن با موارد: فیلینگ بوک چوی و چیلی کرانچ توفو و قارچ مرغ و زنجبیل غیرممکن است گوشت و اسفناج

ممیزی دسترسی:

  • تمامی صفحات دارای عناوین منحصربفرد هستند
  • رنگ ها نسبت کنتراست کافی دارند
  • HTML معنایی تعامل منطقی را تضمین می کند
  • همه کنترل ها توسط صفحه خوان ها قابل دسترسی هستند
  • 🛑 صفحه خوان مقادیر لغزنده را نمی خواند
  • 🛑 فوکوس صفحه خوان در انتخابگر رنگ از گفتگو خارج می شود
  • 🛑 تغییرات، خطاها و اعلان ها اعلام نمی شود
  • 🛑 حالت High Contrast فعال نیست

8. برچسب های کنترلی با ARIA ارائه دهید

شما مؤلفه‌های معنایی HTML و Material برنامه Angular خود را تغییر دادید، اما برخی از مؤلفه‌ها به ویژگی‌های خاصی نیاز دارند تا به طور کامل توسط صفحه‌خوان‌ها پیمایش شوند.

مشخصات برنامه های کاربردی اینترنت غنی قابل دسترسی (WAI-ARIA یا ARIA) ابتکار دسترسی به وب، به رفع مشکلاتی که نمی توان با HTML بومی مدیریت کرد کمک می کند. به شما امکان می دهد ویژگی هایی را مشخص کنید که نحوه ترجمه یک عنصر به درخت دسترسی را تغییر می دهند.

در پایان این بخش، برنامه شما ممیزی زیر را پشت سر می گذارد:

  • 🛑 صفحه خوان مقادیر لغزنده را نمی خواند

شما می توانید هر یک از این مراحل را در نظرات پیدا کنید: TODO: #8. Provide control labels with ARIA.

موضوع را شناسایی کنید

برای شناسایی این مشکل، صفحه خوان خود را روشن کنید و نوار لغزنده خود را حرکت دهید:

  1. VoiceOver را روشن کنید.
  2. به نوار لغزنده مقدار بروید و مقدار را تغییر دهید.
  3. توجه داشته باشید که برچسب مقدار وجود ندارد.

نتایج ممیزی Lighthouse Chrome DevTools با خطا: فیلدهای ورودی ARIA نام قابل دسترسی ندارند وقتی یک فیلد ورودی نام قابل دسترسی ندارد، صفحه‌خوان‌ها آن را با یک نام عمومی اعلام می‌کنند و برای کاربرانی که به صفحه‌خوان‌ها متکی هستند غیرقابل استفاده می‌شود. بیشتر بدانید.

از ویژگی های ARIA استفاده کنید

کنترل برچسب با استفاده از aria-label به <mat-slider> :

src/app/shop/shop.component.html

<mat-slider
  aria-label="Dumpling order quantity slider"
  id="quantity"
  name="quantity"
  color="primary"
  class="quantity-slider"
  [max]="13"
  [min]="1"
  [step]="1"
  [tickInterval]="1"
  thumbLabel
  [(ngModel)]="quantity">
</mat-slider>

بررسی تغییرات

صفحه خوان خود را دوباره روشن کنید و تغییرات خود را تأیید کنید. اکنون می توانید نوار لغزنده را حرکت دهید!

بازرسی Lighthouse Chrome DevTools با ممیزی گذرا برای کنترل‌های ARIA صفحه‌خوان.

ممیزی دسترسی:

  • تمامی صفحات دارای عناوین منحصربفرد هستند
  • رنگ ها نسبت کنتراست کافی دارند
  • HTML معنایی تعامل منطقی را تضمین می کند
  • همه کنترل ها توسط صفحه خوان ها قابل دسترسی هستند
  • اسلایدر از ویژگی های ARIA برای ارائه یک برچسب استفاده می کند
  • 🛑 فوکوس صفحه خوان در انتخابگر رنگ از گفتگو خارج می شود
  • 🛑 تغییرات، خطاها و اعلان ها اعلام نمی شود
  • 🛑 حالت High Contrast فعال نیست

9. قدرت @angular/cdk/a11y را اضافه کنید

تا به حال، برای رفع مشکلات رایج a11y به ابزار Angular داخلی متکی بوده اید. حال، بیایید به ماژول a11y CDK و اینکه چگونه می‌تواند به ما در حل مسائل پیچیده‌تر و مختص Angular کمک کند، نگاهی بیاندازیم.

در پایان این بخش، این دوره را با ابزار Angular a11y ماژول ادامه خواهید داد.

شما می توانید این مراحل را زیر نظر پیدا کنید: TODO: #9. Add the power of @angular/cdk/a11y.

ماژول را وارد کنید

ماژول را به برنامه خود اضافه کنید:

src/app/app.module.ts

import { A11yModule } from '@angular/cdk/a11y';

@NgModule({
  declarations: [...],
  imports: [
    A11yModule
  ],
  providers: [...],
  bootstrap: [...]
})

'@angular/cdk/a11y' چه کاری انجام می‌دهد؟

ماژول a11y تعدادی ابزار برای بهبود دسترسی فراهم می کند و به طور خاص برای نویسندگان مؤلفه مفید است.

در بخش‌های زیر، سه سرویس رایج را اضافه می‌کنید: FocusTrap، LiveAnnouncer و HighContrast.

برای اطلاعات بیشتر در مورد سایر خدماتی که @angular/cdk/a11y ارائه می‌کند، به قابلیت دسترسی مراجعه کنید.

10. فوکوس را با FocusTrap کنترل کنید

وقتی یک گفتگو یا مدال باز است، کاربر فقط در داخل آن تعامل دارد. اجازه دادن به فوکوس خارج از گفتگو، زمینه ها را مخلوط می کند و حالتی را ایجاد می کند که کاربر نمی داند در کجای صفحه قرار دارد.

در Angular، دستور cdkTrapFocus تمرکز کلید tab- را در یک عنصر به دام می اندازد. این در نظر گرفته شده است که برای ایجاد تجربه قابل دسترسی برای مؤلفه‌هایی مانند دیالوگ‌های مدال، که در آن تمرکز باید محدود شود، استفاده شود.

در پایان این بخش، برنامه شما ممیزی زیر را پشت سر می گذارد:

  • 🛑 فوکوس صفحه خوان در انتخابگر رنگ از گفتگو خارج می شود

شما می توانید این مراحل را در نظرات پیدا کنید: TODO: #10. Control focus with FocusTrap.

موضوع را شناسایی کنید

برای شناسایی این مشکل، صفحه خوان خود را روشن کنید و کادر گفتگوی انتخابگر رنگ را باز کنید.

  1. VoiceOver را روشن کنید.
  2. برای تغییر رنگ از پیمایش تب استفاده کنید.
  3. برای مشاهده ترتیب فوکوس بصری و به دام انداختن فوکوس در انتخابگر رنگ، علامت بزنید.

وب سایت فروشگاه Dumpling Time با تم بنفش و سبز با گفتگوی باز برای انتخاب رنگ بسته بندی پیراشکی

FocusTrap را اضافه کنید

cdkFocusTrap می توان برای به دام انداختن و کنترل ترتیب فوکوس در اجزای سفارشی استفاده کرد. استفاده از mat-dialog-content برای حل اکثر مسائل با به دام انداختن تمرکز در یک گفتگو کافی است. ویژگی cdkFocusInitial را اضافه کنید تا منطقه فوکوس اولیه را روی رنگ بسته بندی دامپلینگ <mat-selection-list> در گفتگوی انتخابگر رنگ تعریف کنید.

src/app/shop/color-picker/color-picker-dialog/color-picker-dialog.component.html

<mat-selection-list #colors aria-label="Dumpling wrapper color" multiple="false" cdkFocusInitial>
  ...
</mat-selection-list>

بررسی تغییرات

صفحه خوان خود را دوباره روشن کنید و تغییرات خود را تأیید کنید. اکنون فوکوس در ابتدا روی تغییر رنگ در گفتگو تنظیم شده است!

ممیزی دسترسی:

  • تمامی صفحات دارای عناوین منحصربفرد هستند
  • رنگ ها نسبت کنتراست کافی دارند
  • HTML معنایی تعامل منطقی را تضمین می کند
  • همه کنترل ها توسط صفحه خوان ها قابل دسترسی هستند
  • اسلایدر از ویژگی های ARIA برای ارائه یک برچسب استفاده می کند
  • انتخابگر رنگ فوکوس درستی دارد
  • 🛑 تغییرات، خطاها و اعلان ها اعلام نمی شود
  • 🛑 حالت High Contrast فعال نیست

11. تغییرات را با LiveAnnouncer اعلام کنید

هنگامی که چیزی در صفحه تغییر می کند، صفحه خوان ها باید مطلع شوند. تصور کنید که سعی می‌کنید یک فرم ارسال کنید یا یک خرید را تکمیل کنید، و ندانید که خطایی ظاهر شده است که مانع از ارسال فرم شده است. این ناامید کننده است!

LiveAnnouncer برای اعلام پیام‌ها برای کاربران صفحه‌خوان استفاده می‌شود که از منطقه aria-live استفاده می‌کنند تا اطمینان حاصل شود که خوانندگان صفحه از اعلان‌ها و تغییرات صفحه زنده مطلع می‌شوند. برای اطلاعات بیشتر در مورد مناطق زنده آریا، WAI-ARIA W3C را ببینید. در انگولار، فراخوانی LiveAnuncher به عنوان یک سرویس راه حلی قابل آزمایش تر از ویژگی های aria-live است.

در پایان این بخش، برنامه شما ممیزی زیر را پشت سر می گذارد:

  • 🛑 تغییرات، خطاها و اعلان ها اعلام نمی شود

شما می توانید این مراحل را در نظرات پیدا کنید: TODO: #11. Announce changes with LiveAnnouncer.

موضوع را شناسایی کنید

برای شناسایی این مشکل، صفحه خوان خود را روشن کنید و بدون تکمیل فیلدهای فرم، خرید را انتخاب کنید:

  1. VoiceOver را روشن کنید.
  2. برای تغییر رنگ و خرید جعلی از پیمایش تب استفاده کنید.
  3. توجه داشته باشید که هیچ نشانه ای از رنگ انتخاب شده در هنگام خروج از گفتگو وجود ندارد و خرید خوانده نمی شود.

وب سایت فروشگاه دامپلینگ تایم با تم صورتی و قرمز با گفتگوی باز برای انتخاب رنگ بسته بندی پیراشکی

LiveAnnouncer را به کد خود اضافه کنید

LiveAnnouncer را اضافه کنید و انتخاب رنگ و خرید جعلی را به صورت رشته ای اعلام کنید. در یک پیاده سازی واقعی، این ممکن است زمانی خوانده شود که به یک سیستم پرداخت شخص ثالث یا برای خطاهای فرم بروید.

  1. وقتی رنگی انتخاب می شود، اعلامیه اضافه کنید:

src/app/shop/color-picker/color-picker-dialog/color-picker-dialog.component.ts

import { LiveAnnouncer } from '@angular/cdk/a11y';

@Component(...)
export class ColorPickerDialogComponent implements OnInit {
  constructor(
    public dialogRef: MatDialogRef<ColorPickerDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: ColorDialogData,
    private liveAnnouncer: LiveAnnouncer) { }

  public changeColor(color: string): void {
    this.liveAnnouncer.announce(`Select color: ${color}`);
    this.dialogRef.close();
  }
}
  1. هنگام خرید جعلی اعلامیه اضافه کنید:

src/app/shop/shop.component.ts

import { LiveAnnouncer } from '@angular/cdk/a11y';

@Component(...)
export class ShopComponent implements OnInit {

  constructor(private liveAnnouncer: LiveAnnouncer) { }

  fauxPurchase(): void {
    let flavor = '...';
    const fakePurchase = `Purchase ${this.quantity} ${flavor}dumplings in the color ${this.color}!`;

    this.liveAnnouncer.announce(fakePurchase);
  }
}

بررسی تغییرات

صفحه خوان خود را دوباره روشن کنید و تغییرات خود را تأیید کنید. اکنون از خطاهای خود مطلع شده اید!

ممیزی دسترسی:

  • تمامی صفحات دارای عنوان صفحات منحصربفرد هستند
  • رنگ ها نسبت کنتراست کافی دارند
  • HTML معنایی تعامل منطقی را تضمین می کند
  • همه کنترل ها توسط صفحه خوان ها قابل دسترسی هستند
  • اسلایدر از ویژگی های ARIA برای ارائه یک برچسب استفاده می کند
  • انتخابگر رنگ فوکوس درستی دارد
  • تغییرات، خطاها و اطلاعیه ها اعلام می شود
  • 🛑 حالت High Contrast فعال نیست

12. حالت High Contrast را فعال کنید

مایکروسافت ویندوز از یک ویژگی دسترسی به نام حالت کنتراست بالا پشتیبانی می کند. این حالت ظاهر همه برنامه ها از جمله برنامه های وب را تغییر می دهد تا کنتراست را به شدت افزایش دهد. در Angular، شما می خواهید به ترجیحات کاربر در برنامه خود احترام بگذارید.

HighContrastModeDetector به شما امکان می دهد تعیین کنید که آیا مرورگر در حال حاضر در یک محیط با حالت کنتراست بالا قرار دارد یا خیر.

Internet Explorer، Microsoft Edge و Firefox از این حالت پشتیبانی می کنند. Google Chrome از حالت کنتراست بالا ویندوز پشتیبانی نمی کند. این سرویس حالت کنتراست بالا را که توسط افزونه مرورگر کروم با کنتراست بالا اضافه شده است شناسایی نمی کند.

در پایان این بخش، برنامه شما ممیزی زیر را پشت سر می گذارد:

  • 🛑 حالت High Contrast فعال نیست

شما می توانید این مراحل را در نظرات پیدا کنید: TODO: #12. Enable HighContrast mode.

موضوع را شناسایی کنید

برای شناسایی این مشکل، برنامه خود را در اینترنت اکسپلورر، مایکروسافت اج یا فایرفاکس باز کنید، حالت کنتراست بالا را روشن کنید و عدم تغییر را مشاهده کنید:

  1. برنامه خود را در Internet Explorer، Microsoft Edge یا Firefox باز کنید.
  2. حالت کنتراست بالا را روشن کنید.
  3. توجه داشته باشید که برنامه بدون تغییر است.

پشتیبانی از حالت کنتراست بالا را اضافه کنید

در styles.scss ، از ترکیب cdk-high-contrast ارائه شده در @angular/cdk/a11y استفاده کنید تا یک طرح کلی به دکمه های خود در حالت کنتراست بالا اضافه کنید:

src/app/shop/shop.component.scss

@use '@angular/cdk';

.purchase-button {
    border-radius: 5px;
    background-color: mat.get-color-from-palette(mat.$pink-palette, A100);

    @include cdk-high-contrast {
      outline: solid 1px;
      background-color: mat.get-color-from-palette(mat.$pink-palette, 50);
    }
}

:host-context(.dark-theme) {
  .purchase-button {
    background-color: mat.get-color-from-palette(mat.$light-green-palette, A100);

    @include cdk-high-contrast {
      outline: solid 1px;
      background-color: mat.get-color-from-palette(mat.$light-green-palette, 50);
    }
  }
}

بررسی تغییرات

برنامه خود را بازخوانی کنید و تغییرات خود را تأیید کنید. شما یک طرح کلی به دکمه در حالت کنتراست بالا اضافه کردید!

وب سایت فروشگاه Dumpling Time با تم قرمز و صورتی با حالت کنتراست بالا روشن است و دکمه خرید اکنون به شدت با طرح کلی قرمز ضخیم متمرکز شده است.وب سایت فروشگاه Dumpling Time در تم آبی و سبز با حالت کنتراست بالا روشن و دکمه خرید اکنون به شدت با طرح کلی آبی ضخیم متمرکز شده است.

ممیزی دسترسی:

  • تمامی صفحات دارای عناوین منحصربفرد هستند
  • رنگ ها نسبت کنتراست کافی دارند
  • HTML معنایی تعامل منطقی را تضمین می کند
  • همه کنترل ها توسط صفحه خوان ها قابل دسترسی هستند
  • اسلایدر از ویژگی های ARIA برای ارائه یک برچسب استفاده می کند
  • انتخابگر رنگ فوکوس درستی دارد
  • تغییرات، خطاها و اطلاعیه ها اعلام می شود
  • حالت کنتراست بالا فعال است

13. تبریک می گویم!

تبریک می‌گوییم، شما به مشکلات رایج دسترسی به وب در برنامه Angular خود پرداختید! 🎉

برای مشاهده همه راه حل ها، شعبه main را بررسی کنید.

وب سایت Dumpling Time shop با تم قرمز و صورتی تمامی تغییرات ایجاد شده در این کدلب را نشان می دهدوب سایت فروشگاه Dumpling Time با تم آبی و سبز تمام تغییرات ایجاد شده در این کد لبه را نشان می دهدChrome DevTools Lighthouse ممیزی با امتیاز 100/100

اکنون مراحل کلیدی مورد نیاز برای حل هشت مشکل رایج a11y در برنامه Angular خود را می دانید.

بیشتر بدانید

این کدها را بررسی کنید:

این مطالب را بخوانید: