آموزش ساخت گالری تصاویر به سبک Pinterest با کدهای CSS
رفیق برنامهنویس، حالت چطوره؟ امروز قراره دست به کار شیم و یه گالری تصویر بزنیم که هرکی دید بگه: “واو، چه کدی زدی!” منظورم همون چیدمان جذاب و نامنظم پینترستی هست که تصاویر با ارتفاعهای مختلف رو بدون فضای خالی اضافه کنار هم میچینه. شاید فکر کنی کار سختیه، اما با قدرت CSS Grid، این کار مثل آب خوردنه. نه نیاز به کتابخونههای جاوااسکریپت پیچیده داری و نه سردرد اضافي. فقط کد خالص، ساده و پرقدرت CSS. آمادهای برای یه سفر هیجانانگیز به دنیای چیدمانهای مدرن؟ بزن بریم که قراره یه چیز خفن بسازیم! اگه همین الان هم دنبال ابزارها و تمهای آماده برای پروژههات هستی، یه سر به فروشگاه ابزارهای ما بزن، شاید همون چیزی که دنبالشی رو پیدا کردی.
🗺️ نقشه راه گالری پینترستی شما (اینفوگرافیک متنی)
💡 قدم اول: فهم چیدمان Masonry
- چرا پینترست اینقدر جذابه؟
- مبانی کار با CSS Grid
🏗️ قدم دوم: ساختار HTML پایه
- کانتینر اصلی و آیتمهای تصویر
- اهمیت تگ `alt` و تصاویر ریسپانسیو
✨ قدم سوم: جادوی CSS Grid
- `display: grid` و `grid-template-columns`
- `grid-auto-rows` و `grid-row-end` برای چیدمان نامنظم
- فاصلهگذاری با `gap`
📱 قدم چهارم: رسپانسیو کردن برای همه دستگاهها
- استفاده از Media Queries
- تنظیمات برای موبایل، تبلت، لپتاپ و تلویزیون
🔧 قدم پنجم: نکات پیشرفته و عیبیابی
- افکتهای هاور، Lazy Loading و بهینهسازی
- راهحل مشکلات رایج (Troubleshooting)
چرا گالری پینترست اینقدر جذابه؟ (مفهوم Masonry Layout)
احتمالاً تا حالا هزاران بار تو پینترست گشت و گذار کردی و متوجه اون چیدمان منحصر به فردش شدی. تصاویر با هر سایز و ارتفاعی، بدون اینکه فضای خالی و ناخوشایندی بینشون بمونه، مثل بلوکهای یک دیوار آجری (Masonry) کنار هم چیده شدن. این سبک چیدمان نه تنها از نظر بصری خیلی جذابه و حس انسجام رو القا میکنه، بلکه باعث میشه کاربر تجربه بهتری داشته باشه و سریعتر محتوا رو اسکن کنه.
مشکل اصلی تو چیدمانهای گالری سنتی اینه که اگه تصاویر ارتفاعهای متفاوتی داشته باشن، ردیفها بهم میریزن و فضای سفید زیادی ایجاد میشه. اما Masonry Layout این مشکل رو با هوشمندی حل میکنه: آیتمها رو در کوتاهترین ستون موجود قرار میده و به همین دلیل، فضای خالی به حداقل میرسه. قبلاً برای پیادهسازی این افکت باید سراغ جاوااسکریپت میرفتیم، ولی خوشبختانه CSS Grid API کار رو به طرز چشمگیری ساده کرده. دیگه لازم نیست نگران پیچیدگیهای کد باشی، با CSS Grid همهچیز تحت کنترله و کارایی بهتری هم داره.
آمادهسازی اولیه: ساختار HTML پایه
قبل از اینکه وارد دنیای CSS بشیم، باید یه ساختار HTML ساده و منطقی برای گالریمون داشته باشیم. یه کانتینر اصلی نیاز داریم که همه تصاویر داخلش قرار بگیرن. هر تصویر هم بهتره داخل یه `div` یا `figure` جداگانه باشه تا بتونیم راحتتر استایل بدیم.
این یه نمونه از HTML پایه ماست:
<div class="pinterest-gallery">
<div class="gallery-item">
<img src="images/img1.jpg" alt="تصویر گلهای بهاری">
</div>
<div class="gallery-item">
<img src="images/img2.jpg" alt="منظره کوهستان برفی">
</div>
<div class="gallery-item">
<img src="images/img3.jpg" alt="یک فنجان قهوه داغ">
</div>
<div class="gallery-item">
<img src="images/img4.jpg" alt="پل معلق در جنگل">
</div>
<div class="gallery-item">
<img src="images/img5.jpg" alt="خانه سنتی با پنجرههای رنگی">
</div>
<div class="gallery-item">
<img src="images/img6.jpg" alt="غروب آفتاب در ساحل">
</div<!-- به تعداد لازم آیتم اضافه کنید -->
</div>
(روی کد کلیک کنید تا کپی شود)
**نکات مهم:**
* **`pinterest-gallery`:** این `div` کانتینر اصلی ماست که با CSS Grid اون رو به یه گالری پینترستی تبدیل میکنیم.
* **`gallery-item`:** هر `div` که یک تصویر رو در بر میگیره. این به ما اجازه میده که استایلهای خاصی به هر آیتم بدیم (مثلاً یه پسزمینه، پدینگ یا افکت هاور).
* **`img` تگ:** خود تصویر. حتماً از ویژگی `alt` برای توضیحات تصویر استفاده کن! این کار هم برای سئو فوقالعاده مهمه و هم برای دسترسیپذیری (Accessibility) افرادی که از صفحهخوان استفاده میکنن.
* **تصاویر ریسپانسیو:** یادت باشه تصاویرت رو بهینهسازی کنی. هم از نظر حجم و هم از نظر ابعاد. میتونی از ابزارهای آنلاین برای فشردهسازی و فرمتهای مدرن مثل WebP استفادهه کنی.
جادو با CSS: پیادهسازی گرید پینترست
خب، حالا نوبت قسمت هیجانانگیزه! با CSS Grid قراره این HTML ساده رو به یه گالری پینترستی تبدیل کنیم.
گام اول: تنظیمات کانتینر اصلی (Container Setup)
اول از همه، باید کانتینر اصلی رو به یه گرید تبدیل کنیم و تعداد ستونهاش رو مشخص کنیم.
.pinterest-gallery {
display: grid;
/* این خط تعداد ستونها رو مشخص میکنه. repeat(auto-fill, minmax(250px, 1fr)) یعنی:
حداقل 250px عرض برای هر ستون و اگر جا بود، به صورت مساوی (1fr) پخش شه. */
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
/* فاصله بین سطرها و ستونها */
gap: 15px;
}
(روی کد کلیک کنید تا کپی شود)
* **`display: grid;`**: کانتینر رو تبدیل به یک Grid Container میکنه.
* **`grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));`**: این یکی از قدرتهای اصلی Grid هست.
* `repeat`: برای تکرار الگو.
* `auto-fill`: تا جایی که ممکنه ستون ایجاد میکنه.
* `minmax(250px, 1fr)`: هر ستون حداقل 250 پیکسل عرض داره، اما اگه فضای بیشتری باشه، تا جایی که میشه بزرگ میشه و فضای موجود رو تقسیم میکنه (1fr).
* **`gap: 15px;`**: بین آیتمهای گرید 15 پیکسل فاصله ایجاد میکنه.
گام دوم: مدیریت ارتفاع تصاویر (Image Height Management)
اینجاست که جادوی Masonry اتفاق میافته. باید به Grid بگیم که چطور آیتمها رو بر اساس ارتفاعشون در سطرها پخش کنه.
.pinterest-gallery {
/* ... کدهای قبلی ... */
grid-auto-rows: 10px; /* هر سطر به صورت پیشفرض 10 پیکسل */
grid-auto-flow: dense; /* سعی میکنه جاهای خالی رو پر کنه */
}
.gallery-item img {
width: 100%;
height: auto; /* برای حفظ نسبت تصویر */
display: block; /* حذف فضای اضافی زیر تصویر */
}
.gallery-item {
/* اینجا جادو اتفاق میفته! ما ارتفاع آیتم رو بر اساس ارتفاع تصویرش تنظیم میکنیم */
grid-row-end: span var(--row-span); /* از یک متغیر CSS برای span استفاده میکنیم */
/* اگه خواستید بدون JS باشه، باید برای هر آیتم بصورت دستی مقداردهی کنید:
مثلاً: grid-row-end: span 20; یا span 30;
ولی راه حل بهتر و پویاتر، استفاده از جاوااسکریپت برای محاسبه ارتفاع هر تصویر و ست کردن این متغیر است.
برای یک راه حل کاملاً CSS-only (بدون JS)، باید تصاویر طول یکسان داشته باشند یا از روشهای پیچیدهتر Grid استفاده کنیم.
اما برای شبیهسازی کامل پینترست، کمی جاوااسکریپت لازمه تا `var(--row-span)` رو محاسبه کنه.
فعلاً فرض میکنیم این مقدار رو به صورت دستی یا با JS داریم. */
background-color: #ecf0f1; /* برای دیدن بهتر آیتمها */
border-radius: 8px;
overflow: hidden; /* برای اینکه تصویر از border-radius بیرون نزنه */
}
(روی کد کلیک کنید تا کپی شود)
این قسمت کمی نیاز به توضیح بیشتر داره:
* **`grid-auto-rows: 10px;`**: اینجا یه ترفند استفاده میکنیم. هر سطر Grid رو به قطعات کوچیک (مثلاً 10 پیکسل) تقسیم میکنیم. حالا میتونیم به هر آیتم بگیم که چند تا از این قطعات رو اشغال کنه. این عدد (10px) به `grid-row-end` کمک میکنه تا ارتفاع هر آیتم رو دقیقتر محاسبه کنه. هرچه این عدد کوچکتر باشه، دقت چیدمان بیشتره اما ممکنه کمی عملکرد رو پایین بیاره. 20px یا 10px معمولا خوبه.
* **`grid-auto-flow: dense;`**: این ویژگی به Grid میگه که سعی کنه جاهای خالی رو پر کنه. یعنی اگه یه آیتم کوچیکتر پیدا کرد که تو یه فضای خالی جا میشه، اونو اونجا قرار بده تا چیدمان فشردهتر و مرتبتر به نظر برسه.
* **`grid-row-end: span var(–row-span);`**: این خط کد اصلی Masonry رو انجام میده.
* `span`: به Grid میگه که این آیتم باید چند سطر رو اشغال کنه.
* `var(–row-span)`: اینجا از یک متغیر CSS استفاده کردیم. مقدار این متغیر باید برای هر تصویر به صورت پویا (مثلاً با جاوااسکریپت) محاسبه بشه.
* **منظور از محاسبه چیه؟** باید ارتفاع واقعی تصویر رو بگیریم و بر `grid-auto-rows` (مثلاً 10px) تقسیم کنیم. مثلاً اگه یه تصویر 300px ارتفاع داره، `300 / 10 = 30` میشه. پس `grid-row-end` اون آیتم میشه `span 30`. این کار باعث میشه Grid بدونه هر تصویر چقدر فضا نیاز داره و اونا رو کنار هم بچینه.
* **آیا بدون جاوااسکریپت هم میشه؟** بله، اگه ارتفاع تصاویرت خیلی متفاوت نباشه یا بتونی یه الگوی خاص برای ارتفاعشون در نظر بگیری، میتونی برای هر `gallery-item` به صورت دستی این استایل رو اضافه کنی (مثلاً `style=”grid-row-end: span 25;”`) اما این کار برای تعداد زیاد تصویر غیرعملیه و پویایی نداره. برای یک گالری کاملاً پویا مثل پینترست، یه خط کوچیک جاوااسکریپت برای محاسبه ارتفاع و ست کردن این متغیر لازمه. اما با همین CSS هم اصول اولیه رو یاد گرفتی.
**یه راه حلل کاملاً CSS-only (با محدودیت):**
اگه واقعاً نمیخوای از جاوااسکریپت استفاده کنی، میتونی از یه ترفند دیگه استفاده کنی که به خوبی پینترست نیست ولی یه جورایی کار رو راه میندازه. میتونی ارتفاع ثابت برای آیتمها تعریف کنی و از `object-fit: cover` استفاده کنی یا اینکه فقط برای تصاویر با نسبتهای مشخص کار کنی. اما بهترین نتیجه با ترکیب CSS و یه ذره JS برای محاسبه ارتفاعها به دست میاد.
گام سوم: استایلدهی تصاویر (Image Styling)
برای اینکه تصاویر داخل آیتمها به درستی نمایش داده بشن و ریسپانسیو باشن، این استایلها رو بهشون اضافه میکنیم:
.gallery-item img {
width: 100%;
height: auto; /* حفظ نسبت تصویر */
display: block; /* حذف فضای خالی زیر تصویر */
border-radius: 8px; /* گوشههای گرد برای تصاویر */
transition: transform 0.3s ease-in-out; /* افکت برای هاور */
}
.gallery-item img:hover {
transform: scale(1.03); /* کمی بزرگتر شدن تصویر در هاور */
}
(روی کد کلیک کنید تا کپی شود)
* **`width: 100%; height: auto;`**: این دو ویژگی تضمین میکنن که تصویر همیشه عرض کامل کانتینر خودش رو اشغال کنه و ارتفاعش هم متناسب با عرض تغییر کنه تا نسبت تصویر حفظ بشه.
* **`display: block;`**: تصاویر به صورت پیشفرض `inline` هستن و ممکنه فضای خالی ناخواستهای زیرشون ایجاد بشه. با `display: block;` این مشکل حل میشه.
* **`border-radius` و `transition`**: برای زیبایی و بهبود تجربه کاربری اضافه شدن.
رسپانسیو کردن گالری برای همه دستگاهها (Mobile, Tablet, Desktop, TV)
امروز دیگه طراحی سایت بدون در نظر گرفتن رسپانسیو بودن، معنی نداره. گالری ما هم باید روی موبایل، تبلت، لپتاپ و حتی تلویزیونهای بزرگ به زیبایی نمایش داده بشه. این کار رو با `Media Queries` انجام میدیم.
استفاده از Media Queries
اصولاً کاری که باید بکنیم اینه که تعداد ستونها رو بر اساس اندازه صفحه تغییر بدیم. هرچه صفحه کوچکتر باشه، ستونهای کمتری نیاز داریم.
/* استایلهای پایه برای موبایل (پیشفرض) */
.pinterest-gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); /* 1 ستون در موبایلهای خیلی کوچک */
gap: 10px;
grid-auto-rows: 10px;
grid-auto-flow: dense;
padding: 10px; /* کمی پدینگ اطراف گالری */
}
/* برای تبلتها و دستگاههای با عرض حداقل 600px */
@media (min-width: 600px) {
.pinterest-gallery {
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); /* 2-3 ستون */
gap: 15px;
}
}
/* برای لپتاپها و دستگاههای با عرض حداقل 900px */
@media (min-width: 900px) {
.pinterest-gallery {
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); /* 3-4 ستون */
gap: 20px;
padding: 20px;
}
}
/* برای دسکتاپهای بزرگ و تلویزیونها (عرض 1200px به بالا) */
@media (min-width: 1200px) {
.pinterest-gallery {
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); /* 4-5 ستون */
}
}
/* برای تلویزیونها و صفحات نمایش خیلی بزرگتر */
@media (min-width: 1600px) {
.pinterest-gallery {
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); /* 5-6 ستون */
}
}
(روی کد کلیک کنید تا کپی شود)
با این روش `mobile-first` (یعنی اول برای موبایل طراحی میکنیم و بعد برای صفحات بزرگتر تغییر میدیم)، گالری شما روی هر دستگاهی عالی به نظر میرسه. مهمترین تغییر، تعداد ستونها با `grid-template-columns` هست که در هر `media query` تنظیم میشه.
نکات پیشرفته و بهبود تجربه کاربری (UX)
ساخت گالری فقط چیدمان نیست، باید به تجربه کاربری (UX) و عملکرد سایت هم فکر کنیم.
افکتهای هاور جذاب (Hover Effects)
یه حرکت ریز در زمان هاور، میتونه حس زندهبودن به گالری بده. ما قبلاً یه `transform: scale` کوچیک اضافه کردیم. میتونی چیزهای دیگهای مثل سایه (box-shadow) یا افکتهای لایه رویی هم اضافه کنی.
بارگذاری تنبل (Lazy Loading) برای تصاویر
اگه گالریت پر از تصاویره، بارگذاری همزمان همه اونها میتونه سرعت سایتت رو به شدت پایین بیاره. `Lazy Loading` یعنی تصاویر فقط وقتی که کاربر به اونها نزدیک میشه، بارگذاری بشن. این کار سرعت اولیه سایت رو به طرز چشمگیری بالا میبره.
به سادگی میتونی ویژگی `loading=”lazy”` رو به تگ `img` اضافه کنی:
<img src="images/img1.jpg" alt="تصویر گلهای بهاری" loading="lazy">
(روی کد کلیک کنید تا کپی شود)
بهینهسازی تصاویر برای سرعت (WebP, Compression)
فرمتهای جدید مثل WebP، تصاویر رو با کیفیت عالی و حجم کمتر ارائه میدن. همیشه قبل از آپلود تصاویر، اونا رو با ابزارهای فشردهسازی مثل TinyPNG یا Squoosh بهینه کن. این کار تاثیر فوقالعادهای روی سرعت بارگذاری سایتت داره.
دسترسیپذیری (Accessibility)
همونطور که قبلاً گفتم، استفاده از `alt` تگ برای تصاویر ضروریه. این کار به کاربرانی که نابینا هستن و از صفحهخوان (Screen Reader) استفاده میکنن کمک میکنه تا محتوای تصاویر رو درک کنن. همچنین، اگه تصویر به هر دلیلی بارگذاری نشد، متن `alt` به جای اون نمایش داده میشه.
مقایسه روشهای ساخت گالری Masonry
برای ساخت گالری Masonry چندین روش وجود داره. هر کدوم مزایا و معایب خاص خودشون رو دارن. بیا یه مقایسه سریع انجام بدیم تا ببینی برای پروژهت کدوم مناسبتره.
| ویژگی | CSS Grid | CSS Flexbox (با ترفند) | کتابخانههای JS (مانند Masonry.js) |
|---|---|---|---|
| سهولت پیادهسازی | متوسط (با فهمیدن مفاهیم Grid) | متوسط تا بالا (با نیاز به ساختار خاص HTML) | بالا (با اضافه کردن کتابخانه و کلاسها) |
| نیاز به جاوااسکریپت | برای پویایی کامل و محاسبه `grid-row-end` توصیه میشود. | نیاز نیست، اما ترفندها پیچیدهترند. | ضروری |
| عملکرد | عالی (بهینه توسط مرورگر) | خوب (فقط CSS) | متوسط (محاسبات JS میتواند سنگین باشد) |
| رسپانسیو بودن | بسیار آسان و قدرتمند با Media Queries | ممکن است پیچیده شود. | معمولاً در کتابخانه گنجانده شده است. |
| پشتیبانی مرورگر | عالی (همه مرورگرهای مدرن) | عالی (همه مرورگرهای مدرن) | عالی (وابسته به خود کتابخانه) |
همونطور که میبینی، CSS Grid یه گزینه قدرتمند و آیندهنگرانه برای این کار محسوب میشه، خصوصاً اگه به دنبال عملکرد بالا و کد تمیز باشی.
حل مشکلات رایج: عیبیابی سریع (Troubleshooting)
هیچ پروژهای بدون چالش نیست! اگه در حین کار با گالریت به مشکل خوردی، نگران نباش. اینا رایجترین مشکلات و راهحلهاشون هستن:
1. **تصاویر به درستی چیده نمیشوند یا فضای خالی زیادی وجود دارد:**
* **بررسی:** مطمئن شو که `grid-auto-rows` رو تعریف کردی و مقدار `grid-row-end` برای هر آیتم به درستی (با جاوااسکریپت یا دستی) محاسبه شده باشه.
* **راهحل:** اگه از JS برای محاسبه ارتفاع استفاده میکنی، مطمئن شو که کد JS بعد از بارگذاری کامل تصاویر اجرا میشه. گاهی اوقات تصاویر هنوز بارگذاری نشدن و JS ارتفاع اشتباه رو محاسبه میکنه.
* **نکته:** چک کن که `grid-auto-flow: dense;` رو در CSS کانتینر اصلیت اضافه کرده باشی. این باعث میشه Grid تلاش کنه جاهای خالی رو پر کنه.
2. **فاصلهها بین آیتمها نامنظم هستند:**
* **بررسی:** از ویژگی `gap` یا `grid-gap` در کانتینر اصلی استفاده کن.
* **راهحل:** اگه از `margin` برای فاصلهگذاری استفاده کردی، سعی کن به `gap` در Grid سوییچ کنی. `gap` بهینهتره و Grid خودش فاصلهها رو مدیریت میکنه.
3. **عملکرد ضعیف در بارگذاری صفحات (کند بودن):**
* **بررسی:** حجم تصاویر رو چک کن. تصاویر با حجم بالا بزرگترین عامل کندی هستن.
* **راهحل:** از `loading=”lazy”` برای تگهای `img` استفاده کن. تصاویر رو به فرمت WebP تبدیل و فشردهسازی کن. اگه تعداد تصاویر خیلی زیاده، میتونی از تکنیک `Infinite Scroll` یا `Pagination` استفاده کنی.
4. **گالری در موبایل بهم ریخته است یا تعداد ستونها مناسب نیست:**
* **بررسی:** `Media Queries` رو به درستی تنظیم کردی؟
* **راهحل:** مطمئن شو که `min-width` در `Media Queries` به ترتیب صعودی (از کوچک به بزرگ) تنظیم شده و برای هر سایز، `grid-template-columns` رو با تعداد ستونهای مناسب ست کردی. یه بار دیگه بخش رسپانسیو رو با دقت مرور کن.
5. **تصاویر از کانتینر والدشون بیرون میزنن یا گوشههاشون گرد نیست:**
* **بررسی:** مطمئن شو که `overflow: hidden;` رو به `gallery-item` اضافه کردی و `border-radius` رو هم به `gallery-item` یا `img` دادی.
* **راهحل:** `object-fit: cover;` رو هم میتونی به `img` اضافه کنی تا اگه ابعاد تصویر با `gallery-item` همخوانی نداشت، به شکل مناسب برش بخوره و کادر رو پر کنه.
اگه با این راه حلها مشکلت حل نشد یا نیاز به کمک تخصصیتر داشتی، همیشه میتونی با تیم فنی ما در تماس باشی. ما آمادهایم که کمکت کنیم! تماس: 09202232789
کدهای آماده و اسنیپتهای مفید
برای اینکه کارت راحتتر بشه، اینجا یه ترکیب کامل از CSS و HTML رو برات گذاشتم. این اسنیپت رو میتونی مستقیم تو پروژهت استفاده کنی و بعداً با تصاویر و محتوای خودت پرش کنی. یادت باشه که برای `grid-row-end` نیاز به محاسبه ارتفاع تصاویر داری، که میتونی این کار رو دستی یا با یک اسکریپت جاوااسکریپت کوچک انجام بدی. اگه دنبال کدهای آماده و اسنیپتهای بیشتر برای بخشهای مختلف پروژههات هستی، حتماً یه سر به این صفحه بزن.
<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>گالری پینترست با CSS Grid</title>
<style>
body {
margin: 0;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f4f7f6;
color: #333;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
.pinterest-gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
gap: 15px;
grid-auto-rows: 10px; /* هر سطر 10px */
grid-auto-flow: dense;
}
.gallery-item {
background-color: #ffffff;
border-radius: 10px;
overflow: hidden;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.08);
display: flex; /* برای توجیه تصویر در مرکز */
align-items: center; /* برای توجیه تصویر در مرکز */
justify-content: center; /* برای توجیه تصویر در مرکز */
/* اینجا باید ارتفاع row-span رو بر اساس ارتفاع تصویر تنظیم کنی */
/* برای مثال، اگه تصویرت 300px ارتفاع داره، اینجا میشه span 30 (چون grid-auto-rows: 10px) */
/* grid-row-end: span 25; -- نمونه برای تصویر با 250px ارتفاع */
/* grid-row-end: span 35; -- نمونه برای تصویر با 350px ارتفاع */
/* grid-row-end: span 40; -- نمونه برای تصویر با 400px ارتفاع */
/* برای هر آیتم باید این مقدار به صورت پویا (با JS) یا دستی تنظیم شود. */
}
.gallery-item img {
width: 100%;
height: auto;
display: block;
border-radius: 10px;
transition: transform 0.3s ease-in-out;
object-fit: cover; /* برای اطمینان از پوشش کامل آیتم */
}
.gallery-item img:hover {
transform: scale(1.05);
}
/* Responsive Styles */
@media (min-width: 600px) {
.pinterest-gallery {
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: 20px;
}
}
@media (min-width: 900px) {
.pinterest-gallery {
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 25px;
}
}
@media (min-width: 1200px) {
.pinterest-gallery {
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
gap: 30px;
}
}
</style>
</head>
<body>
<div class="container">
<h1 style="text-align: center; color: #2c3e50; margin-bottom: 30px;">گالری جذاب من</h1>
<div class="pinterest-gallery">
<div class="gallery-item" style="grid-row-end: span 35;"><img src="https://picsum.photos/400/350?random=1" alt="تصویر تصادفی 1" loading="lazy"></div>
<div class="gallery-item" style="grid-row-end: span 25;"><img src="https://picsum.photos/400/250?random=2" alt="تصویر تصادفی 2" loading="lazy"></div>
<div class="gallery-item" style="grid-row-end: span 45;"><img src="https://picsum.photos/400/450?random=3" alt="تصویر تصادفی 3" loading="lazy"></div>
<div class="gallery-item" style="grid-row-end: span 30;"><img src="https://picsum.photos/400/300?random=4" alt="تصویر تصادفی 4" loading="lazy"></div>
<div class="gallery-item" style="grid-row-end: span 20;"><img src="https://picsum.photos/400/200?random=5" alt="تصویر تصادفی 5" loading="lazy"></div>
<div class="gallery-item" style="grid-row-end: span 50;"><img src="https://picsum.photos/400/500?random=6" alt="تصویر تصادفی 6" loading="lazy"></div>
<div class="gallery-item" style="grid-row-end: span 28;"><img src="https://picsum.photos/400/280?random=7" alt="تصویر تصادفی 7" loading="lazy"></div>
<div class="gallery-item" style="grid-row-end: span 38;"><img src="https://picsum.photos/400/380?random=8" alt="تصویر تصادفی 8" loading="lazy"></div>
<div class="gallery-item" style="grid-row-end: span 22;"><img src="https://picsum.photos/400/220?random=9" alt="تصویر تصادفی 9" loading="lazy"></div>
<div class="gallery-item" style="grid-row-end: span 32;"><img src="https://picsum.photos/400/320?random=10" alt="تصویر تصادفی 10" loading="lazy"></div>
</div>
</div>
<script>
// یک اسکریپت کوچک جاوااسکریپت برای محاسبه خودکار grid-row-end (اختیاری)
document.addEventListener('DOMContentLoaded', () => {
const galleryItems = document.querySelectorAll('.gallery-item');
const gridAutoRows = 10; // باید با مقدار grid-auto-rows در CSS یکی باشد
galleryItems.forEach(item => {
const img = item.querySelector('img');
if (img) {
// منتظر بارگذاری تصویر میمانیم
img.onload = () => {
const imageHeight = img.clientHeight; // ارتفاع واقعی تصویر
const rowSpan = Math.ceil(imageHeight / gridAutoRows);
item.style.gridRowEnd = `span ${rowSpan}`;
};
// اگر تصویر از قبل بارگذاری شده بود (مثلاً در حافظه کش)
if (img.complete) {
const imageHeight = img.clientHeight;
const rowSpan = Math.ceil(imageHeight / gridAutoRows);
item.style.gridRowEnd = `span ${rowSpan}`;
}
}
});
});
</script>
</body>
</html>
(روی کد کلیک کنید تا کپی شود)
**توضیح کد جاوااسکریپت بالا:**
همونطور که دیدی، تو HTML بالا برای `gallery-item`ها مقدار `grid-row-end` رو به صورت `inline style` و دستی ست کردم (برای نشون دادن مثال). اما اسکریپت جاوااسکریپتی که پایین کدهای HTML گذاشتم، میتونه این کار رو به صورت خودکار انجام بده. این اسکریپت بعد از بارگذاری صفحه، ارتفاع واقعی هر تصویر رو محاسبه میکنه و بعد `grid-row-end` اون `gallery-item` رو بر اساس ارتفاع تصویر و `grid-auto-rows` (که 10px تنظیم کردیم) تنظیم میکنه. این باعث میشه گالری شما کاملاً پویا و خودکار باشه و نیاز به هیچ تنظیم دستی برای هر تصویر نداشته باشی.
جمعبندی و گامهای بعدی
تبریک میگم رفیق! حالا تو نه تنها میدونی چطور یه گالری پینترستی رو با کدهای خالص CSS و Grid بسازی، بلکه با نکات پیشرفته، بهینهسازیها و راهحلهای مشکلات رایجش هم آشنا شدی. CSS Grid یه ابزار فوقالعاده قدرتمنده که دستت رو برای پیادهسازی چیدمانهای پیچیده به کلی باز میذاره.
یادت باشه، بهترین راه برای یادگیری، تمرین کردنه. حالا برو و این گالری رو تو پروژههای خودت پیاده کن، با استایلهاش بازی کن، و ایدههای جدید خودت رو بهش اضافه کن. دنیای طراحی وب پر از خلاقیته و تو هم میتونی بخشی از اون باشی.
برای کسب اطلاعات بیشتر در مورد طراحی وب و ابزارهای مورد نیازت، یه سر به صفحه اصلی fa-tools.ir بزن. منتظرت هستیم!
پرسشهای متداول (FAQ)
۱. آیا برای ساخت گالری پینترست حتماً به جاوااسکریپت نیاز دارم؟
خیر، اصول چیدمان با CSS Grid امکانپذیر است. اما برای محاسبه ارتفاع دقیق هر تصویر و تنظیم خودکار `grid-row-end` (که عنصر اصلی چیدمان Masonry است)، استفاده از یک اسکریپت کوچک جاوااسکریپت به شدت توصیه میشود تا گالری شما کاملاً پویا و بدون نیاز به تنظیم دستی باشد.
۲. چه مرورگرهایی از CSS Grid برای این نوع گالری پشتیبانی میکنند؟
تقریباً تمام مرورگرهای مدرن (کروم، فایرفاکس، سافاری، اج) از CSS Grid به طور کامل پشتیبانی میکنند. پشتیبانی این ویژگی بسیار گسترده است و میتوانید با خیال راحت از آن استفاده کنید.
۳. چگونه میتوانم سرعت بارگذاری گالری را افزایش دهم؟
برای افزایش سرعت، تصاویر خود را فشرده و به فرمتهای بهینهتر مانند WebP تبدیل کنید. همچنین، استفاده از ویژگی `loading=”lazy”` در تگ `img` و پیادهسازی `Lazy Loading` (بارگذاری تنبل) برای تصاویر، به طرز چشمگیری سرعت اولیه سایت شما را بهبود میبخشد.
۴. آیا این گالری برای موبایل هم بهینه است؟
بله، با استفاده از `Media Queries` در CSS، میتوانید تعداد ستونها و فاصلهها را برای اندازههای مختلف صفحه (موبایل، تبلت، دسکتاپ) بهینهسازی کنید تا گالری شما در هر دستگاهی به خوبی نمایش داده شود. این مقاله کدهای لازم برای این منظور را ارائه کرده است.
۵. چگونه میتوانم به آیتمهای گالری افکتهای هاور اضافه کنم؟
میتوانید از شبهکلاس `:hover` در CSS استفاده کنید و ویژگیهایی مانند `transform: scale()`, `box-shadow`, `opacity` یا فیلترهای تصویری را تغییر دهید. برای انتقال نرم و روان بین حالت عادی و هاور، از ویژگی `transition` استفاده کنید. مثالهایی در این مطلب ارائه شده است.


