آکادمی بنو/آموزش CSS

طراحی Responsive در CSS

بهنام نوبخت · ۱۴۰۵/۶/۲۸

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

Responsive Web Design یا طراحی واکنش‌گرا روشی برای طراحی صفحات وب است که باعث می‌شود ساختار، اندازه، فاصله‌ها، تصاویر و سایر بخش‌های صفحه متناسب با فضای موجود تغییر کنند. به عبارت ساده‌تر، صفحه باید خودش را با محیطی که در آن نمایش داده می‌شود تطبیق دهد.

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

نکته مهم این است که Responsive Design فقط به معنی «کوچک کردن نسخه دسکتاپ» نیست. بلکه باید چیدمان، خوانایی، فاصله‌ها، تصاویر، دکمه‌ها و حتی نحوه تعامل کاربر را متناسب با اندازه صفحه در نظر بگیریم.

در این مقاله با اصول طراحی Responsive، واحدهای انعطاف‌پذیر، Breakpointها، تصاویر Responsive، ترکیب Flexbox و Grid و در نهایت ساخت یک بخش Responsive برای سایت «بنو سرویس» آشنا خواهیم شد.

Responsive Design چیست؟

Responsive Design به مجموعه‌ای از تکنیک‌های HTML و CSS گفته می‌شود که به یک صفحه اجازه می‌دهند در اندازه‌های مختلف صفحه نمایش، ساختار مناسبی داشته باشد.

فرض کنید صفحه اصلی سایت شما در دسکتاپ به این شکل باشد:

┌─────────────────────────────────────────────┐
│                 Header                      │
├─────────────────────────────────────────────┤
│                                             │
│              Hero Section                   │
│                                             │
├────────────┬────────────┬────────────┬──────┤
│   Card 1   │   Card 2   │   Card 3   │ Card4│
└────────────┴────────────┴────────────┴──────┘

اما در موبایل همان محتوا می‌تواند به شکل زیر نمایش داده شود:

┌───────────────────┐
│      Header       │
├───────────────────┤
│                   │
│       Hero        │
│                   │
├───────────────────┤
│      Card 1       │
├───────────────────┤
│      Card 2       │
├───────────────────┤
│      Card 3       │
├───────────────────┤
│      Card 4       │
└───────────────────┘

محتوا تغییر نکرده است؛ چیزی که تغییر کرده نحوه نمایش محتوا است.

چرا طراحی Responsive اهمیت دارد؟

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

اگر یک سایت Responsive نباشد، ممکن است در موبایل مشکلاتی مانند موارد زیر ایجاد شود:

  • ایجاد اسکرول افقی

  • خارج شدن متن از محدوده صفحه

  • کوچک شدن بیش از حد فونت

  • قرار گرفتن دکمه‌ها در کنار یکدیگر و غیرقابل استفاده شدن آن‌ها

  • بزرگ بودن بیش از حد تصاویر

  • فشرده شدن کارت‌ها

  • به‌هم‌ریختن منوی سایت

  • افزایش فاصله‌ها یا کاهش بیش از حد آن‌ها

  • دشوار شدن خواندن محتوا

طراحی Responsive تلاش می‌کند این مشکلات را با استفاده از Layoutهای انعطاف‌پذیر، واحدهای نسبی، Grid، Flexbox و Media Query برطرف کند.

Viewport چیست؟

برای درک Responsive Design ابتدا باید مفهوم Viewport را بشناسیم.

Viewport محدوده‌ای از صفحه است که محتوای وب‌سایت در آن قابل مشاهده است.

برای مثال:

Desktop
Viewport
┌─────────────────────────────────────┐
│                                     │
│              Website                │
│                                     │
└─────────────────────────────────────┘

در موبایل:

Mobile Viewport
┌──────────────────┐
│                  │
│     Website      │
│                  │
└──────────────────┘

عرض Viewport می‌تواند بسته به دستگاه و اندازه پنجره مرورگر متفاوت باشد.

به همین دلیل نباید طراحی خود را به یک اندازه خاص محدود کنیم.

Meta Viewport

برای اینکه طراحی Responsive در مرورگرهای موبایل به شکل مورد انتظار عمل کند، معمولاً باید Meta Viewport را در بخش <head> صفحه قرار دهیم.

<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>

    <meta charset="UTF-8">

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

    <title>Responsive Website</title>

</head>
<body>

</body>
</html>

مهم‌ترین قسمت:

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

یعنی عرض Viewport با عرض دستگاه هماهنگ شود و صفحه با بزرگنمایی اولیه مناسب نمایش داده شود.

اصول اصلی طراحی Responsive

برای ساخت یک سایت Responsive فقط استفاده از @media کافی نیست. بهتر است چند اصل را همزمان رعایت کنیم.

مهم‌ترین اصول عبارت‌اند از:

  1. استفاده از اندازه‌های انعطاف‌پذیر

  2. استفاده از Layoutهای مدرن

  3. تصاویر انعطاف‌پذیر

  4. استفاده صحیح از Breakpointها

  5. Typography Responsive

  6. فاصله‌های Responsive

  7. طراحی مناسب برای لمس در موبایل

  8. جلوگیری از Overflow افقی

استفاده از اندازه‌های انعطاف‌پذیر

یکی از اشتباهات رایج استفاده بیش از حد از اندازه‌های ثابت است.

مثلاً:

.container {
    width: 1200px;
}

این مقدار ممکن است روی مانیتور بزرگ مناسب باشد، اما روی موبایل مشکل ایجاد می‌کند.

بهتر است بنویسیم:

.container {
    width: 100%;
    max-width: 1200px;
    margin-inline: auto;
}

حالا عنصر می‌تواند کوچک شود، اما بیشتر از 1200px رشد نمی‌کند.

استفاده از درصد

واحد % یکی از روش‌های ساده برای ایجاد اندازه‌های انعطاف‌پذیر است.

.card {
    width: 50%;
}

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

مثلاً:

.card {
    width: 33.333%;
}

در یک Layout سه‌ستونه ممکن است مناسب باشد، اما وقتی صفحه کوچک شود، احتمالاً نیاز داریم ساختار را تغییر دهیم.

اینجاست که Flexbox، Grid و Media Query وارد می‌شوند.

استفاده از Grid برای طراحی Responsive

Grid یکی از بهترین ابزارها برای ساخت Layoutهای Responsive است.

مثلاً:

.services {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 24px;
}

در دسکتاپ چهار ستون خواهیم داشت.

اما می‌توانیم در اندازه‌های کوچک‌تر تعداد ستون‌ها را کاهش دهیم:

.services {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 24px;
}

@media (max-width: 1000px) {
    .services {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 600px) {
    .services {
        grid-template-columns: 1fr;
    }
}

در نتیجه:

Desktop

┌──────┬──────┬──────┬──────┐
│  1   │  2   │  3   │  4   │
└──────┴──────┴──────┴──────┘


Tablet

┌──────┬──────┐
│  1   │  2   │
├──────┼──────┤
│  3   │  4   │
└──────┴──────┘


Mobile

┌─────────────┐
│      1      │
├─────────────┤
│      2      │
├─────────────┤
│      3      │
├─────────────┤
│      4      │
└─────────────┘

Responsive بدون Media Query

نکته مهمی که باید بدانید این است که Responsive Design الزاماً به معنی استفاده از Media Query در همه قسمت‌ها نیست.

CSS مدرن امکاناتی مانند:

  • min

  • max

  • clamp

  • minmax

  • fr

  • Flexbox

  • Grid

را در اختیار ما قرار داده است.

مثلاً می‌توانیم یک Grid بسیار انعطاف‌پذیر ایجاد کنیم:

.services {
    display: grid;
    grid-template-columns:
        repeat(auto-fit, minmax(240px, 1fr));

    gap: 24px;
}

در این حالت مرورگر تلاش می‌کند تا جایی که فضای کافی وجود دارد کارت‌ها را کنار هم قرار دهد.

این روش در بسیاری از Layoutهای مدرن بسیار کاربردی است.

minmax چیست؟

تابع minmax یک محدوده حداقل و حداکثر برای اندازه یک Track در Grid مشخص می‌کند.

مثلاً:

grid-template-columns:
    repeat(auto-fit, minmax(250px, 1fr));

یعنی هر ستون:

  • حداقل حدود 250px باشد

  • در صورت وجود فضای بیشتر بتواند رشد کند

این یکی از الگوهای بسیار کاربردی برای ساخت کارت‌های Responsive است.

تصاویر Responsive

تصاویر یکی از مهم‌ترین قسمت‌های طراحی Responsive هستند.

فرض کنید چنین تصویری داریم:

<img src="images/banner.jpg" alt="بنر سایت">

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

راه‌حل ساده:

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

حالا تصویر نمی‌تواند از فضای والد خود بزرگ‌تر شود.

object-fit

گاهی اوقات می‌خواهیم تصویر داخل یک محدوده مشخص قرار بگیرد.

در این حالت object-fit بسیار کاربردی است. این ویژگی مشخص می‌کند تصویر یا ویدئو چگونه داخل جعبه خود قرار بگیرد.

مثلاً:

.card-image {
    width: 100%;
    height: 220px;
    object-fit: cover;
}

با این روش تصویر فضای مشخص‌شده را پر می‌کند و نسبت تصویر حفظ می‌شود.

برای کارت‌های محصول بسیار کاربردی است:

<div class="product-card">

    <img
        src="product.jpg"
        alt="محصول"
        class="card-image"
    >

    <h3>فروشگاه ساز</h3>

</div>
.card-image {
    width: 100%;
    height: 220px;
    object-fit: cover;
    border-radius: 16px;
}

Responsive Typography

فقط Layout نباید Responsive باشد؛ اندازه متن نیز باید متناسب با صفحه تغییر کند.

مثلاً:

h1 {
    font-size: 48px;
}

ممکن است در دسکتاپ مناسب باشد، اما برای موبایل بزرگ باشد.

یک روش استفاده از Media Query است:

h1 {
    font-size: 48px;
}

@media (max-width: 600px) {
    h1 {
        font-size: 32px;
    }
}

اما CSS مدرن راه دیگری نیز در اختیار ما قرار می‌دهد.

تابع clamp

تابع clamp سه مقدار دریافت می‌کند:

clamp(min, preferred, max)

یعنی مقدار نهایی بین حداقل و حداکثر نگه داشته شود.

مثلاً:

h1 {
    font-size: clamp(2rem, 5vw, 4rem);
}

در این حالت اندازه عنوان با اندازه Viewport تغییر می‌کند، اما از مقدار مشخص‌شده کمتر یا بیشتر نمی‌شود.

این تکنیک برای Typography Responsive بسیار مفید است.

مثال دیگر:

.hero-title {
    font-size: clamp(2rem, 5vw, 4.5rem);
}

.hero-description {
    font-size: clamp(1rem, 2vw, 1.25rem);
}

min و max

دو تابع دیگر که در طراحی Responsive بسیار مفید هستند:

min()

و:

max()

مثلاً:

.container {
    width: min(100% - 32px, 1200px);
    margin-inline: auto;
}

در اینجا عرض Container از مقدار مناسب بین گزینه‌های ارائه‌شده انتخاب می‌شود.

این الگو باعث می‌شود در موبایل حاشیه مناسبی داشته باشیم و در دسکتاپ Container بیش از حد بزرگ نشود.

Responsive Spacing

فاصله‌ها نیز باید با اندازه صفحه سازگار باشند.

مثلاً:

.hero {
    padding: 100px 0;
}

ممکن است در موبایل فاصله زیادی ایجاد کند.

می‌توانیم از clamp() استفاده کنیم:

.hero {
    padding-block: clamp(48px, 8vw, 120px);
}

حالا فاصله به شکل نرم‌تری با اندازه صفحه تغییر می‌کند.

برای فاصله افقی نیز می‌توانیم بنویسیم:

.container {
    padding-inline: clamp(16px, 4vw, 48px);
}

Breakpoint چیست؟

Breakpoint نقطه‌ای در Layout است که در آن تصمیم می‌گیریم ساختار یا ظاهر صفحه تغییر کند.

برای مثال ممکن است بگوییم:

عرض کم
    ↓
یک ستون

عرض متوسط
    ↓
دو ستون

عرض زیاد
    ↓
چهار ستون

اما یک نکته بسیار مهم وجود دارد:

Breakpoint نباید صرفاً بر اساس نام دستگاه انتخاب شود.

یعنی نباید بگوییم:

این Breakpoint مخصوص iPhone است.

یا:

این Breakpoint مخصوص تبلت Samsung است.

تعداد و اندازه دستگاه‌ها بسیار زیاد است و دائماً تغییر می‌کند. بهتر است Breakpoint را جایی قرار دهیم که محتوای Layout شروع به خراب شدن می‌کند.

مثلاً اگر منوی شما در عرض 850px دیگر فضای کافی ندارد، همان محدوده می‌تواند Breakpoint مناسبی باشد.

یک نمونه Media Query

ساختار ساده Media Query:

@media (max-width: 768px) {

    .hero {
        padding: 60px 20px;
    }

}

یعنی قوانین داخل این بخش زمانی اعمال شوند که عرض Viewport حداکثر 768px باشد.

طراحی Mobile First

یکی از روش‌های مهم در طراحی Responsive، Mobile First است.

در این روش ابتدا طراحی را برای صفحه کوچک انجام می‌دهیم و سپس برای صفحات بزرگ‌تر امکانات و Layout بیشتری اضافه می‌کنیم.

مثلاً:

.services {
    display: grid;
    grid-template-columns: 1fr;
    gap: 16px;
}

سپس:

@media (min-width: 768px) {

    .services {
        grid-template-columns: repeat(2, 1fr);
    }

}

و در نمایشگر بزرگ‌تر:

@media (min-width: 1100px) {

    .services {
        grid-template-columns: repeat(4, 1fr);
    }

}

این رویکرد باعث می‌شود ساختار پایه ساده و مناسب صفحه‌های کوچک باشد و Layout در اندازه‌های بزرگ‌تر توسعه پیدا کند. MDN نیز Mobile First را یکی از رویکردهای رایج برای طراحی Responsive معرفی می‌کند.

Fixed، Fluid و Adaptive Layout

برای درک بهتر Responsive Design، سه مفهوم مهم را باید بشناسیم.

Fixed Layout

در این روش اندازه‌ها بیشتر ثابت هستند:

.container {
    width: 1200px;
}

این روش برای Responsive Design مناسب نیست مگر اینکه محدودیت‌های دیگری برای آن در نظر گرفته شود.

Fluid Layout

در این روش اندازه‌ها انعطاف‌پذیر هستند:

.container {
    width: 90%;
}

عرض با اندازه فضای موجود تغییر می‌کند.

Adaptive Layout

در این روش Layout در محدوده‌های خاص تغییر می‌کند.

مثلاً:

Mobile → یک ستون
Tablet → دو ستون
Desktop → چهار ستون

Media Query یکی از ابزارهای اصلی برای پیاده‌سازی چنین تغییراتی است.

ترکیب Grid و Flexbox

در پروژه‌های واقعی معمولاً لازم نیست فقط از Grid یا فقط از Flexbox استفاده کنیم.

می‌توانیم آن‌ها را ترکیب کنیم.

مثلاً:

.services {
    display: grid;
    grid-template-columns:
        repeat(auto-fit, minmax(240px, 1fr));

    gap: 24px;
}

و داخل هر کارت:

.service-card {
    display: flex;
    flex-direction: column;
}

یعنی:

Page
 │
 └── Grid
      │
      ├── Card
      │    └── Flexbox
      │
      ├── Card
      │    └── Flexbox
      │
      └── Card
           └── Flexbox

این یکی از الگوهای بسیار رایج در پروژه‌های حرفه‌ای است.

پروژه عملی: بخش خدمات Responsive بنو سرویس

حالا یک بخش واقعی برای سایت «بنو سرویس» طراحی کنیم.

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

  • طراحی سایت

  • طراحی اپلیکیشن

  • سئو

  • ربات تلگرامی

HTML

<section class="services-section">

    <div class="container">

        <div class="section-header">

            <span class="section-label">
                خدمات بنو سرویس
            </span>

            <h2>
                راهکارهای دیجیتال برای کسب‌وکار شما
            </h2>

            <p>
                مجموعه‌ای از خدمات تخصصی برای توسعه و رشد
                کسب‌وکارهای آنلاین
            </p>

        </div>

        <div class="services-grid">

            <article class="service-card">
                <h3>طراحی سایت</h3>
                <p>
                    طراحی وب‌سایت‌های مدرن و حرفه‌ای
                    متناسب با نیاز کسب‌وکار شما.
                </p>
                <a href="#">مشاهده خدمات</a>
            </article>

            <article class="service-card">
                <h3>طراحی اپلیکیشن</h3>
                <p>
                    توسعه اپلیکیشن‌های کاربردی برای
                    پلتفرم‌های مختلف.
                </p>
                <a href="#">مشاهده خدمات</a>
            </article>

            <article class="service-card">
                <h3>بهینه‌سازی سایت</h3>
                <p>
                    بهبود ساختار سایت و افزایش عملکرد
                    آن برای موتورهای جستجو.
                </p>
                <a href="#">مشاهده خدمات</a>
            </article>

            <article class="service-card">
                <h3>ربات تلگرامی</h3>
                <p>
                    طراحی و توسعه ربات‌های تلگرامی
                    اختصاصی برای کسب‌وکارها.
                </p>
                <a href="#">مشاهده خدمات</a>
            </article>

        </div>

    </div>

</section>

CSS

ابتدا Container:

* {
    box-sizing: border-box;
}

body {
    margin: 0;
}

.container {
    width: min(100% - 32px, 1200px);
    margin-inline: auto;
}

سپس بخش:

.services-section {
    padding-block: clamp(60px, 8vw, 120px);
}

عنوان:

.section-header {
    text-align: center;
    max-width: 700px;
    margin-inline: auto;
    margin-bottom: 48px;
}

.section-header h2 {
    font-size: clamp(2rem, 4vw, 3.5rem);
    margin: 12px 0;
}

.section-header p {
    font-size: clamp(1rem, 1.5vw, 1.2rem);
}

Grid:

.services-grid {
    display: grid;
    grid-template-columns:
        repeat(auto-fit, minmax(240px, 1fr));

    gap: 24px;
}

کارت:

.service-card {
    display: flex;
    flex-direction: column;

    padding: 28px;
    border-radius: 20px;
    min-height: 260px;
}

.service-card p {
    line-height: 1.9;
}

.service-card a {
    margin-top: auto;
}

در این مثال تقریباً بدون نیاز به تعریف تعداد زیادی Breakpoint، Grid می‌تواند تعداد ستون‌ها را بر اساس فضای موجود تغییر دهد.

Responsive Navigation

یکی از بخش‌هایی که معمولاً در Responsive Design چالش‌برانگیز است، Navigation است.

مثلاً در دسکتاپ:

Logo     خانه   خدمات   محصولات   درباره ما   تماس

اما در موبایل ممکن است فضای کافی وجود نداشته باشد:

Logo                              ☰

یک ساختار ساده:

<header class="header">

    <div class="container">

        <nav class="navbar">

            <a href="#" class="logo">
                بنو سرویس
            </a>

            <div class="nav-links">

                <a href="#">خانه</a>
                <a href="#">خدمات</a>
                <a href="#">محصولات</a>
                <a href="#">درباره ما</a>
                <a href="#">تماس با ما</a>

            </div>

            <button class="menu-button">
                ☰
            </button>

        </nav>

    </div>

</header>

CSS:

.navbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
}

.nav-links {
    display: flex;
    align-items: center;
    gap: 24px;
}

.menu-button {
    display: none;
}

در موبایل:

@media (max-width: 700px) {

    .nav-links {
        display: none;
    }

    .menu-button {
        display: block;
    }

}

در پروژه واقعی می‌توانیم با JavaScript منوی موبایل را باز و بسته کنیم.

جلوگیری از Horizontal Overflow

یکی از مشکلات بسیار رایج در سایت‌های Responsive، ایجاد اسکرول افقی است.

مثلاً:

.element {
    width: 1000px;
}

اگر Viewport فقط 390px باشد، عنصر از صفحه خارج می‌شود.

گاهی نیز مشکل به دلیل ترکیب Width و Padding ایجاد می‌شود.

استفاده از:

* {
    box-sizing: border-box;
}

می‌تواند بسیاری از مشکلات مربوط به محاسبه اندازه عناصر را کاهش دهد.

همچنین باید عناصر دارای اندازه ثابت را بررسی کنیم.

برای پیدا کردن Overflow می‌توانیم در DevTools به دنبال عناصری بگردیم که عرضشان از Viewport بیشتر شده است.

متن فارسی و Responsive Design

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

طول کلمات و متن فارسی ممکن است باعث شود یک عنصر در عرض کم فضای بیشتری نیاز داشته باشد.

مثلاً:

.card {
    min-width: 0;
}

در Layoutهای Flex و Grid این نکته می‌تواند برای جلوگیری از بزرگ شدن ناخواسته بعضی عناصر مفید باشد.

همچنین نباید برای متن‌های فارسی ارتفاع ثابت غیرضروری تعریف کنیم:

.card {
    height: 180px;
}

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

در بسیاری از موارد بهتر است:

.card {
    min-height: 180px;
}

استفاده کنیم.

اندازه دکمه‌ها در موبایل

Responsive Design فقط به اندازه صفحه مربوط نیست؛ تجربه تعامل کاربر نیز مهم است.

مثلاً اگر چند دکمه بسیار کوچک باشند، کاربر موبایل ممکن است نتواند به راحتی آن‌ها را لمس کند.

بنابراین در طراحی موبایل:

.button {
    min-height: 44px;
    padding-inline: 20px;
}

می‌تواند شروع مناسبی باشد.

همچنین نباید چند لینک مهم را بیش از حد نزدیک به یکدیگر قرار دهیم.

Breakpointهای زیاد؛ یک اشتباه رایج

یکی از اشتباهات رایج این است که برای هر اندازه صفحه یک Media Query ایجاد کنیم:

@media (max-width: 1400px) { ... }

@media (max-width: 1300px) { ... }

@media (max-width: 1200px) { ... }

@media (max-width: 1100px) { ... }

@media (max-width: 1000px) { ... }

@media (max-width: 900px) { ... }

@media (max-width: 800px) { ... }

@media (max-width: 700px) { ... }

@media (max-width: 600px) { ... }

@media (max-width: 500px) { ... }

@media (max-width: 400px) { ... }

این کار معمولاً باعث پیچیده شدن CSS می‌شود.

بهتر است ابتدا با Layoutهای انعطاف‌پذیر مشکل را حل کنیم و فقط زمانی Breakpoint اضافه کنیم که واقعاً Layout یا محتوا نیاز به تغییر داشته باشد.

Breakpoint را بر اساس شکستن Layout انتخاب کنید، نه بر اساس فهرست دستگاه‌ها.

Fixed Height؛ دشمن Responsive Design

این کد را در نظر بگیرید:

.hero {
    height: 600px;
}

در یک دسکتاپ ممکن است مناسب باشد.

اما در موبایل:

ارتفاع صفحه کم
       ↓
محتوا زیاد
       ↓
فضای کافی وجود ندارد
       ↓
Overflow

در بسیاری از موارد بهتر است از:

min-height: 600px;

یا حتی:

min-height: clamp(400px, 70vh, 700px);

استفاده کنیم.

البته height در بعضی طراحی‌های خاص کاملاً قابل استفاده است؛ نکته این است که نباید بدون دلیل برای بخش‌های دارای محتوای متغیر استفاده شود.

طراحی Responsive برای Hero

یک Hero مدرن می‌تواند در دسکتاپ دو ستون داشته باشد:

┌────────────────────────────────────────┐
│                                        │
│   متن و دکمه‌ها       تصویر / Graphic  │
│                                        │
└────────────────────────────────────────┘

در موبایل:

┌──────────────────┐
│       متن        
│      دکمه‌ها     
│                  
│      تصویر      
└──────────────────┘

با Grid:

.hero {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: center;
    gap: 48px;
}

در موبایل:

@media (max-width: 768px) {

    .hero {
        grid-template-columns: 1fr;
        text-align: center;
    }

}

یک Hero Responsive کامل‌تر

<section class="hero">

    <div class="hero-content">

        <span class="hero-label">
            راهکارهای دیجیتال
        </span>

        <h1>
            زیرساخت دیجیتال کسب‌وکار شما
        </h1>

        <p>
            از طراحی سایت و فروشگاه اینترنتی
            تا سرور، هاست و ابزارهای دیجیتال.
        </p>

        <div class="hero-actions">

            <a href="#" class="primary-button">
                مشاهده خدمات
            </a>

            <a href="#" class="secondary-button">
                بیشتر بدانید
            </a>

        </div>

    </div>

    <div class="hero-image">

        <img
            src="hero-image.jpg"
            alt="خدمات دیجیتال"
        >

    </div>

</section>

CSS:

.hero {
    width: min(100% - 32px, 1200px);
    margin-inline: auto;

    display: grid;
    grid-template-columns: 1fr 1fr;

    align-items: center;
    gap: 48px;

    padding-block: clamp(60px, 10vw, 140px);
}

.hero h1 {
    font-size: clamp(2.2rem, 5vw, 4.5rem);
    line-height: 1.2;
}

.hero p {
    font-size: clamp(1rem, 1.5vw, 1.25rem);
    line-height: 1.9;
}

.hero-image img {
    display: block;
    width: 100%;
    max-width: 100%;
    height: auto;
}

و برای موبایل:

@media (max-width: 768px) {

    .hero {
        grid-template-columns: 1fr;
        text-align: center;
    }

}

Responsive فقط برای Width نیست

گاهی Responsive Design را فقط با عرض صفحه مرتبط می‌دانیم، اما محیط نمایش ویژگی‌های دیگری نیز دارد.

Media Query می‌تواند برای شرایط مختلف نمایش استفاده شود و علاوه بر Width، ویژگی‌های دیگری را نیز بررسی کند.

برای مثال در ادامه مسیر با مواردی مانند:

prefers-reduced-motion

نیز روبه‌رو خواهیم شد.

بنابراین Responsive Design را بهتر است بخشی از یک رویکرد کلی‌تر برای Adaptive User Experience بدانیم.

اشتباهات رایج در طراحی Responsive

۱. استفاده از Width ثابت

.container {
    width: 1200px;
}

در بسیاری از Layoutها مشکل ایجاد می‌کند.

۲. استفاده بیش از حد از Media Query

هر مشکل Responsive الزاماً با Media Query حل نمی‌شود.

گاهی Grid، Flexbox، minmax() یا clamp() راه‌حل بهتری هستند.

۳. انتخاب Breakpoint بر اساس دستگاه

این روش قدیمی و محدودکننده است.

Breakpoint باید جایی باشد که محتوا یا Layout به تغییر نیاز دارد.

۴. استفاده زیاد از Height ثابت

height: 400px;

ممکن است محتوای متغیر را در موبایل دچار مشکل کند.

۵. فراموش کردن تصاویر

تصویر بزرگ می‌تواند باعث ایجاد Horizontal Overflow شود.

راه‌حل عمومی:

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

۶. نادیده گرفتن متن فارسی

متن‌های فارسی ممکن است در اندازه‌های مختلف تعداد خطوط متفاوتی داشته باشند.

پس بهتر است از ارتفاع ثابت غیرضروری برای عناصر متنی اجتناب کنیم.

۷. طراحی فقط برای دسکتاپ

این رویکرد معمولاً باعث می‌شود Responsive کردن پروژه در مراحل پایانی بسیار دشوار شود.

بهتر است Responsive بودن را از ابتدای پروژه در نظر بگیریم.

تمرین‌های عملی

تمرین ۱ — Container Responsive

یک Container ایجاد کنید که:

  • در موبایل تمام عرض را با فاصله داخلی مناسب بگیرد.

  • در دسکتاپ حداکثر 1200px باشد.

  • در وسط صفحه قرار بگیرد.

سعی کنید بدون Media Query این بخش را پیاده‌سازی کنید.

تمرین ۲ — کارت‌های Responsive

چهار کارت ایجاد کنید.

در صفحه بزرگ:

1 | 2 | 3 | 4

در صفحه متوسط:

1 | 2
3 | 4

و در موبایل:

1
2
3
4

ابتدا با Grid و minmax امتحان کنید و سپس یک نسخه با Media Query بسازید.

تمرین ۳ — Hero Responsive

یک Hero برای «بنو سرویس» طراحی کنید که:

  • در دسکتاپ دو ستون باشد.

  • در موبایل تک‌ستونه شود.

  • عنوان با clamp() تغییر اندازه دهد.

  • تصویر از Container خارج نشود.

  • دکمه‌ها در موبایل نیز قابل استفاده باشند.

تمرین ۴ — Navigation

یک Navbar بسازید که:

در دسکتاپ:

Logo | خانه | خدمات | محصولات | تماس

و در موبایل:

Logo | ☰

نمایش داده شود.

در این مرحله لازم نیست منوی همبرگری را با JavaScript باز کنید؛ فقط ظاهر Responsive آن را پیاده‌سازی کنید.

جمع‌بندی

Responsive Design یکی از پایه‌ای‌ترین مهارت‌های طراحی وب مدرن است. هدف آن این نیست که نسخه دسکتاپ را کوچک کنیم؛ هدف این است که Layout و تجربه کاربری را با فضای موجود تطبیق دهیم.

در این مقاله با مفاهیم مهمی مانند Viewport، Container، اندازه‌های انعطاف‌پذیر، تصاویر Responsive، object-fit، min()، max()، clamp()، minmax()، Grid، Flexbox، Breakpoint و Mobile First آشنا شدیم.

همچنین دیدیم که Responsive Design فقط وابسته به Media Query نیست. CSS مدرن امکانات زیادی برای ساخت Layoutهای انعطاف‌پذیر در اختیار ما قرار می‌دهد. min(), max() و clamp() می‌توانند بسیاری از اندازه‌ها را بدون ایجاد Media Queryهای متعدد کنترل کنند.

مهم‌ترین نکته این مقاله این است:

Responsive Design یعنی طراحی برای فضا و محتوا، نه طراحی برای یک دستگاه خاص.

اگر Layout شما فقط در عرض‌های مشخص کار می‌کند، هنوز واقعاً Responsive نیست.

۱۰

نظرات

کد در دسترس نیست

هنوز نظری ثبت نشده است.