۱. قبل از شروع

دسترسیپذیری بخش حیاتی توسعه وب است و تضمین میکند که کاربران میتوانند برنامهها را درک، فهم، پیمایش و تعامل کنند. در واقع، از هر ۴ بزرگسال آمریکایی، ۱ نفر دارای معلولیتی است که بر فعالیتهای اصلی زندگی او تأثیر میگذارد. در سراسر جهان، حدود ۱۵ درصد از جمعیت جهان - بیش از ۱ میلیارد نفر - نوعی معلولیت دارند و حدود ۲ تا ۴ درصد از آنها مشکلات قابل توجهی را تجربه میکنند.
شرایط رایجی که بر استفاده فرد از وب تأثیر میگذارند شامل نابینایی یا کمبینایی، ناشنوایی یا اختلال شنوایی، مهارتهای حرکتی محدود، ناتوانیهای شناختی و کوررنگی است - و این فقط یک لیست جزئی است.
در این دوره، a11y مخفف accessibility (دسترسیپذیری) است. توجه داشته باشید که بعد از a، 11 کاراکتر و بعد از a y میآید.
برای آشنایی عمیق با مسائل و تکنیکهای طراحی برنامههای کاربردیِ دسترسپذیر، به بخش دسترسیپذیری مراجعه کنید.
آنچه خواهید ساخت
- از بهترین شیوهها و تکنیکهای داخلی برای رسیدگی به مشکلات رایج دسترسی به وب در یک نسخه آزمایشی از برنامه Angular Dumpling Shop استفاده کنید.
- تمام دستورالعملهای دسترسیپذیری، WCAG 2.0 و ARIA 1.2 را رعایت کنید و ممیزیهای دسترسیپذیری axe و Lighthouse را با موفقیت پشت سر بگذارید.


آنچه یاد خواهید گرفت
شما در مورد هشت مشکل رایج در دسترسیپذیری در برنامههای Angular که کاربران را تحت تأثیر قرار میدهند، نحوه شناسایی آنها و نحوه رفع آنها یاد میگیرید. به طور خاص، شما:
- از ابزارهای توسعهدهندگان گوگل کروم، Lighthouse و axe برای بررسی دسترسیپذیری برنامه خود استفاده کنید
- مشکلات اپلیکیشنهای تکصفحهای (SPA) را با عناوین منحصر به فرد برای صفحات حل کنید
- رفع مشکلات کنتراست رنگ پایین برای کاربران کمبینا
- از HTML معنایی استفاده کنید تا مطمئن شوید خوانندگان صفحه به درستی در صفحه حرکت میکنند.
- از Angular Material و کنترلهای unnest استفاده کنید تا مطمئن شوید که خوانندگان صفحه نمایش میتوانند به همه کنترلها دسترسی داشته باشند.
- پشتیبانی ARIA را برای خوانندگان صفحه اضافه کنید
- بستهی Angular CDK a11y را وارد کرده و از آن استفاده کنید
- استفاده از FocusTrap برای پیمایش صفحهخوان کامپوننت سفارشی
- اعلانها را با CDK LiveAnnouncer اعلام کنید
- شناسایی کاربران با حالت HighContrast و پیادهسازی تمبندی با کنتراست بالا
آنچه نیاز دارید
- آشنایی با Angular، SCSS، Typescript، git و ابزارهای توسعهدهندگان Chrome
۲. آماده شوید
کد را دریافت کنید
هر چیزی که برای این پروژه نیاز دارید در مخزن گیتهاب موجود است. برای شروع، کد را کپی کرده و آن را در محیط توسعه مورد علاقه خود باز کنید.
مخزن را کلون کنید و برنامه را اجرا کنید
VSCode یا یک IDE محلی روش پیشنهادی برای کار با این codelab است.
- یک تب جدید در مرورگر باز کنید و به آدرس https://github.com/googlecodelabs/angular-accessibility بروید.
- مخزن را منشعب و کلون کنید، و
cd angular-accessibility/آن را به مخزن منتقل کنید. - کد آغازین شاخه
git checkout get-startedرا بررسی کنید. - کد را در VSCode یا IDE مورد نظر خود باز کنید.
- برای نصب وابستگیهای مورد نیاز برای اجرای سرور،
npm installاجرا کنید. - برای اجرای سرور
ng serveرا اجرا کنید. - یک تب مرورگر را باز کنید و به آدرس http://localhost:4200 بروید.
۳. یک خط پایه ایجاد کنید
نقطه شروع شما چیست؟
نقطه شروع شما یک اپلیکیشن رستوران ساده است که برای این آزمایشگاه کد طراحی شده است. کد برای نمایش مفاهیم در این آزمایشگاه کد ساده شده است و قابلیتهای کمی دارد.

نسخه آزمایشی را کاوش کنید
برای شروع، سه قابلیت برنامه خود را بررسی کنید:
- از نوار ناوبری برای مشاهده مسیرهای «فروشگاه ما» ، «داستان ما » و «ما را پیدا کنید» استفاده کنید و جزئیات مربوط به شرکت دامپینگ را ببینید.
- برای تغییر حالت روشن و تاریک، تمها را تغییر دهید.
- مواد داخل پیراشکی، مقدار و رنگ آن را به دلخواه خود سفارشی کنید.
- برای ثبت سفارش سفارشی خود در کنسول، گزینه خرید را انتخاب کنید.
استفاده از Angular برای رسیدگی به مشکلات رایج دسترسی به وب
در این آزمایشگاه کد، شما بر روی دسترسیپذیری ویژگیهای موجود این برنامه تمرکز میکنید. شما با شناسایی مشکلات ۱۱ گانه در برنامه خود شروع خواهید کرد، سپس با پیادهسازی یک راهحل، 🛑 را به ✅ تبدیل خواهید کرد.
از کجا میفهمی چی رو باید درست کنی؟
هر مثال را با تشخیص مشکل دسترسیپذیری با استفاده از ترکیبی از تست دستی و خودکار شروع کنید.
در وضعیت فعلی وب، آزمایش دستی دسترسیپذیری الزامی است.
شما ابزارهایی دارید که میتوانند مشکلات دسترسیپذیری را شناسایی کنند، اما هیچ ابزاری نمیتواند تأیید کند که یک برنامه کاملاً قابل دسترس است. تست دستی تضمین میکند که شما طیف وسیعی از مفاهیم a11y را که شامل ترتیب منطقی محتوا و برابری ویژگیها میشود، آزمایش میکنید.
تست دستی
برای آزمایش دستی دسترسیپذیری در این دوره، صفحهخوان داخلی رایانه ما را روشن میکنید و با استفاده از صفحهکلید در برنامه خود پیمایش میکنید. برای اطلاعات بیشتر، به بخش معناشناسی و صفحهخوانها مراجعه کنید.
با روشن کردن صفحهخوان و پیمایش صفحه تمرین کنید.
میتوانید از قابلیت VoiceOver داخلی مکاواس استفاده کنید. برای فعال کردن آن، روی System Preferences > Accessibility > VoiceOver > Enable VoiceOver کلیک کنید. برای فعال کردن VoiceOver، در حالی که کلید Command نگه داشتهاید، سه بار سریع TouchID را فشار دهید.
در این دوره، شما در درجه اول مسائل را به صورت دستی آزمایش میکنید و از ابزارهای خودکار برای کمک به بررسی ویژگیهای خاص قابل خودکارسازی استفاده میکنید.
تست خودکار
شما همچنین از چند ابزار توسعه برای خودکارسازی و بررسی برنامه خود استفاده میکنید. این ابزارها به شما امکان میدهند مواردی مانند وجود متن جایگزین (alt text) روی یک تصویر یا نسبت کنتراست رنگ متن را بررسی کنید. میتوانید این ابزارها را به عنوان linter در نظر بگیرید؛ آنها میتوانند تشخیص دهند که متن جایگزین وجود دارد، اما شما باید به صورت دستی بررسی کنید که محتوا منطقی است و ارزش ارائه میدهد.
ابزارهای توسعهدهنده لایتهاوس و کروم
- ابزارهای توسعهدهنده کروم را باز کنید.
- برگه Lighthouse را انتخاب کنید و کادر انتخاب Accessibility را علامت بزنید.
- برای اجرای یک ممیزی a11y Lighthouse، روی «ایجاد گزارش» کلیک کنید.

تبر
- افزونهی axe DevTools را نصب کنید. برای مشاهدهی افزونه، ممکن است لازم باشد مرورگر خود را مجدداً راهاندازی کنید.
- ابزارهای توسعهدهنده کروم را باز کنید.
- تب axe DevTools را انتخاب کنید و برای اجرای اسکن axe DevTools، گزینه Scan all of my page را انتخاب کنید.
آسترکاری
شما میتوانید از قوانین ESLint در Angular برای Lint کردن کد خود برای ویژگیهای 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 و axe audits و VoiceOver دستی شناسایی کنید:

ممیزی دسترسیپذیری:
- 🛑 همه صفحات عنوان صفحه یکسانی دارند
- 🛑 عناصر باید تضاد رنگی کافی داشته باشند
- 🛑 HTML باید ترتیب، نام و نقش منطقی داشته باشد
- 🛑 کادرهای انتخاب تو در تو برای صفحهخوانها قابل انتخاب نیستند.
- 🛑 صفحهخوان مقادیر اسلایدر را نمیخواند
- 🛑 فوکوس صفحهخوان در انتخابگر رنگ از پنجره خارج میشود
- 🛑 تغییرات، خطاها و اعلانها اعلام نمیشوند
- 🛑 حالت کنتراست بالا فعال نیست
۴. عناوین صفحه منحصر به فرد را تعریف کنید
ارائه عناوین منحصر به فرد و مختصر برای صفحات، به کاربرانی که از خدمات a11y استفاده میکنند، کمک میکند تا به سرعت محتوا و هدف یک صفحه وب را درک کنند. عناوین صفحه برای کاربران دارای معلولیت بینایی بسیار مهم هستند زیرا آنها اولین عنصر صفحه هستند که توسط نرمافزارهای خواندن صفحه نمایش اعلام میشوند.
انگولار یک برنامه تک صفحهای است و در نتیجه، اکثر انتقالها، مانند انتقال به صفحه جدید، شامل بارگذاری مجدد صفحه نمیشوند. تا همین اواخر، این بدان معنا بود که هر صفحه یک عنوان صفحه یکسان داشت و هیچ ارزشی برای درک محتوا یا هدف صفحه ارائه نمیکرد.
در Angular v14، Router یک متد داخلی برای تعریف عناوین منحصر به فرد صفحات به صورت آماده اضافه کرد. این یک رویکرد ساده برای اطمینان از پیروی توسعهدهندگان از بهترین شیوههای عنوان صفحه ارائه میدهد.
در پایان این بخش، برنامه شما ممیزی زیر را با موفقیت پشت سر خواهد گذاشت:
- 🛑 همه صفحات عنوان صفحه یکسانی دارند
میتوانید هر یک از این مراحل را در زیر کامنت پیدا کنید: TODO: #4. Define unique page titles.
مسئله را مشخص کنید
برای شناسایی این مشکل، صفحهخوان خود را روشن کنید و بین برگههای «فروشگاه ما» ، «داستان ما» و «یافتن ما» حرکت کنید تا عناوین صفحه را ببینید:
- ویس اوور (VoiceOver) را روشن کنید.
- برای حرکت بین صفحات از نوار ناوبری استفاده کنید.
- مطمئن شوید که عنوان صفحه در Angular همیشه a11y است.
این یک مشکل است زیرا عنوان صفحه شما باید منحصر به فرد باشد تا کاربر بتواند بدون نیاز به پیمایش در آن، به سرعت بفهمد که صفحه در مورد چیست.

عناوین صفحه معنادار اضافه کنید
اگر یک صفحه یا نما تغییر کند، میخواهید عنوان صفحه را به درستی مدیریت کنید. برای رفع این مشکل، از ویژگی داخلی Router.title در Angular برای تعریف عناوین منحصر به فرد برای هر یک از صفحات خود استفاده میکنید.
- به هر یک از سه مسیر تعریف شده، یک عنوان منحصر به فرد اضافه کنید:
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 سفارشی مدیریت کنید.
تأیید تغییرات
دوباره صفحهخوان خود را روشن کنید و تغییرات خود را تأیید کنید. اکنون صفحات باید عناوین منحصر به فردی داشته باشند!

ممیزی دسترسیپذیری:
- ✅ همه صفحات دارای عناوین منحصر به فرد هستند
- 🛑 عناصر باید تضاد رنگی کافی داشته باشند
- 🛑 HTML باید ترتیب، نام و نقش منطقی داشته باشد
- 🛑 کادرهای انتخاب تو در تو برای صفحهخوانها قابل انتخاب نیستند.
- 🛑 صفحهخوان مقادیر اسلایدر را نمیخواند
- 🛑 فوکوس صفحهخوان در انتخابگر رنگ از پنجره خارج میشود
- 🛑 تغییرات، خطاها و اعلانها اعلام نمیشوند
- 🛑 حالت کنتراست بالا فعال نیست
۵. از کنتراست رنگی کافی اطمینان حاصل کنید
طراحی شما ممکن است جالب به نظر برسد، اما اگر افرادی با اختلالات بینایی مانند کوررنگی نتوانند محتوای شما را بخوانند، اینطور نیست. دستورالعملهای دسترسی به محتوای وب (WCAG 2.0) مجموعهای از نسبتهای کنتراست رنگ را تعریف میکنند که دسترسی به محتوا را تضمین میکنند. در Angular و در وب، میتوانید پالتهای رنگی را تعریف کنید که تضمین میکند اجزای شما این استانداردها را رعایت میکنند و برای کاربران کمبینا و کوررنگ قابل مشاهده هستند.
در پایان این بخش، برنامه شما ممیزی زیر را با موفقیت پشت سر خواهد گذاشت:
- 🛑 عناصر باید تضاد رنگی کافی داشته باشند
میتوانید هر یک از این مراحل را در قسمت نظرات پیدا کنید: TODO: #5. Ensure adequate color contrast.
از ابزارهای توسعهدهنده کروم برای شناسایی مشکلات کنتراست پایین استفاده کنید
برای شناسایی این مشکل، از ابزارهای توسعهدهنده کروم برای بررسی عناصر برنامه خود استفاده کنید.
- از ابزار inspect برای مشاهده دکمههای آیکون منو استفاده کنید. میتوانید ببینید که کنتراست ۱.۸۵ است که بسیار پایینتر از الزامات WCAG است.

- برای مشاهده این مشکلات نسبت کنتراست، Accessibility audit را در Lighthouse یا axe's scan اجرا کنید.

تغییر رنگ تم متریال
طرح رنگ کامپوننت شما در تم متریال سفارشی شما تعریف میشود. شما مقدار تم خود را برای مطابقت با دستورالعملهای نسبت کنتراست رنگ بهروزرسانی میکنید.
تم متریال خود را بهروزرسانی کنید تا از رنگ متن تیرهتری استفاده کند و نسبت کنتراست آیکونهای خود را افزایش دهد:
src/styles.scss
$light-primary: mat.define-palette(mat.$pink-palette, $default: A100, $lighter: 100, $text: 900);
همچنین میتوانید از ابزار دسترسی داخلی Chrome Developer Tools برای یافتن رنگی که مطابق با استانداردها است یا بهروزرسانی مقادیر رنگهای منفرد در Sass استفاده کنید.
تأیید تغییرات
دوباره عناصر خود را بررسی کنید و تغییرات خود را تأیید کنید، قالب ما اکنون باید نسبت کنتراست رنگ کافی داشته باشد!

حسابرسی دسترسیپذیری
- ✅ همه صفحات دارای عناوین منحصر به فرد هستند
- ✅ رنگها نسبت کنتراست کافی دارند
- 🛑 HTML باید ترتیب، نام و نقش منطقی داشته باشد
- 🛑 کادرهای انتخاب تو در تو برای صفحهخوانها قابل انتخاب نیستند.
- 🛑 صفحهخوان مقادیر اسلایدر را نمیخواند
- 🛑 فوکوس صفحهخوان در انتخابگر رنگ از پنجره خارج میشود
- 🛑 تغییرات، خطاها و اعلانها اعلام نمیشوند
- 🛑 حالت کنتراست بالا فعال نیست
۶. از HTML معنایی استفاده کنید
عناصر بومی HTML تعدادی از الگوهای تعاملی استاندارد را که برای دسترسیپذیری مهم هستند، در بر میگیرند. در حالی که یک پاراگراف میتواند به عنوان یک span و یک div میتواند به عنوان یک دکمه استایلبندی شود، عنصر معنایی HTML تضمین میکند که خوانندگان صفحه و ناوبری صفحه کلید، تعاملات و کنترلهای HTML شما را درک میکنند.
هنگام نوشتن کامپوننتهای Angular، باید در صورت امکان از این عناصر بومی مستقیماً استفاده مجدد کنید، نه اینکه رفتارهای به خوبی پشتیبانی شده را دوباره پیادهسازی کنید. این کار تضمین میکند که صفحه دارای ساختار محتوای خوب و جریان محتوای طبیعی است و تبها به ترتیب منطقی قرار دارند تا به کاربران در پیمایش وبسایت با استفاده مؤثر از صفحهکلید کمک کنند.
در پایان این بخش، برنامه شما ممیزی زیر را با موفقیت پشت سر خواهد گذاشت:
- 🛑 HTML باید ترتیب، نام و نقش منطقی داشته باشد
میتوانید هر یک از این مراحل را در قسمت نظرات پیدا کنید: TODO: #6. Use Semantic HTML.
مسئله را مشخص کنید
- ویس اوور (VoiceOver) را روشن کنید.
- از پیمایش برگه برای کلیک کردن روی برگه «داستان ما» استفاده کنید.
- توجه داشته باشید که ترتیب تبها متوالی نیست.
- روی خریدها کلیک کنید.
- توجه کنید که دکمه به عنوان یک دکمه شناخته نمیشود.

تبدیل یک <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 معنایی تعامل منطقی را تضمین میکند
- 🛑 کادرهای انتخاب تو در تو برای صفحهخوانها قابل انتخاب نیستند.
- 🛑 صفحهخوان مقادیر اسلایدر را نمیخواند
- 🛑 فوکوس صفحهخوان در انتخابگر رنگ از پنجره خارج میشود
- 🛑 تغییرات، خطاها و اعلانها اعلام نمیشوند
- 🛑 حالت کنتراست بالا فعال نیست
۷. ایجاد کنترلهای قابل انتخاب با Angular Material
یکی از الگوهای تعاملی پیچیده برای سرویسهای دسترسی، کنترلهای تودرتو هستند. به زیرآیتمهای منو یا چکباکسهای تودرتو فکر کنید. چگونه به کاربر نشان میدهید که میتواند زیرگروهی از گزینهها را انتخاب کند یا به یک آیتم منوی والد برود؟
در انگولار، با سادهسازی هرچه بیشتر کنترلها، منوها و کنترلها را ساده کنید تا اجزای قابل پیمایش ایجاد کنید. در این مثال، از لیستباکس انگولار متریال برای ساخت یک نمونه از این الگوی تعاملی استفاده میکنید.
در پایان این بخش، برنامه شما ممیزی زیر را با موفقیت پشت سر خواهد گذاشت:
- 🛑 کادرهای انتخاب تو در تو برای صفحهخوانها قابل انتخاب نیستند.
میتوانید هر یک از این مراحل را در قسمت نظرات پیدا کنید: TODO: #7. Create selectable controls with Angular Material.
مسئله را مشخص کنید
برای شناسایی این مشکل، صفحهخوان خود را روشن میکنیم و سعی میکنیم یک کادر انتخاب تودرتو را انتخاب کنیم.
- ویس اوور (VoiceOver) را روشن کنید.
- طعمهای مختلف پرکننده را انتخاب کنید.
- توجه کنید که کادرهای انتخاب والدین هنگام خواندن توسط VoiceOver، فرزندان را مشخص نمیکنند. حالا که کادر انتخاب Bok Choy را غیرفعال کردهاید، از کجا میدانید که کادر انتخاب Vegan غیرفعال است؟

A11y در متریال زاویهای
شما کادر انتخاب معنایی را با کادر انتخاب Angular Material جایگزین میکنید، که شامل دانش داخلی این الگوی تعاملی است. توجه به این نکته مهم است که جایگزینی کامپوننتها با Material، دسترسیپذیری را تضمین نمیکند. مانند هر کامپوننت دیگری، باید به صورت دستی تست کنید زیرا روشهای زیادی برای پیادهسازی Material به صورت غیرقابل دسترس وجود دارد.
کادرهای انتخاب را با کادرهای انتخاب متریال جایگزین کنید
- ابتدا، لیست جدید مواد پرکننده و یک متغیر برای ذخیره طعمهای پرکننده انتخابی خود اضافه کنید:
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
})
}
}
- یک
<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 معنایی تعامل منطقی را تضمین میکند
- ✅ همه کنترلها توسط صفحهخوانها قابل دسترسی هستند
- 🛑 صفحهخوان مقادیر اسلایدر را نمیخواند
- 🛑 فوکوس صفحهخوان در انتخابگر رنگ از پنجره خارج میشود
- 🛑 تغییرات، خطاها و اعلانها اعلام نمیشوند
- 🛑 حالت کنتراست بالا فعال نیست
۸. برچسبهای کنترل را با ARIA ارائه دهید
شما کامپوننتهای HTML معنایی و Material برنامه Angular خود را تغییر دادهاید، اما برخی از کامپوننتها برای پیمایش کامل توسط صفحهخوانها به ویژگیهای خاصی نیاز دارند.
مشخصات برنامههای غنی اینترنتی قابل دسترس (WAI-ARIA یا ARIA) از ابتکار عمل دسترسیپذیری وب، به رفع مشکلاتی که با HTML بومی قابل مدیریت نیستند، کمک میکند. این مشخصات به شما امکان میدهد ویژگیهایی را مشخص کنید که نحوه ترجمه یک عنصر به درخت دسترسیپذیری را تغییر میدهند.
در پایان این بخش، برنامه شما ممیزی زیر را با موفقیت پشت سر خواهد گذاشت:
- 🛑 صفحهخوان مقادیر اسلایدر را نمیخواند
میتوانید هر یک از این مراحل را در زیر نظرات پیدا کنید: TODO: #8. Provide control labels with ARIA.
مسئله را مشخص کنید
برای شناسایی این مشکل، صفحهخوان خود را روشن کنید و اسلایدر خود را حرکت دهید:
- ویس اوور (VoiceOver) را روشن کنید.
- به نوار لغزنده کمیت بروید و مقدار را تغییر دهید.
- توجه کنید که برچسب مقدار وجود ندارد.

استفاده از ویژگیهای 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>
تأیید تغییرات
دوباره صفحهخوان خود را روشن کنید و تغییرات خود را تأیید کنید. اکنون میتوانید اسلایدر را حرکت دهید!

ممیزی دسترسیپذیری:
- ✅ همه صفحات دارای عناوین منحصر به فرد هستند
- ✅ رنگها نسبت کنتراست کافی دارند
- ✅ HTML معنایی تعامل منطقی را تضمین میکند
- ✅ همه کنترلها توسط صفحهخوانها قابل دسترسی هستند
- ✅ اسلایدر از ویژگیهای ARIA برای ارائه برچسب استفاده میکند
- 🛑 فوکوس صفحهخوان در انتخابگر رنگ از پنجره خارج میشود
- 🛑 تغییرات، خطاها و اعلانها اعلام نمیشوند
- 🛑 حالت کنتراست بالا فعال نیست
۹. قدرت @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 ارائه میدهد، به Accessibility مراجعه کنید.
۱۰. کنترل فوکوس با FocusTrap
وقتی یک کادر محاورهای یا پنجرهی مودال باز است، کاربر فقط درون آن تعامل دارد. اجازه دادن به فوکوس برای گریز از خارج از کادر محاورهای، زمینهها را با هم مخلوط میکند و حالتی ایجاد میکند که کاربر نمیداند در کجای صفحه قرار دارد.
در Angular، دستورالعمل cdkTrapFocus فوکوس کلید tab- را درون یک عنصر به دام میاندازد. این دستورالعمل برای ایجاد تجربه قابل دسترس برای کامپوننتهایی مانند پنجرههای محاورهای modal در نظر گرفته شده است، جایی که فوکوس باید محدود شود.
در پایان این بخش، برنامه شما ممیزی زیر را با موفقیت پشت سر خواهد گذاشت:
- 🛑 فوکوس صفحهخوان در انتخابگر رنگ از پنجره خارج میشود
میتوانید این مراحل را در قسمت نظرات پیدا کنید: TODO: #10. Control focus with FocusTrap.
مسئله را مشخص کنید
برای شناسایی این مشکل، صفحهخوان خود را روشن کنید و کادر انتخاب رنگ را باز کنید.
- ویس اوور (VoiceOver) را روشن کنید.
- برای تغییر رنگ از پیمایش برگه استفاده کنید.
- برای مشاهدهی ترتیب فوکوس شهودی و تلهگذاری فوکوس در انتخابگر رنگ، بررسی کنید.

فوکوس ترپ را اضافه کنید
cdkFocusTrap میتواند برای به دام انداختن و کنترل ترتیب فوکوس در کامپوننتهای سفارشی استفاده شود. استفاده از mat-dialog-content برای حل اکثر مشکلات به دام انداختن فوکوس در یک دیالوگ کافی است. ویژگی cdkFocusInitial را برای تعریف ناحیه فوکوس اولیه روی رنگ پوشش dumpling <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 برای ارائه برچسب استفاده میکند
- ✅ انتخابگر رنگ، فوکوس تلهگذاری صحیحی دارد
- 🛑 تغییرات، خطاها و اعلانها اعلام نمیشوند
- 🛑 حالت کنتراست بالا فعال نیست
۱۱. اعلام تغییرات با LiveAnnouncer
خوانندگان صفحه نمایش باید وقتی چیزی در صفحه تغییر میکند، مطلع شوند. تصور کنید که سعی میکنید فرمی را ارسال کنید یا خریدی را تکمیل کنید، و نمیدانید که خطایی ظاهر شده است که از ارسال فرم جلوگیری میکند. این ناامیدکننده است!
LiveAnnouncer برای اعلام پیامها برای کاربران صفحهخوان با استفاده از یک ناحیه aria-live استفاده میشود تا اطمینان حاصل شود که صفحهخوانها از اعلانها و تغییرات صفحه به صورت زنده مطلع میشوند. برای اطلاعات بیشتر در مورد نواحی aria-live، به WAI-ARIA از W3C مراجعه کنید. در Angular، فراخوانی LiveAnnouncer به عنوان یک سرویس، یک راه حل قابل آزمایشتر از ویژگیهای aria-live است.
در پایان این بخش، برنامه شما ممیزی زیر را با موفقیت پشت سر خواهد گذاشت:
- 🛑 تغییرات، خطاها و اعلانها اعلام نمیشوند
میتوانید این مراحل را در قسمت نظرات پیدا کنید: TODO: #11. Announce changes with LiveAnnouncer.
مسئله را مشخص کنید
برای شناسایی این مشکل، صفحهخوان خود را روشن کنید و گزینه «خرید بدون تکمیل فیلدهای فرم» را انتخاب کنید:
- ویس اوور (VoiceOver) را روشن کنید.
- از پیمایش تب برای تغییر رنگ و انجام خرید جعلی استفاده کنید.
- توجه داشته باشید که هنگام خروج از پنجره هیچ نشانهای مبنی بر انتخاب رنگ وجود ندارد و خرید خوانده نمیشود.

LiveAnnouncer را به کد خود اضافه کنید
LiveAnnouncer را اضافه کنید و هم انتخاب رنگ و هم خرید جعلی را به عنوان یک رشته اعلام کنید. در یک پیادهسازی واقعی، این ممکن است هنگام پیمایش به یک سیستم پرداخت شخص ثالث یا برای خطاهای فرم خوانده شود.
- اضافه کردن اعلان هنگام انتخاب رنگ:
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();
}
}
- وقتی خرید جعلی انجام میشود، یک اعلان اضافه کنید:
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 Mode) پشتیبانی میکند. این حالت ظاهر همه برنامهها، از جمله برنامههای وب، را تغییر میدهد تا کنتراست را به طرز چشمگیری افزایش دهد. در انگولار، شما میخواهید به ترجیحات کاربر در برنامه خود احترام بگذارید.
ابزار HighContrastModeDetector به شما امکان میدهد تا مشخص کنید که آیا مرورگر در حال حاضر در محیط با کنتراست بالا قرار دارد یا خیر.
اینترنت اکسپلورر، مایکروسافت اج و فایرفاکس از این حالت پشتیبانی میکنند. گوگل کروم از حالت کنتراست بالای ویندوز پشتیبانی نمیکند. این سرویس حالت کنتراست بالای اضافه شده توسط افزونه مرورگر کروم با کنتراست بالا را تشخیص نمیدهد.
در پایان این بخش، برنامه شما ممیزی زیر را با موفقیت پشت سر خواهد گذاشت:
- 🛑 حالت کنتراست بالا فعال نیست
میتوانید این مراحل را در قسمت نظرات پیدا کنید: TODO: #12. Enable HighContrast mode.
مسئله را مشخص کنید
برای شناسایی این مشکل، برنامه خود را در Internet Explorer، Microsoft Edge یا Firefox باز کنید، حالت کنتراست بالا (High Contrast Mode) را فعال کنید و عدم تغییر را مشاهده کنید:
- برنامه خود را در Internet Explorer، Microsoft Edge یا Firefox باز کنید.
- حالت کنتراست بالا را روشن کنید.
- توجه داشته باشید که برنامه بدون تغییر باقی مانده است.
اضافه شدن پشتیبانی برای حالت کنتراست بالا
در 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);
}
}
}
تأیید تغییرات
برنامه خود را رفرش کنید و تغییرات را تأیید کنید. شما یک طرح کلی به دکمه در حالت کنتراست بالا اضافه کردید!


ممیزی دسترسیپذیری:
- ✅ همه صفحات دارای عناوین منحصر به فرد هستند
- ✅ رنگها نسبت کنتراست کافی دارند
- ✅ HTML معنایی تعامل منطقی را تضمین میکند
- ✅ همه کنترلها توسط صفحهخوانها قابل دسترسی هستند
- ✅ اسلایدر از ویژگیهای ARIA برای ارائه برچسب استفاده میکند
- ✅ انتخابگر رنگ، فوکوس تلهگذاری صحیحی دارد
- ✅ تغییرات، خطاها و اعلانها اعلام میشوند
- ✅ حالت کنتراست بالا فعال است
۱۳. تبریک میگویم!
تبریک میگویم، شما مشکلات رایج دسترسیپذیری وب را در برنامه Angular خود برطرف کردید! 🎉
برای دیدن همه راهکارها، به شاخه main مراجعه کنید.



اکنون شما مراحل کلیدی مورد نیاز برای حل هشت مشکل رایج در برنامه Angular خود را میدانید.
بیشتر بدانید
این آزمایشگاههای کد را بررسی کنید:
این مطالب را بخوانید: