در این فصل چه میسازی#
آخر این فصل یک صفحهٔ پستِ کوتاه داری با یک عکسِ بزرگِ بالای مطلب و یک عکسِ کوچکِ گردِ نویسنده — و هر دو کاملاً responsiveاند. عکسِ بزرگ روی هر عرضی جا میشود و از صفحه بیرون نمیزند، عکسِ گرد شکلش را نگه میدارد و کش نمیآید، و مرورگر برای هر صفحه اندازهٔ درستِ فایل را دانلود میکند نه یک عکسِ غولپیکر. تصویر تا اینجا تنها چیزی بود که به قاعدههای responsive گوش نمیداد؛ این فصل رامش میکند.

آخر این فصل میتوانی:
- با
max-width: 100%جلوی سرریزِ یک عکس را بگیری - با
object-fitیک عکس را در یک شکلِ مشخص بدونِ کشآمدن جا بدهی - با
aspect-ratioجای عکس را رزرو کنی تا صفحه نپرد - با
srcsetوsizesبگذاری مرورگر اندازهٔ درستِ عکس را انتخاب کند
قبل از شروع#
- از ترم ۱:
<img>،src،alt،width/heightو<figure>/<figcaption>— پایهٔ کار همینهاست. - از فصل ۱ و ۲ (همین ترم):
max-width،%و mobile-first. - از ترم ۳:
display: flex،align-itemsوgap— برای چیدنِ عکسِ نویسنده کنارِ اسمش.
مثل همیشه فقط یک مرورگر لازم داری، یا فقط همین آزمایشگاه.
۱. تصویری که از جعبهاش بیرون میزند#
بیا با یک پستِ ساده شروع کنیم: یک <main> باریک با یک تیتر و یک عکسِ بزرگ. عکس را با <img> میگذاریم، مثل ترم ۱:
<main class="post">
<h1>یک سفر کوتاه</h1>
<img src="https://picsum.photos/id/1015/800/450"
alt="رودخانهای که از میان کوههای جنگلی میگذرد"
width="800" height="450">
</main>
و به .post یک عرضِ نسبی بده تا مثل فصل ۱ جمعوجور بماند:
.post {
max-width: 700px;
margin: 0 auto;
}
حالا نگاه کن. .post نهایتاً ۷۰۰ پیکسل است، ولی عکس ۸۰۰ پیکسل پهناست — و از جعبهاش بیرون میزند، از لبهٔ صفحه رد میشود و یک نوارِ لغزشِ افقی میسازد. عرضِ پیشنمایش را باریکتر کن؛ بدتر میشود، چون عکس همچنان اصرار دارد ۸۰۰ پیکسل بماند.
🔧 اگر کار نکرد: بله، این سرریز همان چیزی است که باید ببینی. یک
<img>بهطور پیشفرض به عرضِ واقعیِ فایل کشیده میشود و به عرضِ جعبهاش کاری ندارد. علاجش یک خطِ کوتاه است که در بخش بعد مینویسیم:max-width: 100%.
۲. max-width: 100% و height: auto#
max-width: 100% روی یک عکس یعنی «هیچوقت پهنتر از جعبهات نشو». اگر جعبه از عکس بزرگتر بود، عکس اندازهٔ واقعیاش میماند؛ اگر جعبه کوچکتر شد، عکس با آن جمع میشود. height: auto را هم کنارش میگذاری تا وقتی عرض کم میشود، ارتفاع هم به همان نسبت کم شود و عکس کش نیاید:
.hero {
max-width: 100%;
height: auto;
border-radius: 8px;
}
✅ چک کن: حالا عرضِ پیشنمایش را باریک و پهن کن. عکس دیگر بیرون نمیزند و نوارِ لغزشِ افقی رفته؛ روی صفحهٔ باریک با آن جمع میشود و نسبتش هم حفظ میماند. این دو خط (max-width: 100% و height: auto) مهمترین چیزِ کلِ فصلاند — تقریباً هر عکسی روی وب به همین دو نیاز دارد.
💡 نکته: فرق
width: 100%وmax-width: 100%مثل فصل ۱ است:width: 100%عکسِ کوچک را هم به زور بزرگ میکند تا کلِ جعبه را پر کند (و تارش میکند)، ولیmax-width: 100%فقط جلوی بزرگترشدن از جعبه را میگیرد و عکسِ کوچک را کش نمیدهد. برای عکس، تقریباً همیشهmax-widthرا میخواهی.
۳. object-fit: پر کردنِ یک شکل بدونِ کشآمدن#
گاهی میخواهی عکس یک شکلِ مشخص بگیرد — مثلاً عکسِ گردِ نویسنده که باید مربع (بعد گرد) باشد، هرچند فایلش مستطیل است. بیا <figure> نویسنده را اضافه کنیم:
<figure class="author">
<img class="avatar"
src="https://picsum.photos/id/64/300/200"
alt="عکس نویسنده" width="300" height="200">
<figcaption>نوشتهٔ آوا</figcaption>
</figure>
فایلِ این عکس مستطیل است (۳۰۰ در ۲۰۰). اگر به زور در یک مربعِ ۹۶ در ۹۶ بگذاریاش، پهنبهپهن فشرده میشود و صورتِ آدم کشیده و بدشکل میشود:
.avatar {
width: 96px;
height: 96px;
border-radius: 50%;
}
این را در آزمایشگاه امتحان کن و ببین: عکس در مربع فشرده و لهیده شده. object-fit: cover این را حل میکند — به عکس میگوید «جعبه را پر کن، ولی نسبتت را نگه دار؛ هرچه اضافه آمد را از لبهها ببُر». height: 96px را با object-fit عوض کن:
.avatar {
width: 96px;
height: 96px;
object-fit: cover;
border-radius: 50%;
}
✅ چک کن: حالا عکسِ گرد بدونِ هیچ کشآمدنی جا شده؛ بهجای فشردهشدن، وسطش نگه داشته شده و طرفینِ اضافه بریده شده. object-fit: cover رایجترین حالت است؛ یک حالتِ دیگرش contain است که کلِ عکس را نشان میدهد و اگر لازم شد دورش فضای خالی میگذارد.

۴. aspect-ratio: نسبتِ ثابت بدونِ پرش#
آن height: 96px یک عیبِ کوچک دارد: عددِ ثابت است. اگر بعداً عرض را عوض کنی، شکل بههم میریزد. aspect-ratio بهتر است: بهجای ارتفاعِ ثابت، نسبت را ثابت میکند و ارتفاع را خودش از روی عرض حساب میکند. برای یک مربع مینویسی aspect-ratio: 1 / 1:
.avatar {
width: 96px;
aspect-ratio: 1 / 1;
object-fit: cover;
border-radius: 50%;
}
✅ چک کن: عکس هنوز یک مربعِ گرد است، ولی حالا اگر width را عوض کنی، مربع بودنش حفظ میماند چون ارتفاع همیشه برابرِ عرض حساب میشود. یک سودِ بزرگِ دیگر هم دارد: مرورگر پیش از دانلودِ عکس هم میداند جایش چه شکلی است، پس جای عکس را از اول رزرو میکند و وقتی عکس میرسد، بقیهٔ صفحه نمیپرد. همین پرش، یکی از آزاردهندهترین عیبهای صفحههای کُند است.
💡 نکته: همان
widthوheightکه در ترم ۱ روی<img>گذاشتی هم همین کارِ رزروِ جا را میکند.aspect-ratioوقتی به کار میآید که شکلِ نمایشِ عکس با شکلِ فایلش فرق دارد.
۵. srcset و sizes: عکسِ درست برای هر عرض#
یک مشکل باقی مانده که دیده نمیشود ولی مهم است: عکسِ بزرگ همیشه فایلِ ۸۰۰ پیکسلی را دانلود میکند، حتی روی یک موبایلِ باریک که فقط ۳۶۰ پیکسل جا دارد. یعنی موبایل دارد دیتای هدر میدهد. srcset این را حل میکند: چند نسخه با عرضهای مختلف به مرورگر میدهی و میگویی هر کدام چند پیکسل پهناست (با پسوندِ w)، و مرورگر خودش مناسبترین را برمیدارد:
<img
class="hero"
src="https://picsum.photos/id/1015/800/450"
srcset="https://picsum.photos/id/1015/400/225 400w,
https://picsum.photos/id/1015/800/450 800w,
https://picsum.photos/id/1015/1200/675 1200w"
sizes="(min-width: 700px) 680px, 100vw"
alt="رودخانهای که از میان کوههای جنگلی میگذرد"
width="800"
height="450">
srcset فهرستِ نسخههاست و 400w یعنی «این فایل ۴۰۰ پیکسل پهناست». sizes به مرورگر میگوید عکس روی صفحه چقدر جا میگیرد تا بتواند درست انتخاب کند: اینجا نوشتهایم «اگر عرضِ صفحه از ۷۰۰ بیشتر بود، عکس ۶۸۰ پیکسل جا میگیرد؛ وگرنه کلِ عرضِ صفحه». آن 100vw یعنی «کلِ عرضِ صفحه» — این vw را فعلاً همینطور بپذیر؛ فصل بعد کامل یادش میگیریم. src هم میماند بهعنوان نسخهٔ پیشفرض برای مرورگرهای خیلی قدیمی.
✅ چک کن: روی صفحه فرقی نمیبینی — و همین درست است. سودِ srcset در سرعت و مصرفِ دیتاست، نه در ظاهر. مرورگر روی موبایل نسخهٔ کوچک را برمیدارد و روی دسکتاپِ پهن نسخهٔ بزرگ را.
۶. <picture>: وقتی عکسِ متفاوت میخواهی#
srcset نسخههای همشکل با اندازههای مختلف میدهد. ولی گاهی میخواهی روی موبایل یک عکسِ متفاوت نشان بدهی — مثلاً یک بُرشِ نزدیکترِ عمودی بهجای منظرهٔ عریض. برای این کار <picture> هست: چند <source> با شرطِ media میگذاری و مرورگر اولین شرطِ درست را برمیدارد؛ <img> هم همیشه تهاش میماند بهعنوان پیشفرض:
<picture>
<source media="(min-width: 700px)"
srcset="https://picsum.photos/id/1015/1200/675">
<img src="https://picsum.photos/id/1015/500/700"
alt="رودخانهای در میان کوهها"
width="500" height="700">
</picture>
اینجا روی صفحهٔ پهن عکسِ عریض میآید و روی باریک عکسِ عمودی. به این کار «art direction» میگویند: تصمیم میگیری روی هر صفحه کدام بُرش بهتر است. برای اکثرِ عکسها همان srcset کافی است؛ <picture> را وقتی بیاور که واقعاً به عکسِ متفاوت نیاز داری.
🤖 با AI: یک
<img>معمولی به دستیار AI ات بده و بپرس «این را برای responsive کامل کن — چه چیزهایی کم دارد؟». جوابش را خطبهخط بسنج: آیاmax-width: 100%را گفت؟srcsetوsizesرا درست نوشت؟altرا دستنخورده نگه داشت؟ بعد در آزمایشگاه امتحانش کن — AI گاهیsizesرا غلط مینویسد و همان باعث میشود نسخهٔ اشتباه دانلود شود، که فقط با دیدنِ نتیجه پیدا میشود.
کد کاملِ این فصل#
این هم دو فایلِ کامل، یکجا. اول index.html:
<!-- index.html -->
<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>عکس responsive</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<main class="post">
<h1>یک سفر کوتاه</h1>
<img
class="hero"
src="https://picsum.photos/id/1015/800/450"
srcset="https://picsum.photos/id/1015/400/225 400w,
https://picsum.photos/id/1015/800/450 800w,
https://picsum.photos/id/1015/1200/675 1200w"
sizes="(min-width: 700px) 680px, 100vw"
alt="رودخانهای که از میان کوههای جنگلی میگذرد"
width="800"
height="450">
<p>این عکس روی هر عرضی اندازهٔ درستِ خودش را میگیرد و بدشکل نمیشود.</p>
<figure class="author">
<img
class="avatar"
src="https://picsum.photos/id/64/300/200"
alt="عکس نویسنده"
width="300"
height="200">
<figcaption>نوشتهٔ آوا</figcaption>
</figure>
</main>
</body>
</html>
و styles.css:
/* styles.css */
* {
box-sizing: border-box;
}
body {
background-color: #f6edda;
margin: 0;
padding: 16px;
}
.post {
max-width: 700px;
margin: 0 auto;
}
.hero {
max-width: 100%;
height: auto;
border-radius: 8px;
}
.author {
display: flex;
align-items: center;
gap: 12px;
margin: 0;
}
.avatar {
width: 96px;
aspect-ratio: 1 / 1;
object-fit: cover;
border-radius: 50%;
}
✅ چک کن: روی صفحه یک پستِ تمیز میبینی: عکسِ بزرگِ بالای مطلب که با عرض جمع و باز میشود، و عکسِ گردِ نویسنده کنارِ اسمش که شکلش را نگه میدارد. عرض را بکش و مطمئن شو هیچچیز بیرون نمیزند و هیچچیز کش نمیآید.
واژههای تازهٔ این فصل#
| کلمه | تلفظ به حروف فارسی | یعنی چه |
|---|---|---|
max-width: 100% |
مکس-ویدث صد درصد | عکس هیچوقت پهنتر از جعبهاش نمیشود |
object-fit |
آبجکت-فیت | چطور عکس داخلِ جعبهاش جا شود؛ cover یعنی پر کن و لبهها را ببُر |
aspect-ratio |
اسپکت-ریشو | نسبتِ عرض به ارتفاع را ثابت میکند |
srcset |
سورس-ست | فهرستِ چند نسخهٔ عکس با عرضهای مختلف برای انتخابِ مرورگر |
sizes |
سایزِز | به مرورگر میگوید عکس روی صفحه چقدر جا میگیرد |
<picture> |
پیکچر | برای دادنِ عکسِ متفاوت روی صفحههای مختلف (art direction) |
تمرینها
اول خودت فکر کن یا امتحان کن — بعد اینجا را باز کن.
در فصل بعد#
الان چیدمان و تصویر، هر دو، responsiveاند. یک چیزِ آخر مانده: متن. اندازهٔ فونت را هم میشود سیال کرد تا خودش با عرضِ صفحه بزرگ و کوچک شود — بدونِ اینکه برای هر breakpoint یک @media بنویسی. فصل بعد سراغِ ریاضیِ CSS میرویم: clamp()، min()، max()، calc() و همان واحدِ vw که این فصل قرضش گرفتیم، اینبار کامل.
به آخر این فصل رسیدی!
اگر ساختی و جواب داد، این دکمه مال توست.