@container در CSS: طراحی واکنشگرا مبتنی بر کامپوننت با قدرت کانتینرها
دستور @container
در CSS: انقلابی در طراحی واکنش گرا مبتنی بر کامپوننت
سلام به همه پیشگامان و علاقه مندان به جدیدترین قابلیت های CSS! در دنیای طراحی وب، ما همواره به دنبال راه هایی برای ساخت رابط های کاربری انعطاف پذیرتر و قابل استفاده مجدد بوده ایم. طراحی واکنش گرا (Responsive Design) به ما آموخت که چگونه صفحات وب خود را بر اساس اندازه صفحه نمایش کاربران تطبیق دهیم. اما گاهی اوقات، چیدمان یک کامپوننت (مانند یک کارت، یک فرم، یا یک ویجت) به ابعاد خود کامپوننت وابسته است، نه به اندازه کلی صفحه نمایش. برای مثال، یک کارت ممکن است در یک صفحه عریض به صورت افقی نمایش داده شود، اما در یک ستون باریک تر، به صورت عمودی. تا همین اواخر، دستیابی به چنین رفتاری نیازمند استفاده از جاوا اسکریپت یا تکنیک های پیچیده CSS بود. اما حالا، با دستور @container
و مفهوم Container Queries، CSS به ما ابزاری قدرتمند برای دستیابی به این هدف می دهد. این دستور به ما اجازه می دهد تا استایل ها را مستقیماً بر اساس ابعاد عنصر والد (کانتینر) اعمال کنیم، که این امر انقلابی در نحوه طراحی کامپوننت های مستقل و واکنش گرا ایجاد می کند. در این راهنمای جامع، به بررسی عمیق دستور @container
، نحوه عملکرد آن، سینتکس، کاربردها و مثال های عملی خواهیم پرداخت.
دستور @container
یکی از قابلیت های جدید و قدرتمند CSS است که امکان تعریف Container Queries را فراهم می کند. برخلاف Media Queries که استایل ها را بر اساس ویژگی های دستگاه (مانند اندازه صفحه نمایش) اعمال می کنند، Container Queries استایل ها را بر اساس ابعاد و ویژگی های عنصر والد یا کانتینری که یک عنصر در آن قرار دارد، اعمال می کنند.
این قابلیت به توسعه دهندگان اجازه می دهد تا کامپوننت های UI را به صورت مستقل طراحی کنند که رفتار و ظاهرشان بر اساس فضایی که در آن قرار می گیرند، تغییر کند، بدون اینکه نیازی به دانستن اندازه کلی صفحه نمایش باشد.
چرا به @container
نیاز داریم؟ محدودیت های Media Queries
@container
، ابتدا باید محدودیت های Media Queries را درک کنیم.
Media Queries:
- مبنا: بر اساس ویژگی های دستگاه یا viewport (مانند
min-width
,max-width
,orientation
). - کاربرد: برای تطبیق کل صفحه یا بخش های بزرگ صفحه با اندازه های مختلف صفحه نمایش (دسکتاپ، تبلت، موبایل).
- مشکل: اگر یک کامپوننت (مثلاً یک کارت) در چندین نقطه از صفحه یا در طرح بندی های مختلف (مانند گرید دو ستونی یا سه ستونی) استفاده شود، هر بار که ابعاد صفحه نمایش تغییر می کند، ما نیاز داریم تا Media Query های مختلفی را برای تطبیق ظاهر کامپوننت در آن شرایط خاص تعریف کنیم. این می تواند منجر به کد CSS تکراری و مدیریت دشوار شود.
مثال محدودیت Media Query: فرض کنید یک کارت داریم که می خواهیم در عرض صفحه نمایش بزرگ، عنوان آن بزرگتر باشد و در عرض صفحه نمایش کوچک، عنوان کوچکتر شود.
/* برای صفحات عریض */
@media (min-width: 1024px) {
.card {
/* استایل های کارت برای صفحه عریض */
}
.card-title {
font-size: 24px;
}
}
/* برای صفحات متوسط */
@media (min-width: 768px) and (max-width: 1023px) {
.card {
/* استایل های کارت برای صفحه متوسط */
}
.card-title {
font-size: 20px;
}
}
/* برای صفحات کوچک */
@media (max-width: 767px) {
.card {
/* استایل های کارت برای صفحه کوچک */
}
.card-title {
font-size: 16px;
}
}
در این مثال، ما برای هر اندازه صفحه نمایش، استایل های مربوط به کارت و عنوان آن را جداگانه تعریف کرده ایم. این کار زمانی که کامپوننت کارت در چندین مکان مختلف با اندازه های متفاوت ظاهر می شود، بسیار تکراری و مدیریت ناپذیر می شود.
Container Queries و @container
:
- مبنا: بر اساس ابعاد و ویژگی های کانتینر والد (عنصر حاوی).
- مزیت: به شما اجازه می دهد تا استایل های یک کامپوننت را مستقیماً بر اساس فضایی که در آن قرار دارد، تغییر دهید. این بدان معناست که یک کامپوننت می تواند “بداند” که در چه فضایی قرار گرفته و بر اساس آن خود را تطبیق دهد، بدون اینکه نیازی به دانستن اندازه کلی صفحه نمایش باشد.
- نتیجه: کامپوننت ها مستقل تر، قابل استفاده مجددتر و نگهداری آن ها آسان تر می شود.
با @container
، ما می توانیم به جای نوشتن استایل برای “اندازه صفحه نمایش”، استایل برای “اندازه کانتینر” بنویسیم.
نحوه استفاده از @container
و سینتکس Container Queries
@container
برای اعمال استایل ها بر اساس ابعاد آن کانتینر استفاده نمایید.
مراحل:
-
تعریف کانتینر:
-
برای اینکه یک عنصر به عنوان کانتینر برای Container Queries عمل کند، باید یکی از ویژگی های زیر را داشته باشد:
container-type
: نوع کوئری که می خواهید بر اساس آن استایل دهید (مانندnormal
,inline-size
,block-size
,size
). رایج ترین مقدارnormal
است که بر اساس عرض و ارتفاع عمل می کند.inline-size
فقط بر اساس جهت خط (عرض در زبان های LTR) عمل می کند.container-name
: یک نام دلخواه برای کانتینر (اختیاری). این امکان را می دهد که کوئری ها را به کانتینرهای خاصی ارجاع دهید.
-
مثال:
.my-component-container { container-type: normal; /* یا inline-size */ container-name: sidebar; /* نام اختیاری */ width: 300px; /* یا هر ابعاد دیگری */ height: 400px; border: 1px solid red; } .my-component { /* استایل های پیش فرض کامپوننت */ }
نکته: تعریف
container-type
الزامی است.container-name
اختیاری است اما برای ارجاع به کانتینرهای خاص مفید است.
-
-
نوشتن Container Queries با
@container
:-
دستور
@container
شبیه به@media
است، اما به جای ویژگی های صفحه نمایش، از ویژگی های کانتینر (مانندmin-width
,max-width
,inline-size
,block-size
,aspect-ratio
) استفاده می کند. -
سینتکس پایه:
@container [name] (condition) { /* استایل هایی که زمانی اعمال می شوند که شرط برقرار باشد */ selector { property: value; } }
[name]
: نام کانتینر (اگر نام گذاری کرده اید). اگر نامی مشخص نکنید، کوئری به نزدیک ترین کانتینر والد اعمال می شود.(condition)
: شرطی که بر اساس ابعاد کانتینر بررسی می شود (مانندmin-width: 500px
).
-
مثال بازگشت به مثال کارت: با استفاده از @container
، می توانیم همان مثال کارت را به شکلی بسیار تمیزتر و مستقل تر پیاده سازی کنیم.
HTML:
<div class="card-container">
<div class="card">
<img src="image.jpg" alt="مثال" class="card-image">
<h3 class="card-title">عنوان کارت</h3>
<p class="card-description">این یک توضیح کوتاه برای کارت است.</p>
</div>
</div>
<div class="card-container narrow-container">
<div class="card">
<img src="image.jpg" alt="مثال" class="card-image">
<h3 class="card-title">عنوان کارت</h3>
<p class="card-description">این یک توضیح کوتاه برای کارت است.</p>
</div>
</div>
CSS:
/* تعریف کانتینرها */
.card-container {
container-type: normal; /* یا inline-size */
width: 40%; /* مثال: کانتینر اول 40% عرض صفحه را می گیرد */
margin-bottom: 20px;
}
.narrow-container {
width: 20%; /* مثال: کانتینر دوم 20% عرض صفحه را می گیرد */
}
/* استایل های پیش فرض کارت */
.card {
border: 1px solid #ccc;
padding: 15px;
background-color: #f9f9f9;
display: flex; /* برای چیدمان داخلی */
flex-direction: column; /* چیدمان پیش فرض عمودی */
align-items: center; /* وسط چین کردن عناصر */
text-align: center; /* وسط چین کردن متن */
}
.card-image {
max-width: 100px;
height: auto;
margin-bottom: 10px;
}
.card-title {
font-size: 18px; /* اندازه فونت پیش فرض */
margin-bottom: 5px;
}
.card-description {
font-size: 14px;
color: #555;
}
/* Container Queries برای کارت */
@container (min-width: 600px) {
/* اگر کانتینر حداقل 600px عرض داشته باشد */
.card {
flex-direction: row; /* تغییر چیدمان به افقی */
align-items: flex-start; /* هم ترازی عناصر به سمت بالا */
text-align: left; /* متن از چپ */
}
.card-image {
margin-right: 20px; /* فاصله سمت راست تصویر */
margin-bottom: 0; /* حذف فاصله پایین تصویر */
max-width: 150px; /* افزایش اندازه تصویر */
}
.card-title {
font-size: 22px; /* فونت بزرگتر عنوان */
}
.card-description {
font-size: 15px; /* فونت بزرگتر توضیحات */
}
}
@container (min-width: 800px) {
/* اگر کانتینر حداقل 800px عرض داشته باشد */
.card-title {
font-size: 26px; /* فونت عنوان باز هم بزرگتر */
}
}
/* مثال برای کانتینر باریک تر */
@container (max-width: 300px) { /* اگر کانتینر 300px یا کمتر باشد */
.card-image {
max-width: 70px; /* تصویر کوچکتر */
}
.card-title {
font-size: 16px; /* عنوان کوچکتر */
}
}
در این مثال، استایل های کارت (چیدمان، اندازه فونت، اندازه تصویر) بر اساس عرض کانتینر والد (.card-container
) تغییر می کنند، نه بر اساس اندازه کلی صفحه نمایش. این باعث می شود کامپوننت کارت به طور مستقل واکنش گرا باشد.
کاربردها و سناریوهای خلاقانه
@container
و Container Queries، امکانات جدید و هیجان انگیزی را برای طراحی وب فراهم می کنند. در اینجا چند کاربرد و سناریوی خلاقانه آورده شده است:
-
طراحی کامپوننت های مستقل و قابل استفاده مجدد:
- این اصلی ترین مزیت است. شما می توانید یک کامپوننت (مانند کارت، دکمه، فرم، هدر) را طراحی کنید که ظاهر آن به طور خودکار بر اساس فضایی که در آن قرار می گیرد، تغییر کند. این امر باعث می شود که کامپوننت ها در صفحات مختلف، فوتر، سایدبار، یا حتی درون یکدیگر، به درستی نمایش داده شوند.
-
طراحی واکنش گرا در سطح کامپوننت:
- به جای اینکه فقط کل صفحه را واکنش گرا کنیم، می توانیم هر کامپوننت را به طور مستقل واکنش گرا کنیم. برای مثال، یک جدول ممکن است در یک کانتینر عریض، ستون های بیشتری را نمایش دهد، اما در یک کانتینر باریک تر، فقط ستون های اصلی را نشان دهد و یا به حالت کارت تبدیل شود.
-
استفاده از
inline-size
وblock-size
:- علاوه بر عرض، می توانید از
container-type: inline-size
(که بر اساس جهت متن عمل می کند) یاblock-size
(بر اساس ارتفاع) برای اعمال کوئری ها استفاده کنید. این برای زبان هایی که جهت متن آن ها عمودی است (مانند برخی زبان های آسیایی) یا برای طراحی هایی که به ارتفاع نیز واکنش نشان می دهند، بسیار مفید است. - مثال:
.vertical-card { container-type: block-size; /* کوئری بر اساس ارتفاع */ } @container (min-height: 300px) { .vertical-card { /* استایل ها برای کانتینرهای بلند */ } }
- علاوه بر عرض، می توانید از
-
کامپوننت های تطبیق پذیر در گریدها و فلکس باکس:
- هنگامی که از CSS Grid یا Flexbox برای چیدمان استفاده می کنید، آیتم های گرید یا فلکس می توانند به عنوان کانتینر عمل کنند. شما می توانید استایل های درون این آیتم ها را بر اساس اندازه خود آیتم (که خود تابعی از چیدمان کلی است) تغییر دهید.
-
طراحی الگوهای تکراری (Pattern Libraries):
- Container Queries برای ساخت الگوهای UI که در اندازه های مختلف قابل استفاده هستند، ایده آل است. شما می توانید یک الگو را یک بار طراحی کنید و سپس با استفاده از
@container
، آن را برای نمایش در کانتینرهای مختلف تطبیق دهید.
- Container Queries برای ساخت الگوهای UI که در اندازه های مختلف قابل استفاده هستند، ایده آل است. شما می توانید یک الگو را یک بار طراحی کنید و سپس با استفاده از
-
قابلیت استفاده مجدد بالا (High Reusability):
- توسعه دهندگان می توانند کامپوننت هایی را بسازند که بدون نیاز به تغییرات CSS اضافی، در هر جایی از پروژه قابل استفاده باشند. این امر سرعت توسعه را افزایش داده و خطاهای ناشی از مدیریت استایل های متعدد را کاهش می دهد.
-
مدیریت پیچیدگی در Layout های پیچیده:
- در صفحات یا برنامه هایی با چیدمان های پیچیده و nesting شده (مانند داشبوردها)، Container Queries به شما امکان می دهد تا استایل های داخلی هر بخش را به طور مستقل مدیریت کنید.
مثال خلاقانه: کارت با چیدمان های مختلف فرض کنید یک کارت دارید که:
- در کانتینرهای کوچک (زیر 400px)، فقط تصویر و عنوان بالا و توضیحات پایین باشد (چیدمان عمودی).
- در کانتینرهای متوسط (400px تا 700px)، تصویر در کنار عنوان و توضیحات قرار گیرد (چیدمان افقی).
- در کانتینرهای بزرگ (بالای 700px)، عنوان بزرگتر شده و توضیحات با فونت بزرگتر نمایش داده شود.
این سناریو به راحتی با استفاده از @container
و نام گذاری مناسب کانتینرها قابل پیاده سازی است.
Container Queries با @container
، گامی بزرگ به سوی طراحی کامپوننت محور واقعی و ایجاد وب سایت هایی است که واقعاً “واکنش گرا” در تمام سطوح هستند.
پشتیبانی مرورگر و آینده Container Queries
@container
و قابلیت Container Queries، یکی از بزرگترین پیشرفت های CSS در سال های اخیر محسوب می شود، اما مانند هر تکنولوژی جدیدی، وضعیت پشتیبانی مرورگرها و ملاحظات مربوط به آن اهمیت دارد.
پشتیبانی مرورگر:
- Chrome: پشتیبانی کامل از Container Queries (شامل
@container
وcontainer-type
) از نسخه 105 به بعد. - Edge: پشتیبانی کامل (به دلیل اشتراک در موتور Blink با Chrome).
- Firefox: پشتیبانی از Container Queries از نسخه 117 به بعد به صورت پایدار اضافه شده است.
- Safari: پشتیبانی از Container Queries از نسخه 16.4 به بعد به صورت پایدار اضافه شده است.
وضعیت فعلی: با توجه به پشتیبانی نسبتاً گسترده در مرورگرهای اصلی، Container Queries اکنون به اندازه کافی پایدار هستند که بتوان از آن ها در پروژه های واقعی استفاده کرد، به خصوص اگر استراتژی fallback مناسبی داشته باشید.
ملاحظات مهم برای پیاده سازی:
-
Fallback برای مرورگرهای قدیمی تر:
- مرورگرهایی که از Container Queries پشتیبانی نمی کنند، دستور
@container
را نادیده می گیرند. این بدان معناست که استایل هایی که درون@container
تعریف شده اند، اعمال نخواهند شد. - استراتژی: شما باید استایل های پیش فرض را طوری تعریف کنید که در همه مرورگرها کار کنند (معمولاً استایل های مربوط به کوچکترین اندازه کانتینر). سپس، با استفاده از
@container
، استایل های بهبودیافته را برای کانتینرهای بزرگتر اعمال کنید. این یک رویکرد “Progressive Enhancement” است.
- مرورگرهایی که از Container Queries پشتیبانی نمی کنند، دستور
-
نیاز به تعریف
container-type
:- به یاد داشته باشید که برای فعال شدن Container Queries، عنصر والد باید حتماً
container-type
(مانندnormal
یاinline-size
) داشته باشد. بدون آن،@container
کار نخواهد کرد.
- به یاد داشته باشید که برای فعال شدن Container Queries، عنصر والد باید حتماً
-
نام گذاری کانتینرها (
container-name
):- در طرح بندی های پیچیده که چندین کانتینر وجود دارد، استفاده از
container-name
به شما این امکان را می دهد که کوئری های خود را به یک کانتینر خاص ارجاع دهید، که مدیریت استایل ها را بسیار آسان تر می کند.
- در طرح بندی های پیچیده که چندین کانتینر وجود دارد، استفاده از
-
ترکیب با Media Queries:
- Container Queries جایگزین Media Queries نیستند، بلکه مکمل آن ها هستند. شما همچنان ممکن است نیاز به استفاده از Media Queries برای تنظیمات کلی صفحه نمایش داشته باشید، در حالی که Container Queries را برای رفتار کامپوننت ها در داخل آن چیدمان ها استفاده می کنید.
-
اهمیت
inline-size
وblock-size
:- هنگام کار با زبان های مختلف یا چیدمان هایی که جهت گیری متفاوتی دارند، درک تفاوت بین
normal
(عرض و ارتفاع)،inline-size
(جهت متن) وblock-size
(عمود بر جهت متن) بسیار مهم است.
- هنگام کار با زبان های مختلف یا چیدمان هایی که جهت گیری متفاوتی دارند، درک تفاوت بین
آینده Container Queries: Container Queries یک گام بسیار مهم به سوی طراحی وب مدرن و کامپوننت محور است. انتظار می رود که با افزایش پشتیبانی مرورگرها، این قابلیت به بخشی استاندارد از جعبه ابزار طراحان و توسعه دهندگان CSS تبدیل شود. این امر منجر به ساخت وب سایت هایی با قابلیت استفاده مجدد بالاتر، نگهداری آسان تر و انعطاف پذیری بیشتر خواهد شد.
با استفاده از @container
، ما از یک رویکرد “صفحه محور” به یک رویکرد “کامپوننت محور” در طراحی واکنش گرا حرکت می کنیم که برای ساخت سیستم های طراحی (Design Systems) مدرن بسیار حیاتی است.
نتیجه گیری: قدرتمندسازی کامپوننت ها با @container
@container
و قابلیت Container Queries، یک پیشرفت قابل توجه در CSS است که به ما اجازه می دهد تا طراحی واکنش گرا را از سطح صفحه نمایش به سطح کامپوننت ها گسترش دهیم. با تعریف کانتینرها و استفاده از @container
، می توانیم استایل هایی را اعمال کنیم که به طور مستقل بر اساس ابعاد عنصر والد (کانتینر) تغییر می کنند، نه صرفاً اندازه کلی صفحه نمایش.
این قابلیت، مشکل تکرار کد CSS برای کامپوننت های مشابه در اندازه های مختلف صفحه نمایش را حل می کند و به ما امکان می دهد تا کامپوننت هایی بسازیم که واقعاً مستقل، قابل استفاده مجدد و به طور ذاتی واکنش گرا باشند. از کارت های محصول گرفته تا جداول و فرم ها، هر کامپوننتی می تواند به طور هوشمندانه خود را با فضایی که در آن قرار گرفته، تطبیق دهد.
با توجه به پشتیبانی روزافزون مرورگرها، استفاده از Container Queries اکنون یک استراتژی عملی برای ساخت وب سایت های مدرن و انعطاف پذیر است. با ترکیب @container
با Media Queries و بهترین شیوه های طراحی کامپوننت محور، می توانیم رابط های کاربری قوی تر، قابل نگهداری تر و جذاب تری را خلق کنیم. @container
بدون شک آینده طراحی واکنش گرا را شکل خواهد داد.