FA-TOOLS — Header Component
آموزش کار با Container Queries در CSS برای کامپوننت‌های فوق ریسپانسیو (کانتینر کوئری در CSS)

آموزش کار با Container Queries در CSS برای کامپوننت‌های فوق ریسپانسیو (کانتینر کوئری در CSS)

رفیق برنامه‌نویس، دیگه وقتشه یه قدم بزرگ تو طراحی ریسپانسیو برداری! اگه از دست مدیا کوئری‌های گیج‌کننده خسته شدی که فقط به سایز viewport اهمیت میدن و کامپوننت‌هات توش قایم میشن، این مقاله واست نوشته شده. همین الان یه سر به فروشگاه ابزارهای کاربردی ما بزن تا ببینی چطور می‌تونیم کارت رو راحت‌تر کنیم. برای یه مشاوره فنی سریع هم می‌تونی با ما تماس بگیری: 09202232789
اینجا قراره با Container Queries آشنا بشیم و کامپوننت‌هایی بسازیم که خودشون از حال و روز ظرفشون باخبرن و بر اساس اون تغییر شکل میدن، نه سایز کلی صفحه. این یعنی انقلاب توی توسعه کامپوننت و رسیدن به وبسایتی واکنش‌گرا در هر ابعادی.

نگاهی سریع به Container Queries: انقلاب ریسپانسیو

💡 چی هست؟

یه قابلیت جدید تو CSS که به جای viewport، به سایز المنت والد (container) نگاه می‌کنه. کامپوننت‌هات دیگه مستقل از کل صفحه، خودشون رو تطبیق میدن.

🚀 چرا مهمه؟

وبسایت‌های فوق ریسپانسیو، کامپوننت‌های قابل استفاده مجدد (reusable components)، کاهش CSS اضافه، تجربه کاربری بی‌نظیر در هر دستگاهی (موبایل، تبلت، لپ‌تاپ، تلویزیون).

🛠️ چطور کار می‌کنه؟

اول یه المنت رو به عنوان کانتینر تعریف می‌کنیم، بعد با `@container` برای المنت‌های داخلش قوانین CSS می‌نویسیم. دقیقاً مثل مدیا کوئری، فقط با دامنه کوچیک‌تر.

🎯 هدف نهایی؟

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

Container Queries چیست و چرا به آن نیاز داریم؟

آموزش کار با Container Queries در CSS برای کامپوننت‌های فوق ریسپانسیو (کانتینر کوئری در CSS) — تصویر 2

تا همین چند وقت پیش، وقتی می‌خواستیم یه وب‌سایت رو برای نمایش تو دستگاه‌های مختلف بهینه کنیم، تنها راه چاره استفاده از Media Queries بود. Media Queries به ما اجازه میدادند بر اساس مشخصات کلی مرورگر (مثل عرض viewport یا رزولوشن صفحه)، استایل‌های مختلفی رو اعمال کنیم. مثلاً اگه صفحه نمایش زیر ۶۰۰ پیکسل بود، منوی سایت رو به یه آیکون همبرگری تبدیل می‌کردیم. این روش برای صفحات کلی خوب بود، اما یه مشکل اساسی داشت: کامپوننت‌ها!

تصور کن یه کارت محصول داری که هم تو صفحه اصلی وب‌سایت نمایش داده میشه، هم تو سایدبار، و هم شاید تو یه مودال (popup). هر کدوم از این مکان‌ها ممکنه عرض‌های متفاوتی داشته باشن. با Media Queries، کارت محصول فقط بر اساس سایز کلی صفحه تغییر می‌کرد. اگه viewport بزرگ بود، کارت تو سایدبار هم بزرگ نمایش داده میشد و ظاهرش به هم می‌ریخت، چون فقط به سایز کلی اهمیت می‌داد. اینجا بود که Container Queries وارد بازی شد.

Container Queries یا به اختصار CQ، به ما این امکان رو میده که استایل‌های یه المنت رو بر اساس سایز (عرض، ارتفاع یا حتی استایل) المنت والدش (parent) تغییر بدیم. به عبارت ساده‌تر، کامپپوننت‌های ما حالا می‌تونن بپرسن: “من الان تو یه ظرف بزرگم یا کوچیک؟” و بر اساس پاسخشون، خودشون رو تنظیم کنن. این یعنی هر کامپوننت می‌تونه رفتار ریسپانسیو مخصوص به خودش رو داشته باشه، بدون اینکه به بقیه صفحه کاری داشته باشه. این رویکرد رو “Component-Driven Responsive Design” یا “Container-Based Responsive Design” میگن که برای ساخت کدهای آماده و اسنیپت‌های واکنش‌گرا عالیه.

چرا CQ ضروریه؟

  • کامپوننت‌های قابل استفاده مجدد: می‌تونی یه کامپوننت بسازی که تو هر جای سایت قرار بگیره و خودش رو با محیطش تطبیق بده. دیگه لازم نیست برای هر مکان، یه ورژن جدید از کامپوننت بسازی.
  • کدنویسی تمیزتر: استایل‌های ریسپانسیو هر کامپوننت کنار خودش قرار می‌گیره، نه تو Media Queryهای سراسری که باعث میشه پیدا کردن و مدیریت استایل‌ها سخت بشه.
  • معماری فرانت‌اند منعطف‌تر: توسعه‌دهندگان فرانت‌اند آزادی عمل بیشتری برای طراحی کامپوننت‌های مستقل دارن.
  • تجربه کاربری بهتر: محتوا همیشه به بهترین شکل ممکن نمایش داده میشه، فارغ از اینکه کاربر از چه دستگاهی یا با چه طرح‌بندی استفاده می‌کنه. این شامل دستگاه‌های مختلف مثل موبایل، تبلت، لپ‌تاپ و حتی تلویزیون‌های هوشمند میشه.

نحوه استفاده از Container Queries: گام به گام

آموزش کار با Container Queries در CSS برای کامپوننت‌های فوق ریسپانسیو (کانتینر کوئری در CSS) — تصویر 3

استفاده از Container Queries خیلی سادست. فقط کافیه دو مرحله رو انجام بدی:

گام اول: تعریف کانتینر (Container Definition)

اولین کاری که باید بکنی، اینه که به مرورگر بگی کدوم المنت قراره “ظرف” باشه. این کار رو با ویژگی container-type انجام میدیم. این ویژگی دو مقدار اصلی می‌گیره:

  • size: این المنت هم بر اساس عرض (width) و هم بر اساس ارتفاع (height) قابل کوئری گرفتن میشه. بهترین گزینه برای کامپوننت‌هایی که باید هم به عرض و هم به ارتفاع واکنش نشون بدن.
  • inline-size: فقط بر اساس عرض (width) قابل کوئری گرفتنه. این رایج‌ترین و مفیدترین حالت برای اکثر سناریوهای ریسپانسیو کامپوننت‌هاست، چون بیشتر اوقات کامپوننت‌ها با تغییر عرض، خودشون رو تنظیم می‌کنن.

یه نکته‌ای که باید حواست باشه اینه که وقتی یه المنت رو به عنوان کانتینر تعریف می‌کنی، در واقع یه “containing block” برای فرزندانش ایجاد می‌کنه و زمینه (context) اون رو مشخص می‌کنه.

مثال: تعریف کانتینر

.my-container {
    container-type: inline-size; /* این المنت بر اساس عرضش قابل کوئری گرفتنه */
    container-name: card-container; /* اختیاری: یه اسم بهش میدیم برای وضوح بیشتر */
}

function copyCode(button) {
const codeBlock = button.nextElementSibling.querySelector(‘code’);
const textToCopy = codeBlock.innerText;
navigator.clipboard.writeText(textToCopy).then(() => {
button.innerText = ‘کپی شد!’;
setTimeout(() => { button.innerText = ‘کپی’; }, 2000);
}).catch(err => {
console.error(‘Failed to copy text: ‘, err);
});
}

ویژگی container-name هم اختیاریه، ولی خیلی به درد می‌خوره، مخصوصاً وقتی چند تا کانتینر تو هم تو هم داری (nested containers). با اسم‌گذاری، می‌تونی دقیقاً مشخص کنی که کوئری برای کدوم کانتینر اعمال بشه.

گام دوم: نوشتن کوئری (Writing the Query)

حالا که کانتینر رو تعریف کردیم، وقتشه استایل‌های مشروط رو برای المنت‌های داخلش بنویسیم. این کار با استفاده از قانون @container انجام میشه، که شبیه @media عمل می‌کنه:

مثال: کوئری ساده

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

.item {
    padding: 15px;
    background-color: #f2f2f2;
    border: 1px solid #ccc;
}

@container (min-width: 400px) {
    .item {
        font-size: 1.2em;
        padding: 20px;
        background-color: #e0f2f7; /* وقتی کانتینر بزرگ شد، رنگش هم عوض میشه */
    }
}

تو این مثال، المنت .item فقط زمانی استایل‌های داخل @container رو می‌گیره که عرض المنت .my-container حداقل ۴۰۰ پیکسل باشه. این یعنی اگه .my-container تو یه سایدبار کوچیک باشه (مثلاً ۳۰۰px)، .item همون استایل‌های اولیه رو داره، ولی اگه تو بخش اصلی صفحه باشه و عرضش به بالای ۴۰۰px برسه، استایل‌های جدید اعمال میشن.

کوئری با نام کانتینر

اگه کانتینرت رو نام‌گذاری کردی (با container-name)، می‌تونی تو کوئری هم از اسمش استفاده کنی. این کار برای جلوگیری از تداخل و شفافیت کد خیلی مفیده:

.my-container {
    container-type: inline-size;
    container-name: card-wrapper;
}

@container card-wrapper (min-width: 500px) {
    .item {
        display: flex;
        flex-direction: row; /* وقتی کانتینر بزرگ شد، آیتم‌ها کنار هم قرار می‌گیرن */
        justify-content: space-between;
    }
}

@container card-wrapper (max-width: 499px) {
    .item {
        flex-direction: column; /* وقتی کانتینر کوچیک شد، آیتم‌ها زیر هم میان */
    }
}

اینجا، المنت .item رفتار متفاوتی رو بر اساس عرض .card-wrapper داره. این انعطاف‌پذیری فوق‌العاده‌ای به ما میده.

مزایای بی‌نظیر Container Queries برای کامپوننت‌های مدرن

همونطور که تا اینجا متوجه شدی، CQ فقط یه قابلیت جدید نیست، یه تغییر پارادایم تو نحوه فکر کردن به طراحی ریسپانسیوه. بیاید چند تا از مهم‌ترین مزایاش رو مرور کنیم:

۱. طراحی ماژولار و مستقل کامپوننت‌ها

با CQ، هر کامپوننت می‌تونه خودش یه دنیای ریسپانسیو داشته باشه. دیگه لازم نیست نگران تداخل استایل‌ها یا پیچیدگی‌های Media Queryهای سراسری باشی. این یعنی می‌تونی یه کارت کاربری بسازی، یه دکمه، یه فرم یا هر چیزی که فکرش رو بکنی، و مطمئن باشی که تو هر سایزی، تو هر کانتینری، بهترین خودش رو نشون میده. این رویکرد به ویژه برای سیستم‌های طراحی (Design Systems) و کتابخانه‌های کامپوننت مثل React، Vue یا Angular فوق‌العادست.

۲. کاهش پیچیدگی CSS و بهبود خوانایی

یادت میاد چقدر طول می‌کشید تا یه استایل ریسپانسیو رو تو Media Queryهای مختلف پیدا کنی و تغییر بدی؟ با CQ، استایل‌های مربوط به ریسپانسیو بودن یه کامپوننت، دقیقاً کنار استایل‌های اصلی اون کامپوننت قرار می‌گیره. این نه تنها خوانایی کد رو به شدت بالا میبره، بلکه نگهداری و دیباگ کردنش رو هم آسون‌تر می‌کنه. انگار هر کامپوننت، CSS ریسپانسیو مخصوص به خودش رو داره.

۳. پشتیبانی بهتر از Flexbox و Grid Layout

Container Queries و Flexbox/Grid مثل پازلی هستن که کنار هم معرکه کار می‌کنن. می‌تونی یه کانتینر داشته باشی که چینش آیتم‌های داخلش (با استفاده از فلکس یا گرید) رو بر اساس عرض خودش تغییر بده. مثلاً اگه کانتینر پهن بود، آیتم‌ها رو تو دو ستون نشون بده و اگه باریک شد، همه رو تو یه ستون زیر هم بچینه. این ترکیب برای ساخت طرح‌بندی‌های پویا و پیچیده ضروریه.

۴. واکنش‌گرایی در ابعاد مختلف (موبایل، تبلت، لپ‌تاپ، تلویزیون)

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

کاربردها و سناریوهای واقعی

حالا که با مفهوم و نحوه استفاده از CQ آشنا شدی، بذار چند تا سناریوی واقعی رو بررسی کنیم که چطور می‌تونه کارت رو متحول کنه.

۱. کارت محصول (Product Card)

یه کارت محصول که شامل تصویر، عنوان، توضیحات، قیمت و دکمه “افزودن به سبد خرید” هست رو در نظر بگیر.

<div class="product-wrapper">
    <div class="product-card">
        <img src="product.jpg" alt="Product Image" class="product-image">
        <div class="product-details">
            <h4 class="product-title">عنوان محصول</h4>
            <p class="product-description">این یک توضیح کوتاه برای محصول است.</p>
            <span class="product-price">$29.99</span>
            <button class="add-to-cart">افزودن به سبد خرید</button>
        </div>
    </div>
</div>

.product-wrapper {
    container-type: inline-size;
    container-name: product-card-container;
    border: 1px solid #eee;
    margin: 10px;
    padding: 10px;
    background-color: #fff;
    /* این wrapper میتونه در layout های مختلفی قرار بگیره و سایزش تغییر کنه */
}

.product-card {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.product-image {
    max-width: 100%;
    height: auto;
    border-radius: 5px;
}

.product-details {
    text-align: center;
}

.product-title {
    font-size: 1.1em;
    margin-bottom: 5px;
}

.product-description {
    font-size: 0.9em;
    color: #666;
    display: -webkit-box;
    -webkit-line-clamp: 2; /* Limit to 2 lines by default */
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.product-price {
    font-size: 1.2em;
    font-weight: bold;
    color: #e67e22;
    display: block;
    margin-top: 10px;
}

.add-to-cart {
    background-color: #3498db;
    color: white;
    padding: 8px 15px;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    margin-top: 10px;
    font-size: 0.95em;
}

/* Container Queries برای product-card-container */
@container product-card-container (min-width: 400px) {
    .product-card {
        flex-direction: row; /* وقتی کانتینر پهن شد، تصویر و جزئیات کنار هم */
        align-items: center;
        text-align: left;
        gap: 20px;
    }
    .product-image {
        max-width: 150px; /* تصویر کوچیکتر میشه */
    }
    .product-details {
        flex-grow: 1;
        text-align: left;
    }
    .product-title {
        font-size: 1.3em;
    }
    .product-description {
        -webkit-line-clamp: 3; /* توضیحات بیشتر */
    }
    .product-price {
        font-size: 1.4em;
        display: inline-block;
        margin-right: 15px;
    }
    .add-to-cart {
        padding: 10px 20px;
        font-size: 1em;
    }
}

@container product-card-container (min-width: 600px) {
    .product-title {
        font-size: 1.5em;
    }
    .product-image {
        max-width: 200px; /* تصویر بزرگتر */
    }
    .product-description {
        -webkit-line-clamp: 4; /* توضیحات بیشتر */
    }
}

تو این مثال، کارت محصول خودش رو با عرض .product-wrapper تطبیق میده. اگه .product-wrapper کوچیک باشه، تصویر و متن زیر هم قرار می‌گیرن، ولی اگه پهن بشه (مثلاً بالای ۴۰۰px)، تصویر و جزئیات محصول کنار هم قرار می‌گیرن. این همون جادویی که انتظارش رو داشتیم.

۲. ویجت اخبار یا بلاگ (News/Blog Widget)

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

<div class="news-widget-wrapper">
    <h3>آخرین اخبار</h3>
    <div class="news-item">
        <img src="news1.jpg" alt="News Image">
        <div class="news-content">
            <h4>عنوان خبر اول</h4>
            <p>خلاصه‌ای از خبر جذاب و خواندنی اول...</p>
        </div>
    </div>
    <div class="news-item">
        <img src="news2.jpg" alt="News Image">
        <div class="news-content">
            <h4>عنوان خبر دوم</h4>
            <p>خلاصه‌ای از خبر جذاب و خواندنی دوم...</p>
        </div>
    </div>
</div>

.news-widget-wrapper {
    container-type: inline-size;
    container-name: news-widget;
    border: 1px solid #ccc;
    padding: 15px;
    background-color: #f9f9f9;
    margin-bottom: 20px;
}

.news-item {
    display: flex;
    flex-direction: column;
    margin-bottom: 15px;
    gap: 10px;
    border-bottom: 1px dashed #eee;
    padding-bottom: 15px;
}

.news-item:last-child {
    border-bottom: none;
    margin-bottom: 0;
    padding-bottom: 0;
}

.news-item img {
    max-width: 100%;
    height: auto;
    border-radius: 4px;
}

.news-content h4 {
    font-size: 1.1em;
    margin-bottom: 5px;
    color: #2c3e50;
}

.news-content p {
    font-size: 0.9em;
    color: #777;
    line-height: 1.4;
}

@container news-widget (min-width: 350px) {
    .news-item {
        flex-direction: row; /* وقتی کانتینر پهن شد، تصویر و متن کنار هم */
        align-items: flex-start;
    }
    .news-item img {
        max-width: 100px;
        margin-right: 15px;
    }
}
@container news-widget (min-width: 500px) {
    .news-item img {
        max-width: 150px;
    }
    .news-content h4 {
        font-size: 1.2em;
    }
    .news-content p {
        font-size: 1em;
    }
}

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

ویژگی‌های پیشرفته و ملاحظات مهم

Units Based on Container (واحدهای وابسته به کانتینر)

شاید بدونی که CSS یه سری واحدهای وابسته به viewport داره مثل vw (viewport width) و vh (viewport height). حالا با Container Queries، ما واحدهای مشابهی داریم که به جای viewport، به کانتینر خودشون اشاره می‌کنن:

  • cqw: ۱ درصد از عرض کانتینر (Container Query Width)
  • cqh: ۱ درصد از ارتفاع کانتینر (Container Query Height)
  • cqi: ۱ درصد از اندازه اینلاین کانتینر (inline size – معمولاً عرض)
  • cqb: ۱ درصد از اندازه بلاک کانتینر (block size – معمولاً ارتفاع)
  • cqmin: مقدار کوچکتر بین cqi و cqb
  • cqmax: مقدار بزرگتر بین cqi و cqb

این واحدها فوق‌العاده کاربردی هستن، چون بهت اجازه میدن المنت‌های داخل کانتینر رو به صورت کاملاً پویا و متناسب با سایز کانتینر، اندازه‌گذاری کنی. مثلاً یه فونت سایز با 2cqi یعنی فونت سایز همیشه ۲ درصد از عرض کانتینر خواهد بود. این یعنی هرچی کانتینر کوچیک‌تر بشه، فونت هم کوچیک‌تر میشه و برعکس. دیگه لازم نیست تو هر @container یه فونت سایز جدید تعریف کنی.

مثال: استفاده از واحدهای کانتینر

.my-component {
    container-type: inline-size;
    padding: 1cqmin; /* padding 1 درصد از اندازه کوچکتر کانتینر */
}

.my-component h3 {
    font-size: 3cqi; /* فونت 3 درصد از عرض کانتینر */
    line-height: 1.2;
}

.my-component p {
    font-size: 1.5cqi; /* فونت 1.5 درصد از عرض کانتینر */
}

این واحدهای جدید برای ایجاد تایپوگرافی و spacing کاملاً پویا، ابزار قدرتمندی به حساب میان.

پشتیبانی مرورگرها (Browser Support)

خبر خوب اینه که Container Queries الان تقریباً توسط همه مرورگرهای مدرن (Chrome, Firefox, Edge, Safari) پشتیبانی میشه. این یعنی می‌تونی با خیال راحت ازش تو پروژه‌های جدیدت استفاده کنی. البته، همیشه بهتره با ابزارهایی مثل Can I Use سازگاری رو چک کنی.

ملاحضه مهم: برای اینکه Container Queries به درستی کار کنه، المنت والد باید یه “containing block” باشه. گاهی اوقات ممکنه نیاز باشه به کانتینرت ویژگی‌های position: relative; یا display: flex; / grid; بدی تا به درستی عمل کنه. البته این همیشه ضروری نیست و بستگی به ساختار دقیق HTML و CSS تو داره.

تفاوت Container Queries با Media Queries: یه مقایسه ساده

برای اینکه این دو مفهوم کاملاً برات جا بیفته، یه مقایسه کوتاه بینشون انجام میدیم.

ویژگی Container Queries Media Queries
مبنای واکنش سایز و استایل المنت والد (Container) سایز و مشخصات کلی Viewport (صفحه نمایش)
دامنه عملکرد لوکال (محلی)، مخصوص کامپوننت گلوبال (سراسری)، مخصوص کل صفحه
هدف اصلی ریسپانسیو کردن کامپوننت‌ها ریسپانسیو کردن ساختار کلی صفحه (Layout)
قابلیت استفاده مجدد خیلی زیاد، کامپوننت‌های خودکار و مستقل کمتر، نیاز به بازنویسی یا اصلاح برای مکان‌های مختلف

عیب‌یابی سریع (Troubleshooting)

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

۱. Container Queryهام کار نمیکنه! چرا؟

  • تعریف کانتینر رو فراموش کردی؟ مطمئن شو المنت والدت container-type: inline-size; یا size; رو داره. اگه این ویژگی نباشه، کوئری هیچ تاثیری نداره.
  • آیا المنت داخل کانتینر هست؟ CSS Selector باید المنت داخل کانتینر رو هدف قرار بده.
  • تداخل با مدیا کوئری‌ها: اگه همزمان Media Query و Container Query داری، مطمئن شو که اولویت‌ها و تداخل‌ها رو درک کردی. معمولاً CQها چون خاص‌تر هستن، اولویت دارن.
  • پشتیبانی مرورگر: هرچند الان گسترده شده، ولی اگه مرورگر خیلی قدیمی استفاده می‌کنی، ممکنه پشتیبانی نشه.

۲. المنت‌های داخل کانتینر، باعث تغییر سایز خود کانتینر میشن و یه حلقه بی‌نهایت ایجاد میشه!

این مشکل رو “Cyclical Dependency” یا “Size Containment Issue” میگن. اگه المنت‌های فرزند روی سایز کانتینر تاثیر بذارن و کانتینر هم بر اساس سایز خودش، استایل فرزندان رو تغییر بده، یه لوپ به وجود میاد. راه حلش اینه که به کانتینرت contain: layout; یا contain: size; یا contain: layout inline-size; رو اضافه کنی. این ویژگی به مرورگر میگه که سایز این المنت رو ایزوله کنه و از فرزندانش تاثیر نگیره یا فقط در جهت مشخصی تاثیر پذیر باشد. مثلاً:

.my-container {
    container-type: inline-size;
    container-name: my-panel;
    contain: layout inline-size; /* جلوگیری از لوپ بی‌نهایت */
    /* یا فقط contain: layout; اگر فقط مشکل layout داری */
}

۳. چگونه Container Queryها را در ابزار توسعه‌دهنده (DevTools) دیباگ کنم؟

اکثر مرورگرهای مدرن، ابزارهای خوبی برای دیباگ CQ ارائه میدن. تو Chrome DevTools، وقتی روی یه کانتینر کلیک می‌کنی، یه گزینه برای فعال کردن “Container badges” میبینی. این باعث میشه مرزهای کانتینرها مشخص بشن و می‌تونی اون‌ها رو Resize کنی و ببینی چطور المنت‌های داخلش واکنش نشون میدن. همچنین، تو پنل Styles، می‌تونی ببینی کدوم @container فعال شده.

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

جمع‌بندی و آینده ریسپانسیو وب

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

دیگه زمانش رسیده که از تفکر “صفحه به صفحه” به تفکر “کامپوننت به کامپوننت” کوچ کنیم. Container Queries ابزاریه که این انتقال رو ممکن می‌کنه. پس شروع کن به آزمایش، یاد بگیر و ازش تو پروژه‌هات استفاده کن تا وب رو جای بهتری برای کاربرانت بسازی. این قدم، یه گام بزرگ به سمت آینده وب فوق ریسپانسیوه.

سوالات متداول (FAQ) درباره Container Queries

Container Query چیست؟

Container Query (کوئری کانتینر) قابلیتی در CSS است که به شما امکان می‌دهد استایل‌های یک المنت را بر اساس اندازه (عرض، ارتفاع یا استایل) المنت والد (container) آن تغییر دهید، نه بر اساس اندازه کلی viewport مرورگر. این قابلیت امکان ساخت کامپوننت‌های واقعاً مستقل و ریسپانسیو را فراهم می‌کند.

چه تفاوتی بین Container Query و Media Query وجود دارد؟

Media Queryها بر اساس مشخصات کلی مرورگر (مثل عرض viewport) استایل‌ها را تغییر می‌دهند و برای تغییر طرح‌بندی (layout) کلی صفحه مناسب هستند. اما Container Queryها بر اساس اندازه المنت والد یک کامپوننت عمل می‌کنند و برای ریسپانسیو کردن خود کامپوننت‌ها، صرف‌نظر از جایگاهشان در صفحه، ایده‌آل هستند.

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

برای تعریف یک المنت به عنوان کانتینر، از ویژگی container-type در CSS استفاده می‌کنید. دو مقدار اصلی دارد: inline-size (برای واکنش به تغییر عرض کانتینر) و size (برای واکنش به تغییر عرض و ارتفاع کانتینر). می‌توانید با container-name نیز برای آن نامی انتخاب کنید.

آیا Container Queryها در همه مرورگرها پشتیبانی می‌شوند؟

بله، Container Queryها در حال حاضر به طور گسترده توسط مرورگرهای مدرن از جمله Chrome، Firefox، Edge و Safari پشتیبانی می‌شوند. می‌توانید برای اطمینان بیشتر، سازگاری را در Can I Use بررسی کنید.

آموزش کار با Container Queries در CSS برای کامپوننت‌های فوق ریسپانسیو (کانتینر کوئری در CSS)

تا حالا شده یک کارت محصول یا یک کامپوننت زیبا طراحی کنی، ولی وقتی توی سایدبار یا بخش‌های کوچک‌تر سایت قرارش می‌دی، کل استایلش بهم بریزه؟ سال‌هاست که توسعه‌دهندکان وب با مِدیا کوئری‌ها (Media Queries) این مشکل رو حل می‌کنن؛ اما مدیا کوئری‌ها یک ایراد بزرگ دارن: اونا فقط به عرض کل صفحه (Viewport) واکنش نشون می‌دن، نه به اندازه خودِ المان مادری که کامپوننت توش قرار گرفته! اینجاست که معجزه‌ای به اسم Container Queries در CSS معرفی شده تا طراحی کامپوننت‌محور رو برای همیشه متحول کنه. در این مقاله به زبان کاملاً ساده، کاربردی و عمیق یاد می‌گیریم چطور از کانتینر کوئری‌ها برای خلق کامپوننت‌های فوق ریسپانسیو استفاده کنیم.

خلاصه کاربردی: تفاوت مدیا کوئری و کانتینر کوئری در یک نگاه

🌍 Media Queries

مبنای تصمیم‌گیری: عرض کل مرورگر (Viewport)

مناسب برای چیدمان کلی صفحه (Layout)، هدر، فوتر و ستون‌بندی‌های اصلی سایت.

📦 Container Queries

مبنای تصمیم‌گیری: عرض باکس والد (Parent Container)

مناسب برای کامپوننت‌های مستقل مانند کارت‌ها، منوها و ابزارک‌های قابل جابه‌جایی در صفحات مختلف.

۱. کانتینر کوئری چیست و چرا به آن نیاز داریم؟

برای سال‌ها، ما از مِدیا کوئری‌ها استفاده می‌کردیم تا استایل‌ها را بر اساس اندازه صفحه نمایش گوشی، تبلت یا لپ‌تاپ تغییر دهیم. اما دنیای امروزی طراحی وب بر پایه کامپوننت‌ها می‌چرخد. ما کامپوننت‌ها را یک بار طراحی می‌کنیم و می‌خواهیم در جاهای مختلفی از وب‌سایت استفاده کنیم؛ مثلاً یک کارت خبر را هم در بخش عریض بالای صفحه و هم در بخش سایدبار باریک کناری نمایش دهیم.

اگر با استفاده از مدیا کوئری این کار را انجام دهیم، کارت ما فقط می‌داند که کل مرورگر چقدر عرض دارد؛ ولی نمی‌داند که خودش در یک سایدبار ۳۰۰ پیکسلی قرار گرفته است یا یک بخش محتوای ۸۰۰ پیکسلی! اینجاست که به کانتینر کوئری‌ها نیاز داریم. این تکنولوزی فوق‌العاده به کامپوننت اجازه می‌دهد تا مستقیماً به عرض باکس والد خود واکنش نشان دهد. برای شروع کار با کدهای پایه و تمرین روی کدهای آماده، می‌توانید به بخش قطعه کدهای CSS و همچنین کدهای HTML در وب‌سایت مراجعه نمایید تا ترفندهای بیشتری بیاموزید.

۲. راهنمای قدم‌به‌قدم پیاده‌سازی کانتینر کوئری

استفاده از کانتینر کوئری در CSS به طرز عجیبی ساده است. کل فرآیند را می‌توان در ۲ مرحله اصلی خلاصه کرد:

  1. تعریف باکس والد به عنوان کانتینر: ابتدا باید به مرورگر بگوییم که قصد داریم اندازه این المان را مانیتور کنیم.
  2. نوشتن قوانین کوئری برای فرزندان: حالا با استفاده از دستور @container استایل‌های فرزندان را بر اساس اندازه والد تغییر می‌دهیم.

کدنویسی عملی:

فرض کنید ساختار HTML ما به شکل زیر است:

<div class="card-container">
  <div class="my-card">
    <h3>عنوان محصول جدید</h3>
    <p>توضیحات مربوط به محصول فوق‌العاده ما در اینجا قرار می‌گیرد.</p>
  </div>
</div>

حالا در CSS، کلاس card-container را به عنوان کانتینر هدف معرفی می‌کنیم:

/* ۱. تعریف کانتینر */
.card-container {
  container-type: inline-size;
}

/* ۲. نوشتن کوئری بر اساس سایز کانتینر */
@container (min-width: 450px) {
  .my-card {
    display: flex;
    gap: 20px;
    background-color: #f8fafc;
  }
}

💡 نکته کلیدی: کانتینر کوئری به شما اجازه می‌دهد تا دیگر نگران چیدمان کل صفحه نباشید. هر کامپوننت خودش تصمیم می‌گیرد که در چه فضایی چطور نمایش داده شود!

۳. آشنایی با انواع Container Type

وقتی از ویژگی container-type استفاده می‌کنید، باید به مرورگر بگویید که چه ابعادی را زیر نظر بگیرد. سه مقدار اصلی وجود دارد که می‌توانید استفاده کنید:

  • normal: حالت پیش‌فرض است که المان را به کانتینر کوئری استایل تبدیل نمی‌کند، اما همچنان برای کوئری‌های مربوط به حالت‌های خاص (غیرابعادی) کاربرد دارد.
  • inline-size: محبوب‌ترین و کاربردی‌ترین حالت! این گزینه فقط عرض (Width) المان را زیر نظر می‌گیرد. از آنجا که اکثر طراحی‌های ریسپانسیو بر اساس تغییر عرض افقی هستند، این ویژگی پرمصرف‌ترین گزینه است.
  • size: هم عرض و هم ارتفاع کانتینر را بررسی می‌کند. مراقب باشید استفاده نادرست از این حالت ممکن است باعث ایجاد حلقه‌های تکرار بی‌نهایت و باگ‌های نمایشی شود.

۴. نام‌گذاری کانتینرها (Named Container Queries)

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

/* تعریف نام برای کانتینر */
.sidebar {
  container-name: sidebar-container;
  container-type: inline-size;
}

/* اعمال کوئری به کانتینر خاص بر اساس نام آن */
@container sidebar-container (max-width: 350px) {
  .widget-item {
    font-size: 0.85rem;
    padding: 10px;
  }
}

شما همچنین می‌توانید نام و نوع کانتینر را به صورت خلاصه بنویسید:
container: sidebar-container / inline-size; که خوانایی کدها را بالاتر می‌برد. برای یادگیری و دریافت مجموعه‌های کاملی از این قطعه کدها، همواره می‌توانید بخش قطعه کدها را دنبال کنید.

۵. واحدهای اندازه‌گیری جدید در کانتینرها

همان‌طور که واحدهای vw و vh را برای اندازه صفحه نمایش داریم، واحدهای جدیدی مخصوص کانتینرها به CSS اضافه شده‌اند که مقدار آن‌ها متناسب با ابعاد کانتینر تغییر می‌کند:

  • cqw: ۱ درصد از کل عرض کانتینر (Container Query Width).
  • cqh: ۱ درصد از کل ارتفاع کانتینر (Container Query Height).
  • cqi: ۱ درصد از اندازه اینلاین کانتینر (جهت نگارش افقی معادل عرض است).
  • cqb: ۱ درصد از اندازه بلاک کانتینر (جهت نگارش افقی معادل ارتفاع است).
  • cqmin: کمترین مقدار بین cqi و cqb.
  • cqmax: بیشترین مقدار بین cqi و cqb.

برای مثال، اگر می‌خواهید اندازه عنوان یک کارد کاملاً متناسب با عرض همان کارد ریسپانسیو شود، می‌توانید بنویسید:
font-size: clamp(1rem, 5cqw, 2.5rem);. این یعنی سایز فونت همیشه متناسب با سایز کانتینر تغییر کرده و هیچ‌وقت از بازه تعریف‌شده فراتر نمی‌رود.

۶. جدول مقایسه جامع Media Queries و Container Queries

برای فهم بهتر تفاوت‌ها، جدول مقایسه زیر به شما کمک می‌کند متوجه شوید چه زمانی از کدام ویژگی کاربردی در پروژه‌های خود استفاده کنید:

ویژگی مقایسه Media Query Container Query
مبنای اندازه‌گیری اندازه کل صفحه نمایش (Viewport) عرض المان نگهدارنده (Parent)
تمرکز اصلی چیدمان کلی صفحه (Macro layout) طراحی کامپوننت مستقل (Micro layout)
قابلیت استفاده مجدد پایین (نیاز به بازنویسی در بخش‌های دیگر) بسیار بالا (کاملاً خودکفا)
بهترین مورد مصرف ستون‌بندی، منوهای سراسری، هدر و فوتر کارت‌های محصول، ویجت‌ها، المان‌های فرم

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

۷. عیب‌یابی سریع و رفع مشکلات رایج

گاهی اوقات استفاده از کانتینر کوئری‌ها مطابق انتظار کار نمی‌کند. در اینجا شایع‌ترین مشکلات و راه‌حل‌های عملی آن‌ها آورده شده است:

۱. چرا کدهای کانتینر کوئری من در مرورگر اعمال نمی‌شوند؟

دلیل احتمالی: فراموش کرده‌اید که برای والد، ویژگی container-type را تعریف کنید. یادتان باشد که فرزندان نمی‌توانند بدون داشتن یک والدِ مانیتورشده، اندازه بگیرند. والد حتماً باید این تگ را در CSS خود داشته باشد. همچنین، اگر قصد استفاده از کدهای دیگر دارید، همیشه مطمین شوید که املای نام کلاس‌ها کاملاً تطابق داشته باشد.

۲. مشکل لوپ یا حلقه بی‌نهایت چیست؟

راه‌حل: اگر تلاش کنید عرض خودِ والد را داخل کدهای @container دستکاری کنید، با تغییر اندازه، کوئری دوباره اجرا می‌شود و این فرآیند متوقف نخواهد شد. برای حل این مشکل، هرگز اندازه خود باکس والد را بر اساس کوئری خودش تغییر ندهید؛ بلکه فقط به فرزندان آن استایل بدهید.

۳. عدم کارکرد بر روی تگ‌های inline

کانتینر کوئری‌ها بر روی المان‌های کاملاً inline کار نمی‌کنند. مطمین شوید کانتینر شما دارای خصوصیت display: block یا display: flex/grid باشد.

۸. سوالات متداول (FAQ)

آیا کانتینر کوئری در تمام مرورگرهای وب پشتیبانی می‌شود؟

بله، در حال حاضر تمام مرورگرهای مدرن (Chrome, Firefox, Safari, Edge) به صورت کامل از ویژگی Container Queries در CSS پشتیبانی می‌کنند و با خیال راحت می‌توانید از آن در پروژه‌های صنعتی و واقعی خود استفاده کنید.

آیا می‌توان از کانتینر کوئری و مدیا کوئری همزمان استفاده کرد؟

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

چرا با فعال کردن container-type المان والد ارتفاع خودش را از دست می‌دهد؟

اگر از container-type: size استفاده کنید، چون مرورگر باید اندازه کل والد را مانیتور کند، والد رفتاری شبیه به عدم آگاهی از ارتفاع فرزند پیدا می‌کند تا حلقه تکرار ایجاد نشود. راه‌حل این است که حتماً از inline-size استفاده کنید تا ارتفاع المان تحت تأثیر قرار نگیرد.

جمع‌بندی:

استفاده از Container Queries گام بزرگی برای طراحی‌های فوق ریسپانسیو و مدرن است. با استفاده از این ویژگی، کامپوننت‌های شما نه تنها زیباتر، بلکه مستقل‌تر و قابل‌استفاده‌تر از همیشه خواهند شد. شروع به پیاده‌سازی این تکنیک در پروژه‌های بعدی خود کنید و از کارایی بالای آن لذت ببرید!

Table of Contents

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

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *