Feature Queries در CSS
کوئری کانتینر میپرسد عرض والد چقدر است. مدیا کوئری سراغ viewport میرود. Feature query سؤال دیگری دارد: این مرورگر اصلاً این CSS را میفهمد؟ با @supports یک پایهٔ مطمئن میگذارید، بعد فقط جایی که موتور قابلیت را دارد، لایهٔ مدرن را باز میکنید.
بهبود تدریجی، نه قمار
Feature query یک دروازهٔ قابلیت است. استایل قدیمی را پاک نمیکنید — چیدمانی نگه میدارید که همهجا کار کند، بعد داخل @supports لایهٔ غنیتر را اضافه میکنید وقتی موتور بتواند همان ویژگی را پارس کند (مثلاً display: grid یا gap روی فلکس).
شکل سادهٔ @supports
رایجترین شکل، یک جفت ویژگی–مقدار را میآزماید. اگر مرورگر آن اعلان را بفهمد، قانونهای داخل بلاک اعمال میشوند:
.card-list {
display: block;
}
.card-list .card {
margin-bottom: 1rem;
padding: 1rem;
border: 1px solid #e2e8f0;
border-radius: 0.75rem;
background: #fff;
}
@supports (display: grid) {
.card-list {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
gap: 1rem;
}
.card-list .card {
margin-bottom: 0;
}
}
بیرون بلاک، کارتها با فاصلهٔ ساده روی هم مینشینند. داخل @supports (display: grid) همان فهرست گرید منعطف میشود — موتورهای قدیمی همان پشته را نگه میدارند؛ موتورهای جدید گرید میگیرند.
ترکیب شرطها: and و or و not
میتوانید چند قابلیت را با هم بخواهید، بین گزینهها یکی را بپذیرید، یا شرط را برعکس کنید:
@supports (display: grid) and (gap: 1rem) {
.toolbar {
display: grid;
grid-auto-flow: column;
gap: 0.75rem;
align-items: center;
}
}
@supports (display: flex) or (display: grid) {
.cluster {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
}
@supports not (display: grid) {
.card-list .card {
max-width: 36rem;
}
}
and دروازه را تنگ میکند (هر دو باید پاس شوند). or بازترش میکند. not مسیر عدم پشتیبانی را استایل میدهد — برای فالبک عمدی بهدرد میخورد، به شرطی که آن فالبک واقعاً خوانا و کامل باشد.
سلکتور را با selector() بیازمایید
بعضی قابلیتها سلکتورند، نه ویژگی. آنها را داخل selector() بگذارید تا سؤال این باشد: «این سلکتور را بلدی پارس کنی؟»
.nav a {
color: #0f172a;
text-decoration: none;
}
@supports selector(:has(*)) {
.nav:has(a:focus-visible) {
outline: 2px solid #2563eb;
outline-offset: 4px;
}
.card:has(img) .title {
font-weight: 700;
}
}
بدون selector()، گذاشتن خامِ :has() داخل @supports الگوی قابلاتکایی نیست. با آن، مرورگری که :has() ندارد فقط لایهٔ پیشرفته را رد میکند و استایل پایهٔ لینکها میماند.
هر ابزار کدام سؤال را میپرسد؟
📊 Media, container, and feature queries
| سؤال شما | ترجیح | ابزار رایج |
|---|---|---|
| عرض viewport / زمینهٔ دستگاه چقدر است؟ | پوستهٔ صفحه، بریکپوینت | @media (…) |
| عرض همین والد دور کامپوننت چقدر است؟ | کارت در جاهای نابرابر | @container (…) بعد از container-type |
| آیا مرورگر این CSS را پشتیبانی میکند؟ | بهبود تدریجی | @supports (…) / selector(…) |
این سه تا کنار هم خوب کار میکنند: مدیا برای صفحه، کانتینر برای جایگاه، @supports برای قابلیت. با @supports بریکپوینت جعلی نسازید و با @media قابلیت را چک نکنید.
اول پایه، بعد ارتقا
الگوی عملی این است که ظاهر مشترک بیرون دروازه بماند و چیدمان ارتقایافته داخلش بیاید:
.feature-panel {
padding: 1.25rem;
border-radius: 0.75rem;
background: #f8fafc;
color: #0f172a;
}
.feature-panel .lead {
margin: 0 0 0.75rem;
font-size: 1.125rem;
line-height: 1.5;
}
.feature-panel .actions {
display: block;
}
.feature-panel .actions a {
display: inline-block;
margin: 0.25rem 0.5rem 0.25rem 0;
padding: 0.5rem 0.875rem;
border-radius: 0.5rem;
background: #e2e8f0;
color: inherit;
text-decoration: none;
}
@supports (display: flex) and (gap: 0.5rem) {
.feature-panel .actions {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
.feature-panel .actions a {
margin: 0;
}
}
هر مرورگری پدینگ، تایپ و لینک قابلکلیک میگیرد. فلکس و gap فقط وقتی هر دو فهمیده شوند ظاهر میشوند — اگر یکی نباشد، صفحه سوراخ خالی نمیماند.
Nesting کنار @supports
قطعههای Modern Toolkit با هم جمع میشوند. Nesting سلکتورها را مرتب میکند؛ دروازهٔ قابلیت هنوز مال @supports است:
.pricing {
padding: 1rem;
border: 1px solid #e2e8f0;
}
@supports (display: grid) {
.pricing {
display: grid;
gap: 1rem;
& .tier {
padding: 1rem;
background: #fff;
}
& .tier .price {
font-size: 1.5rem;
font-weight: 700;
}
}
}
اگر خود nesting پشتیبانی نشود، معادل تخت بیرون بگذارید یا بپذیرید شکل تودرتو بخشی از مسیر ارتقاست — همان ذهنیت بهبود تدریجی.
خودتان امتحان کنید
- فهرستی را ساده و ستونی استایل کنید؛ بعد چیدمان Grid را داخل
@supports (display: grid)بپیچید. - با
andهمgapرا بخواهید تا فاصلهٔ فلکس/گرید نصفه اعمال نشود. @supports not (display: grid)را با یکmax-widthواضح بنویسید — هر دو مسیر باید عمدی به نظر برسند.- یک قانون
:has()را با@supports selector(:has(*))قفل کنید. - همهٔ ظاهر بصری را داخل
@supportsنبرید؛ رنگ برند و تایپ را در پایه نگه دارید.
اشتباههای رایج
- گذاشتن تنها چیدمان قابلاستفاده داخل
@supportsبدون پایه — مرورگر بدون پشتیبانی صفحه را خراب میبیند - نوشتن
@supports (display)بدون مقدار — feature query به جفت ویژگی–مقدار نیاز دارد (یاselector(…)) - بهجای
@mediaاز@supportsاستفاده کردن (یا برعکس) — قابلیت ≠ عرض viewport - آزمودن ویژگیای که پایه از قبل به آن وابسته است — فقط ارتقا را دروازه کنید
- پشتههای تودرتوی
@supportsبرای بردهای کوچک — یک لایهٔ ارتقای روشن بهتر است
خلاصه
@supportsCSS را بر اساس قابلیت مرورگر دروازه میکند (feature queries)- با
(property: value)بیازمایید، باand/or/notترکیب کنید، و برای سلکتور ازselector()استفاده کنید - پایهٔ محکم بگذارید؛ وقتی پشتیبانی هست ارتقا دهید
- سهتایی را یادتان بماند:
@media→ viewport،@container→ اندازهٔ والد،@supports→ قابلیت - Modern Toolkit اینجا تمام میشود — ماژول بعد: دسترسپذیری و جمعبندی (
accessibility)
🧠 دانش خود را بیازمایید
دانش خود را بیازمایید
خود را با این آزمون تعاملی به چالش بکشید و ببینید موضوع را چقدر خوب درک کردهاید
📝 دستورالعملها
- هر سوال را با دقت بخوانید
- بهترین پاسخ را برای هر سوال انتخاب کنید
- میتوانید آزمون را هر چند بار که میخواهید تکرار کنید
- پیشرفت شما در بالا نمایش داده میشود