مدیا کوئری در CSS؛ تغییر چیدمان از یک ستون به دو و سه ستون

درس 40 از دوره آموزش HTML و CSS ارومیا دیزاین

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

پروژه و پاسخ تمرین: دانلود ZIP پروژه درس 40؛ شامل index.html، style.css، solution.css و راهنمای آزمایش. فایل را استخراج کنید و index.html را باز کنید؛ پروژه بدون اینترنت و نصب ابزار اجرا می شود.

مدیا کوئری چیست و چه چیزی را تغییر می دهد؟

مدیا کوئری یک شرط برای اعمال CSS است. وقتی شرط درست باشد، قواعد داخل آن وارد محاسبه استایل می شوند؛ وقتی شرط درست نباشد، همان قواعد اعمال نمی شوند. شرط می تواند به عرض viewport، نوع رسانه مانند چاپ یا بعضی ویژگی های ورودی کاربر مربوط باشد. برای شروع، روی عرض viewport تمرکز می کنیم و در پایان یک نمونه چاپ و هاور هم می بینیم.

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

ساختار پایه @media را بخوانید

.cards {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 20px;
}

@media (min-width: 600px) {
  .cards {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

در این مثال، cards در حالت پایه یک ستون دارد. شرط min-width: 600px از عرض 600 پیکسل CSS به بالا درست می شود و الگوی ستون را تغییر می دهد. آکولاد بیرونی متعلق به @media و آکولاد داخلی متعلق به انتخابگر است. لازم نیست تمام استایل کارت را دوباره بنویسیم؛ فقط ویژگی ای را که باید تغییر کند اضافه می کنیم.

ویژگی min-width روی عنصر با min-width داخل شرط رسانه یک مفهوم اجرایی یکسان ندارد: اولی حداقل اندازه خود عنصر را تعیین می کند، دومی وضعیت عرض viewport را می سنجد. همچنین این شرط عرض خود cards را بررسی نمی کند. اگر همان کامپوننت داخل یک سایدبار باریک در پنجره عریض باشد، مدیا کوئری همچنان از عرض viewport پیروی می کند؛ برای نیازهای وابسته به ظرف، ابزار دیگری مانند container query مطرح است.

min-width و max-width؛ مرزها شامل مقدار خودشان هستند

@media (min-width: 600px) {
  .notice { padding: 24px; }
}

@media (max-width: 600px) {
  .notice { border-width: 2px; }
}

min-width از مقدار مشخص شده به بالا و max-width از همان مقدار به پایین را شامل می شوند. در عرض دقیقا 600px، هر دو شرط بالا درست هستند. چون ویژگی های متفاوتی را تغییر می دهند، مشکلی نداریم؛ اگر هر دو یک ویژگی را تنظیم کنند، قواعد آبشار نتیجه را مشخص می کنند. تصور نکنید مرورگر یکی را به عنوان حالت موبایل و دیگری را به عنوان حالت دسکتاپ انتخاب می کند.

در رویکرد Mobile First معمولا قواعد پایه را برای عرض کم می نویسیم و با شرط های min-width امکانات چیدمان را افزایش می دهیم. این روش الزام مطلق نیست، اما برای پروژه ما منظم است. از ترکیب بی هدف شرط های حداقل و حداکثر زیاد پرهیز کنید؛ ابتدا رابطه حالت ها را روی کاغذ مشخص کنید تا هم پوشانی غیرمنتظره نسازید.

ساخت پروژه یک، دو و سه ستونی

@media (min-width: 600px) {
  .cards {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 960px) {
  .cards {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

در عرض 960px، شرط 600 و شرط 960 هر دو درست هستند. در این مثال، انتخابگرها هم سطح اند، ویژگی یکسان است و هیچ لایه یا !important متفاوتی نداریم؛ پس قاعده سه ستون که بعدتر آمده، نتیجه نهایی را تعیین می کند. اگر جای این دو بلوک را عوض کنید، در عرض زیاد ممکن است دوباره دو ستون ببینید. خود @media اولویت انتخابگر را بیشتر نمی کند.

در نمونه کامل، نمایشگر وضعیت بالای کارت ها هم با همان شرط ها تغییر می کند تا حالت فعال را ببینید. این نشانگر فقط اطلاعات آموزشی تکراری است؛ برای پنهان کردن محتوای ضروری یا منوی اصلی استفاده نشده است. برای مرور تعریف مسیرها، درس CSS Grid را بخوانید. منوی بالای پروژه نیز با فلکس و wrap مستقل از تعداد ستون کارت ها کار می کند.

عرض viewport در پروژه شرط های عرض فعال تعداد ستون
کمتر از 600px هیچ کدام از دو شرط حداقل یک
از 600px تا کمتر از 960px حداقل 600px دو
از 960px به بالا هر دو شرط سه؛ به دلیل قاعده بعدی هم سطح

نقطه شکست را از محتوا پیدا کنید

نقطه شکست یا breakpoint عرضی است که در آن تغییر مشخصی در طراحی لازم می شود. ابتدا صفحه را باریک کنید و ببینید کجا عنوان بیش از حد فشرده، کارت ها تنگ یا گروه لینک ها نامناسب می شوند. سپس در همان حوالی، چیدمان مناسب تر را تعریف کنید. عددهای 600 و 960 این پروژه نمونه آموزشی هستند؛ برای همه سایت ها و همه فونت ها نسخه ثابت محسوب نمی شوند.

متن واقعی، طول عنوان فارسی، فاصله کارت ها و عرض ظرف بر این تصمیم اثر دارند. سه ستون با عنوان کوتاه ممکن است مناسب باشند، اما با توضیح تخصصی و دکمه بلند فضای بیشتری بخواهند. قبل از ساخت شرط جدید، بررسی کنید آیا انتخاب درست Flexbox و Grid، wrap یا اندازه منعطف می تواند مسئله را ساده تر حل کند. هر تغییر کوچک به breakpoint جدا نیاز ندارد.

ترکیب شرط ها با and و جدا کردن حالت ها با کاما

@media (min-width: 600px) and (max-width: 959px) {
  .panel { padding: 24px; }
}

@media (max-width: 400px), (orientation: landscape) {
  .hint { font-weight: bold; }
}

and یعنی همه شرط های ترکیب شده باید درست باشند. کاما میان دو مدیا کوئری، مانند «یا» عمل می کند؛ کافی است یکی از آن ها درست باشد. در مثال دوم، تاکید متن در عرض حداکثر 400px یا حالت landscape فعال می شود. orientation به نسبت عرض و ارتفاع viewport مربوط است و نباید آن را تشخیص قطعی نوع دستگاه یا چرخش فیزیکی گوشی فرض کنید.

اگر می خواهید یک بازه بدون شکاف کسری تعریف کنید، تفاوت 959 و 960 را جدی بگیرید؛ عرض viewport همیشه مجبور نیست عدد صحیح باشد. نگارش بازه ای جدید، این رابطه را روشن بیان می کند. کد زیر از 600 تا کمتر از 960 را می پوشاند. برای پروژه ای با مرورگرهای قدیمی، پشتیبانی نگارش مورد استفاده را بررسی کنید؛ نسخه پایه این درس از min-width های افزایشی استفاده می کند و به بازه بسته جدا احتیاج ندارد.

@media (600px <= width < 960px) {
  .panel { padding: 24px; }
}

واحد px و em در شرط رسانه

px در شرط عرض، پیکسل CSS است و با تعداد پیکسل های فیزیکی نمایشگر یکی نیست. می توانید در شرط از em هم استفاده کنید؛ مثلا min-width: 40em. در مدیا کوئری، واحدهای نسبی به فونت بر اساس مقدار اولیه فونت محاسبه می شوند، نه لزوما font-size نوشته شده روی body یا html صفحه. بنابراین با تغییر font-size بدنه، فرض نکنید آستانه شرط em هم همان نسبت تغییر کرده است.

برای مقایسه واحدها، درس واحدهای اندازه CSS و برای خوانایی محتوا، درس تایپوگرافی را مرور کنید. مهم تر از انتخاب یک واحد محبوب، روشن بودن منطق آستانه ها و آزمایش خروجی با تنظیمات متفاوت کاربر است.

راهنمای تعیین نقاط شکست؛ قاعده پایه، نیاز محتوا و آزمایش دو طرف مرز با فونت یکان بخ
نقطه شکست را با نیاز محتوا انتخاب کنید و دو طرف مرز را آزمایش کنید.

شرط ها فقط درباره عرض نیستند

@media (hover: hover) and (pointer: fine) {
  nav a:hover { background: #b5dfd6; }
}

@media print {
  nav, .status, .practice { display: none; }
  body { background: white; color: black; }
  .cards { display: block; }
}

در نمونه هاور، شرط ها ویژگی ورودی اصلی را بررسی می کنند؛ آن ها معادل نام دسکتاپ نیستند. تغییر رنگ یک بهبود ظاهری است و هیچ اطلاعات ضروری فقط هنگام هاور نمایش پیدا نمی کند. نشانه فوکوس نیز بیرون این شرط تعریف شده است تا کاربر صفحه کلید همیشه آن را داشته باشد. درس focus-visible را برای مرور این تفاوت ببینید.

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

عیب یابی مدیا کوئری؛ از شرط تا قاعده غالب

ابتدا meta viewport را در head بررسی کنید؛ سپس عرض viewport را در ابزار توسعه ببینید. اگر شرط برقرار نیست، تغییر انتخابگر مسئله را حل نمی کند. اگر شرط برقرار است اما خروجی فرق دارد، در پنل Styles دنبال ویژگی خط خورده و قاعده غالب بگردید. محل فایل، ترتیب قواعد، مشخصات انتخابگر، لایه آبشار و !important می توانند در نتیجه دخالت کنند.

یک اشتباه رایج، نوشتن قاعده پایه با همان اولویت بعد از شرط تکمیلی است؛ در این حالت قاعده پایه می تواند تغییر را برگرداند. آکولاد بسته نشده هم ممکن است ساختار بعدی را خراب کند. برای مرور اتصال فایل و انتخابگر، مقدمات CSS را ببینید. برای اسکرول افقی، صرفا breakpoint اضافه نکنید؛ اندازه ثابت، padding و حداقل اندازه آیتم را هم بررسی کنید.

آزمایش روی مرز و دو طرف آن

برای پروژه، عرض های 599، 600، 959 و 960 پیکسل را بررسی کنید و تعداد ستون را با Grid overlay ببینید. در 600 باید دو ستون و در 960 باید سه ستون داشته باشید. سپس عرض را پیوسته حرکت دهید، نه فقط بین چند عدد. متن یک کارت را بلند کنید و بزرگ نمایی را افزایش دهید؛ هیچ لینک ضروری نباید پشت برش یا هم پوشانی بماند.

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

تمرین مستقل و پاسخ درس 40

گروه tools در بخش practice پروژه، در حالت پایه ستونی است. از عرض حداقل 720px آن را ردیفی و چندخطی کنید. قواعد اصلی را تکرار نکنید؛ فقط ویژگی های لازم را تغییر دهید. بعد پاسخ را در 719 و 720 پیکسل بررسی کنید. فایل solution.css پاسخ را دارد و از ابتدا فعال نیست.

@media (min-width: 720px) {
  .practice .tools {
    flex-direction: row;
    flex-wrap: wrap;
  }
}

برای فعال کردن پاسخ، خط زیر را پس از style.css در head قرار دهید. سپس یک لینک با متن بلند اضافه کنید و ببینید چرا wrap مهم است. در پاسخ درست، همه لینک ها در نسخه باریک باقی می مانند و در فضای بیشتر می توانند به ردیف و در صورت نیاز به خط بعد بروند.

<link rel="stylesheet" href="solution.css">

پرسش های متداول

آیا min-width: 600px شامل خود 600 هم می شود؟

بله؛ شرط حداقل، مقدار مرزی را هم شامل می شود. max-width نیز مرز خودش را شامل می شود.

چرا در عرض زیاد شرط کوچک تر هم فعال است؟

چون عرض زیاد از هر دو حداقل عبور کرده است. نتیجه ویژگی های متعارض را قواعد آبشار مشخص می کنند.

آیا @media اولویت انتخابگر را بیشتر می کند؟

خیر؛ شرط تعیین می کند قاعده وارد محاسبه شود یا نه. اولویت خود انتخابگر با قرار گرفتن در مدیا کوئری افزایش پیدا نمی کند.

آیا عددهای 600 و 960 برای همه سایت ها مناسب هستند؟

خیر؛ این ها آستانه های آموزشی پروژه اند. نقطه شکست واقعی را با محتوا و طراحی انتخاب کنید.

آیا پروژه پاسخ تمرین هم دارد؟

بله؛ HTML، CSS اصلی، solution.css و راهنمای آزمایش آفلاین داخل ZIP هستند.

دانلود پروژه و پاسخ تمرین مدیا کوئری درس 40

برای مطالعه تکمیلی: راهنمای مدیا کوئری در MDN. در اجرای پروژه، مهم ترین تمرین این است که برای هر تغییر چیدمان، شرط فعال و قاعده غالب را توضیح دهید.

5/5 - (3 امتیاز)

بدون دیدگاه

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