FA-TOOLS — Header Component

# راهنمای جامع CSS Container Queries برای طراحی کامپوننت‌های هوشمند

رفیق برنامه‌نویس، حالت چطوره؟ تا حالا شده توی پروژه‌ای گیر کنی که یه کامپوننت رو ساخته باشی، ولی وقتی می‌بریش توی یه جای دیگه از سایت، یهو کلاً بهم بریزه؟ یا مجبور بشی برای هر گوشه و کناری که کامپوننتت قرار می‌گیره، یه مدیا کوئری جدید بنویسی و حس کنی داری یه کار تکراری و خسته‌کننده رو انجام میدی؟ دقیقاً همینجا بود که همه ما نیاز به یه راه حل بهتر رو حس کردیم. مدیا کوئری‌ها عالی‌اند، ولی فقط بهت میگن که سایز *کل صفحه* چقدره. اما اگه می‌خواستی یه کامپوننت خودش تصمیم بگیره که چطور نمایش داده بشه، بر اساس فضای *خودش*؟ اینجاست که Container Queries میاد وسط و بازی رو کلاً عوض می‌کنه!

🚀 دوست داری ابزارهای حرفه‌ای طراحی و توسعه وب رو تجربه کنی؟ همین الان یه سر به فروشگاه ابزارهای ما بزن و از کلی کد آماده و اسنیپت‌های خفن بهره‌مند شو تا سرعت کدنویسیت رو چند برابر کنی!

خب، قبل از اینکه بریم سراغ جزئیات و ببینیم چطوری میشه با این قابلیت جدید CSS، کامپوننت‌هایی ساخت که واقعاً “هوشمند” عمل کنن، بیا یه نگاه کلی بندازیم به داستان از چه قراره:

🌟 نقشه راه جامع CSS Container Queries 🌟

┌────────────────────────────────────────────────────────────┐
│ مقدمه: چرا Container Queries؟                              │
│   ├─ مشکل مدیا کوئری‌ها در کامپوننت‌محوری                                  │
│   └─ معرفی قابلیت هوشمندسازی کامپوننت‌ها                                  │
│                                                                            │
│ بخش ۱: فهم عمیق Container Queries                         │
│   ├─ @container: ساختار اصلی و نحو استفاده                               │
│   ├─ container-type: تنظیم نوع کانتینر (size, inline-size)              │
│   └─ container-name: نامگذاری کانتینرها برای سازماندهی بهتر             │
│                                                                            │
│ بخش ۲: واحدهای جدید و کاربری عملی                          │
│   ├─ واحدهای نسبی کانتینر: cqi, cqb, cqh, cqw, cqmin, cqmax            │
│   └─ مثال‌های واقعی: کارت‌ها، سایدبارها و ناوبارها                      │
│                                                                            │
│ بخش ۳: تفاوت‌های کلیدی و مزایا                              │
│   ├─ Container Queries vs. Media Queries: نبرد بزرگ!                    │
│   └─ ارتقاء تجربه کاربری و سئو                                           │
│                                                                            │
│ بخش ۴: ملاحظات و بهترین شیوه‌ها                           │
│   ├─ پشتیبانی مرورگرها و فال‌بک‌ها                                        │
│   ├─ سازماندهی کد CSS و پرفورمنس                                         │
│   └─ موارد استفاده پیشرفته                                               │
│                                                                            │
│ بخش ۵: عیب‌یابی سریع و راهکارهای عملی                      │
│   ├─ مشکلات رایج و حل آن‌ها                                               │
│   └─ نکات حرفه‌ای برای کدنویسی بی‌دردسر                                 │
│                                                                            │
│ پرسش‌های متداول (FAQ Schema)                               │
└────────────────────────────────────────────────────────────┘
    

**چرا اصلاً Container Queries؟ مشکل چیه؟**

خب، بیا یه سناریو رو تصور کنیم: شما یه کامپوننت “کارت محصول” (Product Card) ساختید. این کارت می‌تونه توی یه سایدبار کوچیک (جایی که فضای کمی داره)، یا توی یه گرید بزرگ (جایی که فضای زیادی داره) و حتی توی یه صفحه نمایش اصلی (جایی که فضای متوسط داره) قرار بگیره.

با مدیا کوئری‌های سنتی (`@media`), فقط می‌تونستی بگی: “اگر عرض صفحه نمایش از فلان پیکسل کمتر بود، کارت محصول رو اینطوری نشون بده. و اگر بیشتر بود، اونطوری.” مشکل اینجا بود که مدیا کوئری به *خود کامپوننت* کار نداشت، فقط به *سایز کل صفحه* نگاه می‌کرد. نتیجه؟ باید برای هر جایی که کارت محصول می‌ذاشتی، مدیا کوئری‌های پیچیده و تکراری می‌نوشتی. این یعنی یه عالم کد اضافی، نگهداری سخت‌تر و کلی سردرد.

**فهم عمیق Container Queries: شروع یک انقلاب**

Container Queries دقیقاً برای همین مشکلات اومده. به جای اینکه کامپوننتت به سایز کل صفحه نگاه کنه، حالا می‌تونه به سایز *خود کانتینری* که داخلش قرار گرفته نگاه کنه. این یعنی کامپوننت‌ها واقعاً هوشمند میشن و خودشون رو با محیط اطرافشون وفق میدن.

**@container: ساختار اصلی و نحو استفاده**

اسکلت اصلی `Container Queries` با قانون `container@` شروع میشه. مثل `@media` که برای مدیا کوئری‌ها بود، اینجا از `@container` استفاده می‌کنیم.

برای اینکه یه المنت بتونه به عنوان یک “کانتینر” عمل کنه و بچه‌هاش بتونن به سایز اون واکنش نشون بدن، اول باید اون المنت رو به عنوان کانتینر تعریف کنیم. این کار با پراپرتی `container-type` انجام میشه.

نحوه تعریف کانتینر:

.my-container {
  container-type: inline-size;
  container-name: product-area; /* اختیاری */
}

اینجا `container-type: inline-size;` به مرورگر میگه که این المنت (با کلاس `.my-container`) قراره به عنوان یک کانتینر برای تغییرات سایز در جهت افقی (عرض) عمل کنه. اگه می‌خواستی هم در عرض و هم در ارتفاع واکنش نشون بده، از `size` استفاده می‌کردی.

**container-type: تنظیم نوع کانتینر**

دو تا مقدار اصلی برای `container-type` داریم:
1. **`inline-size`**: این رایج‌ترین و مفیدترین نوعه. کانتینر فقط به تغییرات در بُعد خطی (معمولاً عرض در زبان‌های LTR مثل فارسی) واکنش نشون میده. اگه `writing-mode` عوض بشه، این جهت هم عوض میشه.
2. **`size`**: کانتینر هم به تغییرات در عرض و هم در ارتفاع واکنش نشون میده. استفاده از این حالت می‌تونه باعث بروز مشکلاتレイアウト (layout) بشه اگه حواست نباشه، چون تغییرات ارتفاع محتوا می‌تونه باعث تغییر ارتفاع کانتینر بشه و یه لوپ بی‌پایان درست کنه. معمولاً `inline-size` بهترین انتخابه.

یه نکته کوچیک ولی مهم: برای اینکه `container-type` کار کنه، کانتینر باید یه `contain` پراپرتی هم به صورت ضمنی یا صریح داشته باشه. وقتی `container-type` رو تنظیم می‌کنی، مرورگر خودش `contain: layout inline-size` یا `contain: layout size` (بسته به نوعش) رو اضافه می‌کنه. نگران نباش، لازم نیست دستی این کار رو بکنی.

**container-name: نامگذاری کانتینرها برای سازماندهی بهتر**

وقتی چندین کانتینر تو صفحه داری، نامگذاریشون با `container-name` می‌تونه خیلی به سازماندهی و خوانایی کد کمک کنه. فرض کن یه کانتینر برای سایدبار داری و یه کانتینر برای بخش اصلی محتوا. با نامگذاری می‌تونی مشخص کنی که یه المنت، به کدوم کانتینر باید واکنش نشون بده.

مثال با container-name:

.sidebar {
  container-type: inline-size;
  container-name: sidebar-layout;
}

.main-content {
  container-type: inline-size;
  container-name: content-area;
}

@container sidebar-layout (min-width: 250px) {
  .sidebar-item {
    font-size: 1em;
  }
}

اگر `container-name` رو مشخص نکنی، به صورت پیش‌فرض کامپوننت به نزدیک‌ترین کانتینر والدش واکنش نشون میده. اما نامگذاری، مخصوصاً تو پروژه‌های بزرگ، نجات‌بخش میشه.

**واحدهای جدید و کاربری عملی: دنیای ریسپانسیو واقعی**

یکی از جذاب‌ترین قسمت‌های Container Queries، واحدهای جدیدی هستند که معرفی کرده. این واحدها شبیه واحدهای `vw`, `vh` هستند، ولی به جای اینکه به viewport کل صفحه نگاه کنن، به سایز *کانتینر والد* نگاه می‌کنن.

**واحدهای نسبی کانتینر: cqi, cqb, cqh, cqw, cqmin, cqmax**

| واحد CSS | توضیح |
| :——— | :——————————————————————- |
| `cqw` | ۱٪ از عرض کانتینر (Container Query Width) |
| `cqh` | ۱٪ از ارتفاع کانتینر (Container Query Height) |
| `cqi` | ۱٪ از سایز در جهت خطی کانتینر (Inline Size, معمولاً عرض) |
| `cqb` | ۱٪ از سایز در جهت بلوکی کانتینر (Block Size, معمولاً ارتفاع) |
| `cqmin` | مقدار کوچکتر بین `cqi` و `cqb` |
| `cqmax` | مقدار بزرگتر بین `cqi` و `cqb` |

این واحدها بهت اجازه میدن تا فونت‌ها، پدینگ‌ها، مارجین‌ها و هر چیز دیگه‌ای رو بر اساس سایز کانتینر تنظیم کنی. مثلاً می‌تونی بگی “اندازه فونت عنوان کارت باید ۲ درصد از عرض کانتینر والدش باشه”. این یعنی یه کارت همیشه نسبت به فضایی که داره، زیبا و خوانا میمونه.

**مثال‌های واقعی: کارت‌ها، سایدبارها و ناوبارها**

حالا بیا ببینیم این قابلیت چطوری می‌تونه زندگی یک برنامه‌نویس رو نجات بده و پروژه‌ها رو خیلی باحال‌تر کنه.

سناریو ۱: کارت محصول پویا (Responsive Product Card)

تصور کن یه کارت محصول که توی یه گرید ۳ ستونه یه شکل داره، توی گرید ۲ ستونه یه شکل دیگه و توی یه سایدبار خیلی باریک یه شکل دیگه. بدون Container Queries، این کابوس بود. حالا ببین چقدر راحت میشه:

.product-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 20px;
  container-type: inline-size;
  container-name: product-area;
}

.product-card {
  border: 1px solid #eee;
  padding: 15px;
  border-radius: 8px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.product-card img {
  max-width: 100%;
  height: auto;
}

@container product-area (max-width: 350px) {
  .product-card {
    flex-direction: row;
    text-align: left;
    font-size: 0.9em;
  }
  .product-card img {
    width: 80px;
    margin-right: 15px;
  }
}

@container product-area (min-width: 351px) and (max-width: 500px) {
  .product-card {
    font-size: 1.1em;
  }
}

@container product-area (min-width: 501px) {
  .product-card {
    font-size: 1.2em;
  }
}

**تفاوت‌های کلیدی و مزایا: Container Queries vs. Media Queries**

اینجا دقیقاً همونجاییه که Container Queries درخشش واقعی خودش رو نشون میده.

| ویژگی | Container Queries | Media Queries |
| :—————— | :—————————————————— | :——————————————————- |
| **مبنای شرط‌بندی** | سایز کانتینر والد (المنتی که `container-type` داره) | سایز کل Viewport (صفحه نمایش) |
| **کاربرد اصلی** | ریسپانسیو کردن *کامپوننت‌ها* به صورت مستقل | ریسپانسیو کردن *لی‌اوت کلی صفحه* |
| **استقلال کامپوننت**| بالا؛ کامپوننت هوشمند و قابل استفاده مجدد است. | پایین؛ کامپوننت وابسته به سایز کلی صفحه است. |
| **پیچیدگی کد** | کمتر برای کامپوننت‌ها، کد ماژولارتر و خواناتر | بیشتر برای کامپوننت‌ها، تکرار کد و نگهداری دشوار |
| **فلسفه طراحی** | Component-driven (از جزء به کل) | Page-driven (از کل به جزء) |
| **مزیت اصلی** | ساخت Design Systemهای منعطف و کامپوننت‌های جدا | تنظیم لی‌اوت کلی برای دستگاه‌های مختلف (موبایل، تبلت، دسکتاپ) |

نکته UX و SEO:

وقتی کامپوننت‌هاتون خودشون رو به درستی با فضایی که دارن تطبیق میدن، تجربه کاربری خیلی بهتر میشه. کاربر شما توی هر سایز صفحه و هر پلتفرمی (از موبایل و تبلت گرفته تا لپ‌تاپ و حتی تلویزیون)، یه تجربه بصری بی‌نقص و زیبا داره. این نه تنها برای کاربر عالیه، بلکه گوگل هم عاشق سایت‌هایی با UX قوی و ریسپانسیو هستش و این موضوع روی سئو سایتت هم تاثیر مثبت میذاره. برای داشتن یه سایت کاملاً بهینه و ریسپانسیو، از ابزارها و کدهای آماده در وبسایت fa-tools.ir غافل نشو!

**ملاحظات و بهترین شیوه‌ها: کدنویسی حرفه‌ای**

مثل هر تکنولوژی جدیدی، `Container Queries` هم یه سری ملاحظات و بهترین شیوه‌ها داره که باید حواسمون بهشون باشه.

**پشتیبانی مرورگرها و فال‌بک‌ها**

خبر خوب اینه که `Container Queries` الان توی اکثر مرورگرهای مدرن (Chrome, Firefox, Safari, Edge) پشتیبانی میشه و دیگه نیازی به فلگ یا چیز خاصی نیست. اما همیشه خوبه که برای مرورگرهای قدیمی‌تر یه فال‌بک (Fallback) مناسب داشته باشی.
می‌تونی از روش Progressive Enhancement استفاده کنی. یعنی اول استایل‌های پایه رو بنویسی که همیشه کار کنن، بعد با `container@` استایل‌های پیشرفته‌تر رو اضافه کنی.

مثال فال‌بک:

.my-component {
  font-size: 16px; /* فال‌بک پیش‌فرض */
  padding: 10px;
}

.container-parent {
  container-type: inline-size;
}

@container (min-width: 400px) {
  .my-component {
    font-size: 20px; /* استایل پیشرفته */
    padding: 20px;
  }
}

**سازماندهی کد CSS و پرفورمنس**

با `Container Queries`, کد CSS تمیزتر و ماژولارتر میشه. دیگه نیازی نیست مدیا کوئری‌های تودرتو بنویسی که از خوندنشون کلافه بشی. می‌تونی استایل‌های یه کامپوننت رو دقیقاً کنار همون کامپوننت نگهداری کنی.
از نظر پرفورمنس، `Container Queries` بهینه طراحی شده. مرورگرها فقط وقتی نیاز باشه محاسبات رو انجام میدن و بار اضافی زیادی روی سیستم نمیذارن. فقط حواست باشه که بیش از حد از `container-type: size;` استفاده نکنی، مگر اینکه واقعاً نیاز باشه.

**موارد استفاده پیشرفته**

* **Design Systems:** عالی برای ساخت Design Systemها و کامپوننت‌ لایبرری‌ها. یک کامپوننت رو می‌سازی و اون خودش توی هر فضایی بهترین نمایش رو پیدا می‌کنه.
* **داشبوردها (Dashboards):** داشبوردهایی که ویجت‌های مختلف با سایزهای متنوع دارن، می‌تونن با Container Queries به شدت منعطف و پویا بشن.
* **بخش‌های محتوا (Content Sections):** یه بخش محتوا که توی سایدبار کوتاه و در بخش اصلی طولانی‌تر میشه، می‌تونه با این روش هوشمندانه عمل کنه.

**عیب‌یابی سریع (Troubleshooting): مشکلات رایج و راه‌حل‌ها**

خب، هیچ تکنولوژی‌ای بی‌عیب نیست و ممکنه با Container Queries هم گاهی به مشکل بخوری. بیا چند تا مشکل رایج و راه حلشون رو مرور کنیم:

1. **مشکل: Container Query کار نمی‌کنه!**
* **راه‌حل:**
* **آیا `container-type` رو روی والد تنظیم کردی؟** حتماً المنتی که می‌خوای فرزندش بهش واکنش نشون بده، باید `container-type: inline-size;` یا `container-type: size;` داشته باشه.
* **آیا مرورگرت ازش پشتیبانی می‌کنه؟** همیشه `caniuse.com` رو چک کن. (البته الان اکثر مرورگرها ساپورت می‌کنن.)
* **آیا `display: contents;` یا `display: none;` روی کانتینر تنظیم شده؟** این‌ها می‌تونن باعث بشن کانتینر سایز نداشته باشه یا فرزندانش از flow خارج بشن.
* **آیا روی کانتینر `overflow: hidden;` گذاشتی؟** گاهی اوقات `overflow` می‌تونه روی چگونگی محاسبه سایز تاثیر بذاره.
* **`container-name` رو اشتباه نوشتی؟** اگه از `container-name` استفاده می‌کنی، مطمئن شو که اسمش توی `@container` دقیقاً همون چیزیه که تعریف کردی.

2. **مشکل: لوپ بی‌پایان (Infinite Loop) با `container-type: size;`**
* **راه‌حل:** همونطور که گفتم، استفاده از `size` می‌تونه خطرناک باشه. مثلاً اگه محتوای داخل کانتینر باعث تغییر ارتفاع کانتینر بشه و اون تغییر ارتفاع دوباره روی محتوا تاثیر بذاره. بهترین راه حل اینه که تا حد امکان از `container-type: inline-size;` استفاده کنی. اگه واقعاً به `size` نیاز داری، مطمئن شو که ارتفاع کانتینر رو با یه مقدار ثابت (مثل `height: 200px;`) یا با `max-height` محدود کردی تا از لوپ جلوگیری بشه.

3. **مشکل: واحدهای `cqi` و `cqw` کار نمی‌کنند.**
* **راه‌حل:** مطمئن شو که المنتی که داره از این واحدها استفاده می‌کنه، داخل یک کانتینر با `container-type` مناسب قرار گرفته باشه. این واحدها فقط داخل کانتینرها معنی دارن.

4. **مشکل: استایل‌ها در برخی شرایط اعمال نمی‌شوند.**
* **راه‌حل:** مثل هر CSS دیگه‌ای، ترتیب و اختصاصی بودن (Specificity) استایل‌ها مهمه. مطمئن شو که استایل‌های Container Query شما به اندازه کافی Specific هستند و توسط استایل‌های دیگه override نمی‌شن. همچنین، اگر از `container-name` استفاده می‌کنی، مطمئن شو که توی `@container` هم اون اسم رو صدا زدی.

5. **مشکل: پرفورمنس کاهش یافته (غیرمعمول ولی ممکن است)**
* **راه‌حل:** اگر تعداد کانتینرهای تعریف شده خیلی زیاد باشه یا از `container-type: size;` به صورت بی‌رویه استفاده کنی، ممکنه کمی افت پرفورمنس داشته باشی. سعی کن فقط المنت‌هایی رو کانتینر کنی که واقعاً نیاز به پاسخگویی داخلی دارن. استفاده منطقی و هدفمند همیشه بهترین رویش است.

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

**پرسش‌های متداول (FAQ)**

Container Queries دقیقاً چیست؟

Container Queries یک قابلیت جدید در CSS است که به توسعه‌دهندگان اجازه می‌دهد استایل‌های عناصر را بر اساس اندازه، استایل یا وضعیت کانتینر والد آن‌ها تنظیم کنند، نه بر اساس اندازه کل صفحه نمایش. این به طراحی کامپوننت‌های مستقل و ریسپانسیو کمک می‌کند.

تفاوت اصلی Container Queries با Media Queries چیست؟

Media Queries به سایز *کل صفحه نمایش (viewport)* واکنش نشان می‌دهند، در حالی که Container Queries به سایز *کانتینر والد* یک المنت واکنش نشان می‌دهند. این یعنی کامپوننت‌ها می‌توانند مستقل از مکانشان در صفحه، خود را تطبیق دهند.

چگونه یک المنت را به عنوان کانتینر تعریف کنیم؟

برای تعریف یک المنت به عنوان کانتینر، باید از ویژگی `container-type` استفاده کنید. مثلاً `container-type: inline-size;` که به تغییرات عرض کانتینر واکنش نشان می‌دهد. می‌توانید با `container-name` نامی نیز برای آن انتخاب کنید.

واحدهای `cqi` و `cqw` چه کاربردی دارند؟

این واحدها شبیه `vw` و `vh` هستند اما به جای اینکه ۱٪ از viewport کل صفحه باشند، ۱٪ از سایز کانتینر والد خود را نشان می‌دهند. `cqi` برای ۱٪ از سایز در جهت خطی (معمولاً عرض) و `cqw` برای ۱٪ از عرض کانتینر است. این واحدها برای ایجاد نسبت‌های واکنش‌گرا در داخل کامپوننت‌ها بی‌نظیرند.

برای اطلاعات بیشتر، کدها و ابزارهای توسعه، به وبسایت fa-tools.ir سر بزنید.

نیاز به راهنمایی بیشتر داری؟ تماس بگیر: 09202232789


**پایان مقاله.**

Table of Contents

آخرین نوشته‌ها