طراحی سایت

طراحی واکنشگرا چیست

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

  • درس ۵ از ۱۲
  • مقدماتی
  • رایگان، بدون ثبت نام

یک چیدمان، و عرض هایی که باید در آنها کار کند

ستون سمت راست عرض نمایشگر است. سه نشان پایین، سه باند واقعی همین سایت اند.

۱۲۰۰ ۰
۳۲۰ پیکسلکف عرضی که WCAG می گوید محتوا باید در آن بدون اسکرول افقی کار کند
  • زیر ۶۴۰ پیکسلپرتکرارترین مرز این سایت. همه چیز تک ستونی می شود.
  • ۶۴۱ تا ۱۱۰۰ پیکسلتبلت و لپ تاپ کوچک. هدر هنوز نوار موبایل است.
  • ۱۱۰۱ پیکسل به بالاهدر دسکتاپ و مگامنو روشن می شوند.

۳۲۰ کف است نه هدف، و ۱۲۰۰ سقف ستون محتوای همین سایت است نه یک استاندارد. عدد شما از جایی می آید که چیدمان خودتان می شکند.

آخرین بررسی: فکت ها و نام ابزارهای این درس در همین تاریخ با منابعشان بازبینی شده اند.

طراحی واکنشگرا دقیقا یعنی چه؟

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

این تنها راه نبوده است. سال ها دو راه دیگر هم رایج بود: یک سایت جدا روی زیردامنه موبایل، و سرو کردن HTML متفاوت از سرور بر اساس دستگاه. هر دو هنوز کار می کنند و هر دو دو برابر کار دارند، چون هر تغییری باید دو جا انجام شود. گوگل هم در سند فهرست گذاری موبایل اول خودش می گوید در حالت واکنشگرا محتوا و متادیتا روی موبایل و دسکتاپ یکی است، و برای آن دو حالت دیگر توضیح جداگانه می دهد.

عملا یک خط این را روشن می کند. بدون این خط، مرورگر موبایل صفحه را در یک بوم مجازی حدود ۹۸۰ پیکسلی می کشد و بعد کوچکش می کند؛ نتیجه همان صفحه ای است که باید با دو انگشت بزرگش کنید:

<meta name="viewport" content="width=device-width, initial-scale=1">

روی همین سایت این خط در خط چهاردهم header.php قالب نشسته است. مهم نیست چند مدیا کوئری بنویسید؛ اگر این نباشد هیچ کدامشان آن طور که انتظار دارید عمل نمی کنند.

چرا از باریک ترین حالت شروع می کنیم؟

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

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

یک برداشت غلط را هم همین جا تمام کنیم: موبایل اول یعنی ترتیب نوشتن، نه اینکه نسخه موبایل کم محتواتر باشد. گوگل صریح می گوید محتوای نسخه موبایل باید معادل نسخه دسکتاپ باشد و اگر کمتر است باید کاملش کنید. طراحی می تواند فرق کند؛ محتوا نه.

از باریک شروع کنیم یا از پهن؟ هر دو واقعی اند

تفاوت در توانایی نیست، در نقطه شروع است و در اینکه سایت شما تازه است یا قدیمی.

شروع از باریک، با min-width

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

شروع از پهن، با max-width

  • حالت پایه همان چیدمان دسکتاپ موجود است
  • برای واکنشگرا کردن یک سایت قدیمی کم دردسرتر
  • هر بریک پوینت یک لایه بازنویسی اضافه می کند
  • با زیاد شدن کوئری ها ردیابی سخت می شود

ترکیب کردن این دو در یک فایل، همان جایی است که CSS از دست آدم در می رود. یکی را انتخاب کنید و در کل پروژه به آن بمانید.

عدد بریک پوینت را از کجا برداریم؟

از چیدمان خودتان، نه از فهرست دستگاه ها. این مهم ترین جمله این درس است و بیشتر آموزش ها خلافش را می گویند: عددهای ۷۶۸ و ۹۹۲ و ۱۲۰۰ که همه جا تکرار می شوند، پیش فرض یک فریمورک اند و ربطی به سایت شما ندارند.

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

مثال زنده اش همین سایت است. فایل main.css قالب ۴۳ بلوک مدیا کوئری دارد که روی هم ۱۷ مرز عرضی جدا می سازند: ۴۳۰، ۵۸۰، ۶۰۰، ۶۴۰، ۷۰۰، ۷۲۰، ۷۸۰، ۸۲۰، ۸۶۰، ۸۸۰، ۹۰۰، ۹۲۰، ۹۸۰، ۱۱۰۰، ۱۲۵۹، ۱۲۹۹ و ۱۳۵۹. هیچ کدام ۷۶۸ یا ۹۹۲ نیستند. عدد بلوک ها از عدد مرزها بیشتر است چون بعضی مرزها دو بار نوشته شده اند، یکی با max-width و یکی با min-width یک پیکسل بالاتر: ۶۴۰ و ۶۴۱، و ۱۱۰۰ و ۱۱۰۱. هر عدد داستان خودش را دارد: زیر ۱۱۰۰ هدر شیشه ای دسکتاپ جایش را به نوار موبایل می دهد، و زیر ۷۸۰ هر جدول محتوایی که سه ستون یا بیشتر داشته باشد به کارت های زیر هم تبدیل می شود، چون یک جدول سه ستونی روی گوشی خواندنی نیست.

یک نکته که وقت زیادی می برد تا آدم یاد بگیرد: بریک پوینت مال کامپوننت است نه مال صفحه. کارتی که در یک ستون باریک نشسته، در عرض کل صفحه نمی شکند؛ در عرض ظرف خودش می شکند. برای همین است که @container در CSS اضافه شد، و برای همین است که همان کارت را می شود در دو جای مختلف صفحه گذاشت و در یکی درست باشد و در دیگری نه.

واحد نسبی، ظرف، و تصویری که جایش را از قبل می گیرد

مدیا کوئری آخرین ابزار است نه اولین. اگر چیدمان از اول با واحد نسبی نوشته شود، بیشتر عرض ها را بدون هیچ کوئری رد می کند. عرض ها را درصدی یا با fr در گرید بدهید، اندازه فونت را با rem، و جایی که واقعا لازم است از clamp() استفاده کنید تا یک مقدار بین دو مرز نرم حرکت کند. px برای حاشیه و ضخامت خط جای خودش را دارد؛ برای عرض یک بلوک معمولا نه.

ظرف را هم محدود کنید، نه نمایشگر را. روی همین سایت یک متغیر به اسم --wrap با مقدار ۱۲۰۰ پیکسل وجود دارد و ستون محتوا از آن پهن تر نمی شود، هر چقدر هم مانیتور بزرگ باشد. دلیلش زیبایی نیست: خط متنی که خیلی بلند شود، چشم موقع برگشتن به ابتدای خط بعدی گم می شود.

راست چین بودن اینجا وارد می شود و بیشتر از یک جزئیات است. اگر به جای margin-left بنویسید margin-inline-start، همان یک فایل CSS هم برای فارسی و عربی کار می کند و هم برای انگلیسی و ترکی، و مرورگر جهت را از dir روی تگ html می خواند. این ادعا روی همین سایت قابل شمردن است: در کل main.css هفتاد اعلان با واحد منطقی وجود دارد و صفر مورد margin-left، margin-right، padding-left یا padding-right.

و تصویرها. هر img باید width و height داشته باشد، حتی وقتی با CSS اندازه اش عوض می شود. مرورگر از نسبت این دو، جای تصویر را قبل از رسیدن فایل خالی نگه می دارد و متن زیرش موقع لود شدن نمی پرد. کنارش srcset و sizes بگذارید تا گوشی نسخه کوچک را بگیرد نه نسخه دسکتاپ را. در پست های بلاگ همین سایت هر تصویر هر دو را دارد و تصویر شاخص دو عرض ۷۲۰ و ۱۲۰۰ پیکسلی را عرضه می کند.

چه چیزی را چک کنیم و چه چیزی واکنشگرا بودن نیست

چک لیست واکنشگرا بودنقبل از انتشار

این ها را چک کنید

  • تگ viewport در head هست
  • در ۳۲۰ پیکسل اسکرول افقی وجود ندارد
  • با زوم چهارصد درصد محتوا هنوز خوانده می شود
  • هر تصویر width و height دارد
  • دکمه ها و آیکن ها دست کم ۲۴ در ۲۴ پیکسل اند
  • همان محتوای دسکتاپ روی موبایل هم هست

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

  • پنهان کردن نصف صفحه روی موبایل با display none
  • کوچک کردن کل صفحه با زوم به جای چیدمان دوباره
  • ساختن یک زیردامنه جدا برای موبایل
  • کپی کردن بریک پوینت های یک فریمورک بدون تست

این فهرست جای تست روی گوشی واقعی را نمی گیرد. شبیه ساز مرورگر انگشت را شبیه سازی نمی کند و اینترنت کند را هم نه.

قبل از اینکه بگویید واکنشگراست، این سه چیز را چک کنید

اول، ۳۲۰ پیکسل. معیار Reflow در استاندارد WCAG می گوید محتوا باید در عرض معادل ۳۲۰ پیکسل CSS بدون اسکرول دو طرفه قابل استفاده باشد. بیشتر آدم ها فکر می کنند این عدد مال گوشی های قدیمی است، ولی نکته خود سند جای دیگری است: ۳۲۰ پیکسل معادل یک نمایشگر ۱۲۸۰ پیکسلی است که روی زوم چهارصد درصد باشد. یعنی این معیار در واقع درباره کسی است که چشمش خوب نمی بیند و صفحه را بزرگ کرده، نه درباره گوشی.

دوم، اندازه چیزی که باید لمس شود. معیار دیگری از همان استاندارد می گوید هدف های اشاره گر باید دست کم ۲۴ در ۲۴ پیکسل CSS باشند، مگر آنکه فاصله کافی دورشان باشد. آیکن های کنار هم در فوتر و دکمه های حذف در یک جدول، دو جایی هستند که این قاعده معمولا رد می شود.

سوم، محتوا. نسخه ای که روی موبایل می بینید همان چیزی را می گوید که نسخه دسکتاپ می گوید؟ اگر یک بخش با display: none فقط روی موبایل پنهان شده، آن بخش برای گوگل هم عملا کم رنگ شده، چون فهرست گذاری بر اساس نسخه موبایل انجام می شود.

و یک استثنا که خود W3C می گوید: محتوایی که ذاتا دو بعدی است، مثل یک جدول داده بزرگ یا یک نقشه، از این معیار مستثناست. راه حل چنین چیزی این نیست که در ۳۲۰ پیکسل بچپانیدش؛ این است که خودش داخل یک ظرف اسکرول شونده بماند و بقیه صفحه نه.

مسیر سریع با هوش مصنوعی

مدل های زبانی مدیا کوئری را در چند ثانیه می نویسند. کاری که نمی توانند بکنند این است که بدانند چیدمان <em>شما</em> کجا می شکند، و چون نمی دانند، عددهای رایج آموزش ها را می گذارند. پس مسیر سریع این نیست که از مدل بریک پوینت بخواهید؛ این است که خودتان اندازه بگیرید و مدل فقط CSS را بنویسد. یک مدل سریع و ارزان برای این کار کافی است، چون تبدیل یک فهرست عدد به چند قاعده کار مکانیکی است؛ انتخاب فعلی ما در <a class="text-link" href="/ai/">بخش هوش مصنوعی</a> هست.

  1. صفحه را باز کنید و پنجره را کم کم باریک کنید. هر عرضی که چیزی در آن واقعا خراب می شود را با یک جمله یادداشت کنید: چه چیزی و چطور. سه چهار عرض طبیعی است.
  2. فقط CSS همان کامپوننت را بردارید، نه کل فایل. مدل با پنجاه خط بهتر از پنج هزار خط کار می کند و شما هم خروجی را راحت تر می خوانید.
  3. نسخه پایین را با عرض ها و توضیح هایتان پر کنید و اجرا کنید.
  4. CSS را بگذارید و دوباره باریک کنید. اگر شکستن تازه ای پیدا شد، آن را به فهرست اضافه کنید و نسخه را دوباره اجرا کنید؛ کوئری جدید را دستی روی خروجی نچسبانید.
  5. دو چیز آخر را خودتان چک کنید: ۳۲۰ پیکسل، و اندازه دکمه ها روی یک گوشی واقعی. این دو تا را هیچ مدلی برایتان انجام نمی دهد.

نسخه آماده کپی

این CSS مربوط به کامپوننت {نام کامپوننت} است:

{CSS را اینجا بچسبانید}

روی این عرض ها چیدمان می شکند:
- {عرض}px: {چه چیزی خراب می شود}
- {عرض}px: {چه چیزی خراب می شود}

کمترین تعداد مدیا کوئری را بنویس که فقط همین شکستن ها را درست کند.
قواعد:
۱) از min-width استفاده کن. حالت پایه بدون مدیا کوئری باید همان حالت باریک باشد.
۲) به جای margin-left و padding-right از margin-inline-start و padding-inline-end استفاده کن.
۳) هیچ عرض ثابت px نگذار مگر همان عددهایی که خودم دادم.
۴) هیچ بریک پوینتی اضافه نکن که من در فهرست بالا نگفته ام.
۵) بالای هر کوئری یک کامنت یک خطی بنویس که چرا دقیقا همان عدد.
خروجی فقط CSS باشد.

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

هوش مصنوعی در این کار

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

ابزارهایی که واقعا کمک می کنند

  • Claude در بازنویسی یک فایل CSS طولانی به واحدهای منطقی و توضیح خط به خط آن خوب جواب می دهد. ایران در هیچ کدام از دو فهرست کشورهای پشتیبانی شده انتروپیک نیست؛ این را از صفحه خود انتروپیک خوانده ایم.
  • Gemini برای سوال های کوتاه درباره یک قاعده و برای گرفتن نسخه گرید یک چیدمان کافی است و فارسی را خوب می فهمد. صفحه خود گوگل می گوید اپ وب جمنای در بیش از دویست و سی کشور و منطقه کار می کند و ایران در آن فهرست نیست.
  • ChatGPT رایج ترین انتخاب و برای این کارها قابل قبول. درباره دسترسی و قیمتش اینجا ادعایی نمی کنیم: صفحه کشورهای پشتیبانی شده OpenAI به سرور ما پاسخ ۴۰۳ می دهد و ما ادعایی نمی نویسیم که پشتش چیزی نباشد.

کجا نتیجه معکوس می دهد

خطر اصلی اینجا عدد است. مدل ها روی یک دهه آموزش و پیش فرض فریمورک ها تربیت شده اند، و در استفاده خودمان بارها دیده ایم که وقتی عرض را نگویید، ۷۶۸ و ۹۹۲ را می گذارند؛ عددهایی که در کل main.css همین سایت حتی یک بار هم نیامده اند. نتیجه اش سایتی است که در تست شبیه ساز خوب به نظر می رسد و در عرض واقعی کاربر می شکند. خطر دوم ظریف تر است: مدل نمی تواند چیزی را که اندازه نگرفته قضاوت کند. نه کنتراست را از روی متن می سنجد و نه Reflow را تست می کند، و راهنمای Easy Checks خود W3C هم می گوید بررسی خودکار جای بررسی انسانی را نمی گیرد. پس عددها را خودتان اندازه بگیرید و قاعده را از مدل بخواهید. برای اینکه بدانید هر ابزار از ایران چطور قابل پرداخت است، راهنمای خرید را ببینید.

منبع ها: W3C: Understanding SC 1.4.10 Reflow W3C WAI: Easy Checks Anthropic: supported countries Google: where Gemini Apps are available

حد این توصیه

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

از تجربه خود ما

قاعده «بریک پوینت مال چیدمان شماست» را می شود روی همین سایت شمرد. فایل main.css قالب rgb.ir در روزی که این درس بررسی شد ۴۳ بلوک مدیا کوئری داشت که روی هم ۱۷ مرز عرضی جدا می سازند، و کوچک ترینشان ۴۳۰ و بزرگ ترینشان ۱۳۵۹ است. هیچ کدام ۷۶۸ یا ۹۹۲ نیستند، یعنی هیچ کدام از فهرست دستگاه ها یا پیش فرض یک فریمورک نیامده اند. عدد ۱۲۰۰ در همین فایل هست ولی به عنوان بریک پوینت نیست: مقدار متغیر --wrap است، یعنی سقف عرض ستون محتوا. و یک عدد دیگر که همان جا قابل شمردن است: در کل این فایل هفتاد اعلان با واحد منطقی وجود دارد و صفر مورد margin-left یا padding-right، که دلیلش هم ساده است؛ همین یک فایل باید هم فارسی و عربی راست چین را بچرخاند و هم انگلیسی و ترکی را. همه این ها را می شود با یک grep روی همان فایل دوباره شمرد.

سوال هایی که واقعا پرسیده می شوند

واکنشگرا با موبایل فرندلی فرق دارد؟

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

چند بریک پوینت لازم است؟

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

سایت واکنشگرا رتبه بهتری می گیرد؟

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