دسترسیپذیری با CSS
تا اینجا چیدمان، حرکت و ابزار مدرن را یاد گرفتید. دسترسیپذیری در CSS همان لایهای است که آدمها حس میکنند: جای فوکوس صفحهکلید معلوم است؟ متن خوانا است؟ انیمیشن چرخان کسی را اذیت میکند؟ این جلسه انبار HTML نیست (لندمارک، alt، ARIA). اینجا عادتهای استایلی است که فوکوس، کنتراست و حرکت را قابلاستفاده نگه میدارد.
فوکوس باید دیده شود
کاربر صفحهکلید با Tab بین لینکها و کنترلها جابهجا میشود. اگر حلقهٔ فوکوس غیب شود، راه را گم میکند. :focus-visible را ترجیح بدهید تا کلیک موس آرام بماند و فوکوس صفحهکلید واضح باشد:
:root {
--focus-ring: #2563eb;
}
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
outline: 3px solid var(--focus-ring);
outline-offset: 3px;
}
.text-link:focus:not(:focus-visible) {
outline: none;
}
:focus-visible همان جاهایی را میگیرد که حلقه واقعاً کمک میکند (معمولاً صفحهکلید). حلقهای با کنتراست بالا بگذارید و کمی outline-offset بدهید تا با بوردر قاطی نشود.
بدون جایگزین، outline: none ممنوع
حذف outline پیشفرض فقط وقتی درست است که استایل فوکوس سفارشی و واضح داشته باشید. *:focus { outline: none; } کلاسیکترین دام است:
/* Bad: keyboard users lose the only cue */
.bad-button:focus {
outline: none;
}
/* Good: custom ring that still shows focus */
.good-button:focus-visible {
outline: none;
box-shadow: 0 0 0 3px #fff, 0 0 0 6px #0f766e;
}
اگر outline مرورگر را خاموش میکنید، چیز دیگری باید کنترل فوکوسشده را نشان دهد — box-shadow، رنگ بوردر، یا پسزمینهای که روی هر تم واضح بماند.
کنتراست انتخاب CSS است
رنگ برند روی موکاپ قشنگ است و روی گوشی زیر آفتاب محو میشود. جفت متن / پسزمینه را تصمیم دسترسپذیری بگیرید، نه فقط دکور:
:root {
--surface: #0f172a;
--text: #f8fafc;
--muted: #cbd5e1;
--accent: #38bdf8;
--accent-text: #0c4a6e;
}
.hero {
background: var(--surface);
color: var(--text);
}
.hero .lede {
color: var(--muted);
}
.hero .cta {
background: var(--accent);
color: var(--accent-text);
font-weight: 700;
}
برای متن اصلی و دکمهها کنتراست قوی بخواهید. خاکستری تزیینی برای برچسبهای فرعی اشکالی ندارد، ولی متن و کنترل اصلی باید خوانا بماند. قبل از انتشار پالت، جفتها را با ابزار کنتراست چک کنید.
حرکت کمتر را احترام بگذارید
انیمیشن و تبدیلهای بزرگ بعضیها را اذیت میکند. حرکت غیرضروری را داخل prefers-reduced-motion بگذارید:
.banner {
transition: transform 0.4s ease, opacity 0.4s ease;
}
.banner.is-shown {
transform: translateY(0);
opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
.banner,
.banner.is-shown {
transition: none;
transform: none;
}
.spinner {
animation: none;
}
}
کسی که در سیستمعامل حرکت کمتر خواسته، باید همان UI نهایی را ببیند — فقط بدون مسیر حرکت. تغییر ضروری opacity یا چیدمان بماند؛ چرخش بیپایان و اسلایدهای درشت را بردارید.
کنتراست بالا و forced-colors
بعضی محیطها پالت شما را عوض میکنند (High Contrast ویندوز / forced-colors). دکور شکننده را نرم کنید و بوردر واقعی نگه دارید:
.card {
border: 1px solid #e2e8f0;
background: #fff;
box-shadow: 0 8px 24px rgb(15 23 42 / 12%);
}
@media (forced-colors: active) {
.card {
border: 1px solid CanvasText;
background: Canvas;
box-shadow: none;
color: CanvasText;
}
.card a {
color: LinkText;
}
}
کلمات رنگی سیستم مثل Canvas، CanvasText و LinkText کمک میکنند کنترلها دیده بمانند وقتی رنگ را کاربر تعیین میکند، نه راهنمای برند شما.
چکلیست سمت CSS
📊 CSS accessibility habits
| Practice | CSS habit | Avoid |
|---|---|---|
| Keep focus findable | :focus-visible + strong ring / shadow |
outline: none with no replacement |
| Readable type | High-contrast text/background tokens | Light grey on white for body copy |
| Kind motion | @media (prefers-reduced-motion: reduce) |
Endless spins for everyone |
| Survive high contrast | Real borders; forced-colors tweaks |
Shadow-only “edges” |
| Reachable controls | Comfortable padding / hit area | Tiny icon-only targets with no focus style |
HTML هنوز صاحب لندمارک، برچسب و alt است. CSS صاحب این است که بعد از استایل، همان کنترلها قابلدرک بمانند.
لینک پرش و focus-within
لینک پرش (skip link) از نوار تکراری رد میشود. طوری استایلش کنید که با فوکوس دیده شود. :focus-within هم میتواند کل گروه را وقتی فرزند فوکوس دارد برجسته کند:
.skip-link {
position: absolute;
left: 1rem;
top: -3rem;
padding: 0.5rem 0.75rem;
background: #111827;
color: #fff;
border-radius: 0.375rem;
z-index: 20;
}
.skip-link:focus-visible {
top: 1rem;
outline: 3px solid #fbbf24;
outline-offset: 2px;
}
.nav:focus-within {
box-shadow: inset 0 0 0 2px #2563eb;
}
لینک پرش تا وقتی فوکوس نشده بیرون صفحه میماند، بعد واضح میشود. حلقهٔ nav وقتی Tab روی لینک داخل نوار مینشیند کمک میکند.
خودتان امتحان کنید
- به لینک و دکمه حلقهٔ
:focus-visibleبدهید؛ با Tab بروید و ببینید همیشه فوکوس را میبینید. - یک جفت کمکنتراست را با متن تیرهتر یا سطح عمیقتر درست کنید.
- یک transition یا animation را داخل
prefers-reduced-motion: reduceبگذارید و تنظیم سیستم (یا شبیهسازی DevTools) را عوض کنید. - در حالت forced-colors ببینید کارتها هنوز بوردر واقعی دارند.
- یک skip link بسازید که فقط با فوکوس صفحهکلید ظاهر شود.
اشتباههای رایج
outline: none(یاoutline: 0) سراسری بدون استایل فوکوس سفارشی- رنگ برند قشنگ که روی متن و دکمهٔ اصلی کنتراست ندارد
- انیمیشن درشت برای همه بدون دروازهٔ
prefers-reduced-motion - پنهان کردن کنترل قابلفوکوس فقط با
opacity: 0در حالی که هنوز Tab میگیرد - گرفتن این جلسهٔ CSS بهجای کل کار معنایی HTML و ARIA
خلاصه
- فوکوس صفحهکلید را دیده نگه دارید —
:focus-visibleرا ترجیح دهید و بدون نشانهٔ قویتر outline را پاک نکنید - کنتراست رنگ را برای متن و کنترلها الزام بگیرید
prefers-reduced-motionرا رعایت کنید و برایforced-colorsاستایل را محکم کنید- لینک پرش را استایل دهید و جایی که گروه نیاز دارد از
:focus-withinاستفاده کنید - بعدی: خلاصه و گامهای بعد — CSS (
summary) — جمعبندی کورس قبل از پروژهٔ کوچک
🧠 دانش خود را بیازمایید
دانش خود را بیازمایید
خود را با این آزمون تعاملی به چالش بکشید و ببینید موضوع را چقدر خوب درک کردهاید
📝 دستورالعملها
- هر سوال را با دقت بخوانید
- بهترین پاسخ را برای هر سوال انتخاب کنید
- میتوانید آزمون را هر چند بار که میخواهید تکرار کنید
- پیشرفت شما در بالا نمایش داده میشود