الصور والوسائط المتجاوبة
مشكلة الصور على الويب
الصور هي أحد أكبر التحديات في التصميم المتجاوب للويب. صورة واحدة عالية الدقة مخصصة لشاشة سطح المكتب قد يكون عرضها 2000 بكسل ويبلغ حجمها 500 كيلوبايت أو أكثر. عندما تُقدم نفس الصورة لهاتف بنافذة عرض 375 بكسل على اتصال خلوي بطيء، يحمّل المستخدم 500 كيلوبايت من البيانات فقط ليقوم المتصفح بتقليصها إلى جزء صغير من حجمها. هذا يهدر عرض النطاق الترددي، ويبطئ تحميل الصفحة، ويستنزف البطارية، ويخلق تجربة مستخدم سيئة. تحل الصور المتجاوبة هذه المشكلة بتقديم الصورة المناسبة للسياق المناسب -- ملفات أصغر للشاشات الأصغر، وملفات أكبر للشاشات الأكبر، وقصات مختلفة للتخطيطات المختلفة.
في هذا الدرس، ستتعلم كل تقنية متاحة لجعل الصور والوسائط متجاوبة، من قاعدة CSS البسيطة max-width إلى عناصر HTML القوية srcset و<picture>، إلى جانب خصائص CSS الحديثة مثل object-fit وobject-position وaspect-ratio.
الصور المرنة مع max-width: 100%
أبسط وأهم تقنية للصور المتجاوبة هي قاعدة الصورة المرنة. هذا التصريح الواحد في CSS يمنع الصور من تجاوز حاوياتها:
مثال: الصور المرنة الأساسية
img {
max-width: 100%;
height: auto;
}
/* تطبيق على جميع عناصر الوسائط للتناسق */
img, video, embed, object, svg {
max-width: 100%;
height: auto;
}
كيف يعمل هذا: max-width: 100% يخبر الصورة بأنها لا يمكن أبداً أن تكون أعرض من العنصر الحاوي لها. إذا كان الحاوي بعرض 320 بكسل على الهاتف، ستكون الصورة بحد أقصى 320 بكسل. إذا كان الحاوي بعرض 800 بكسل على سطح المكتب، ستُعرض الصورة بعرض يصل إلى 800 بكسل (لكن لا تتجاوز أبداً عرضها الجوهري). تصريح height: auto يضمن أن الصورة تحافظ على نسبة العرض إلى الارتفاع الطبيعية أثناء التحجيم، مما يمنع التشوه.
max-width: 100% يجعل الصور تتقلص لكنها لا تتمدد أبداً. إذا كانت الصورة بعرض طبيعي 400 بكسل والحاوي 800 بكسل، ستُعرض الصورة بعرض 400 بكسل وليس تمتد إلى 800 بكسل. هذا يمنع الصور الضبابية المكبّرة. إذا أردت أن تملأ الصورة حاويها دائماً بغض النظر عن حجمها الطبيعي، استخدم width: 100% بدلاً من ذلك، لكن كن على دراية بأن الصور الصغيرة ستصبح مبكسلة عند التمدد.فهم object-fit
عندما تحدد أبعاداً صريحة على صورة (باستخدام width وheight في CSS) لا تتطابق مع نسبة العرض إلى الارتفاع الطبيعية للصورة، ستتمدد الصورة أو تنضغط. خاصية object-fit تتحكم في كيفية تغيير حجم محتوى الصورة ليتناسب مع تلك الأبعاد، بشكل مشابه لكيفية عمل background-size لصور الخلفية.
هناك خمس قيم لـ object-fit:
fill (الافتراضي)
الصورة تتمدد لتملأ صندوق محتوى العنصر بالكامل، متجاهلة نسبة العرض إلى الارتفاع. هذا هو السلوك الافتراضي وغالباً ما ينتج عنه صور مشوهة.
مثال: object-fit: fill
.avatar {
width: 200px;
height: 200px;
object-fit: fill; /* الافتراضي: يتمدد للملء، قد يشوه */
}
/* صورة 400×300 مُجبرة في صندوق 200×200
ستنضغط أفقياً */
contain
الصورة تتناسب بالكامل داخل صندوق محتوى العنصر مع الحفاظ على نسبة العرض إلى الارتفاع. الصورة بأكملها مرئية، لكن قد يكون هناك فراغ (أشرطة سوداء) على الجانبين أو أعلى/أسفل.
مثال: object-fit: contain
.product-image {
width: 300px;
height: 300px;
object-fit: contain;
background-color: #f5f5f5; /* يظهر من خلال الفراغ */
}
/* صورة أفقية 600×400 في صندوق 300×300:
الصورة تتقلص إلى 300×200، متمركزة عمودياً
مع 50 بكسل من الفراغ أعلى وأسفل */
cover
الصورة تتناسب لتغطي صندوق محتوى العنصر بالكامل مع الحفاظ على نسبة العرض إلى الارتفاع. قد تُقص الصورة من الجانبين أو أعلى/أسفل، لكن لا يوجد فراغ. هذه هي القيمة الأكثر استخداماً لصور البطل والصور المصغرة للبطاقات وصور الملف الشخصي.
مثال: object-fit: cover
.hero-image {
width: 100%;
height: 400px;
object-fit: cover;
}
.card-thumbnail {
width: 100%;
height: 200px;
object-fit: cover;
}
.avatar-circle {
width: 80px;
height: 80px;
border-radius: 50%;
object-fit: cover;
}
none
الصورة لا يُغير حجمها على الإطلاق. تُعرض بحجمها الطبيعي، وصندوق محتوى العنصر يعمل كنافذة عرض للصورة. إذا كانت الصورة أكبر من العنصر، تتجاوز وتُقص بحدود العنصر.
مثال: object-fit: none
.image-preview {
width: 300px;
height: 200px;
object-fit: none;
overflow: hidden;
}
/* صورة 1200×800 ستُعرض بحجمها الكامل 1200×800،
لكنك ترى فقط المنطقة 300×200 في المنتصف */
scale-down
تُقارن الصورة بحجمي none وcontain، ويُستخدم الأصغر. عملياً، هذا يعني: إذا كانت الصورة أكبر من العنصر، تتصرف مثل contain (تتقلص). إذا كانت الصورة أصغر من العنصر، تتصرف مثل none (تبقى بحجمها الطبيعي). هذا مفيد عندما تريد أن تتقلص الصور لكن لا تتمدد أبداً أكبر من حجمها الطبيعي.
مثال: object-fit: scale-down
.icon-display {
width: 200px;
height: 200px;
object-fit: scale-down;
}
/* أيقونة 64×64 تبقى بحجم 64×64 (مثل 'none')
صورة 800×600 تتقلص لتتناسب (مثل 'contain') */
مثال: مقارنة جميع قيم object-fit جنباً إلى جنب
.comparison-box {
width: 250px;
height: 250px;
border: 2px solid #ddd;
}
.box-fill { object-fit: fill; } /* يتمدد، قد يشوه */
.box-contain { object-fit: contain; } /* يتناسب بالداخل، قد يترك فراغ */
.box-cover { object-fit: cover; } /* يملأ بالكامل، قد يقص */
.box-none { object-fit: none; } /* الحجم الطبيعي، قد يتجاوز */
.box-scale { object-fit: scale-down; } /* الأصغر من none/contain */
التحكم في الموضع مع object-position
عند استخدام object-fit: cover أو object-fit: none، قد تُقص الصورة. افتراضياً، يضع المتصفح الصورة في منتصف العنصر. خاصية object-position تتيح لك التحكم في أي جزء من الصورة يكون مرئياً. تعمل تماماً مثل background-position وتقبل نفس القيم: كلمات مفتاحية ونسب مئوية وقيم طول.
مثال: object-position مع cover
/* الافتراضي: center center -- يقص بالتساوي من جميع الجوانب */
.hero {
width: 100%;
height: 400px;
object-fit: cover;
object-position: center center;
}
/* التركيز على أعلى الصورة (مفيد للصور الشخصية) */
.portrait-hero {
width: 100%;
height: 300px;
object-fit: cover;
object-position: center top;
}
/* التركيز على الجانب الأيسر من الصورة */
.left-focused {
width: 100%;
height: 300px;
object-fit: cover;
object-position: left center;
}
/* تموضع دقيق بالنسب المئوية */
.custom-focus {
width: 100%;
height: 300px;
object-fit: cover;
object-position: 30% 20%; /* 30% من اليسار، 20% من الأعلى */
}
/* إزاحة بالبكسل من الزاوية العلوية اليسرى */
.pixel-offset {
width: 200px;
height: 200px;
object-fit: none;
object-position: -50px -30px; /* إزاحة الصورة لليسار 50 بكسل ولأعلى 30 بكسل */
}
object-fit: cover لصور الملف الشخصي أو الصور الشخصية، حدد دائماً object-position: center top. هذا يضمن بقاء وجه الشخص مرئياً حتى عندما تُقص الصورة بشكل كبير على الهاتف المحمول، لأن الوجوه تكون دائماً تقريباً في الجزء العلوي من الصور الشخصية.خاصية aspect-ratio
خاصية aspect-ratio هي إضافة حديثة لـ CSS تحدد نسبة عرض إلى ارتفاع مفضلة للعنصر. قبل وجود هذه الخاصية، كان المطورون يستخدمون "خدعة padding-top" (حيلة الحشو المبنية على النسب المئوية) للحفاظ على نسب العرض إلى الارتفاع. الآن، يمكنك ببساطة الإعلان عن النسبة مباشرة.
مثال: استخدام aspect-ratio
/* نسبة الشاشة العريضة 16:9 */
.video-container {
width: 100%;
aspect-ratio: 16 / 9;
background: #000;
}
/* مربع مثالي */
.square-card {
width: 100%;
aspect-ratio: 1 / 1;
}
/* نسبة الصورة التقليدية 4:3 */
.photo-frame {
width: 100%;
aspect-ratio: 4 / 3;
}
/* مع object-fit للصور */
.card-image {
width: 100%;
aspect-ratio: 3 / 2;
object-fit: cover;
}
/* متجاوب: تغيير النسبة عند نقاط توقف مختلفة */
.hero-banner {
width: 100%;
aspect-ratio: 1 / 1; /* مربع على الهاتف */
object-fit: cover;
}
@media (min-width: 768px) {
.hero-banner {
aspect-ratio: 16 / 9; /* شاشة عريضة على سطح المكتب */
}
}
aspect-ratio تحدد نسبة مفضلة، لكن يمكن تجاوزها بتصريحات height وwidth الصريحة. إذا حددت كلاً من width: 300px وheight: 200px، يتم تجاهل aspect-ratio لأن الأبعاد محددة بالفعل بالكامل. الخاصية أكثر فائدة عندما يتم تحديد بُعد واحد فقط (مثل width: 100%) وتريد حساب الآخر تلقائياً.الصور المتجاوبة مع srcset وsizes
بينما max-width: 100% في CSS يجعل الصورة متجاوبة بصرياً، فهو لا يحل مشكلة الأداء: المتصفح لا يزال يحمّل الملف بالحجم الكامل. خاصيتا HTML srcset وsizes تسمحان لك بتوفير نسخ متعددة من نفس الصورة بدقات مختلفة، ويختار المتصفح الأنسب بناءً على حجم نافذة العرض ونسبة كثافة البكسل في الجهاز.
واصفات العرض (w)
الاستخدام الأكثر شيوعاً لـ srcset هو مع واصفات العرض، التي تخبر المتصفح بالعرض الفعلي بالبكسل لكل ملف صورة:
مثال: srcset مع واصفات العرض
<img
src="photo-800.jpg"
srcset="
photo-400.jpg 400w,
photo-800.jpg 800w,
photo-1200.jpg 1200w,
photo-1600.jpg 1600w
"
sizes="
(max-width: 600px) 100vw,
(max-width: 1200px) 50vw,
33vw
"
alt="منظر طبيعي لجبال عند الغروب"
width="1600"
height="900"
>
دعنا نفصل هذا جزءاً بجزء:
- src -- الصورة الاحتياطية للمتصفحات التي لا تدعم
srcset. - srcset -- قائمة مفصولة بفواصل من ملفات الصور مع عرضها.
photo-400.jpg 400wيخبر المتصفح أن هذا الملف بعرض 400 بكسل. - sizes -- يخبر المتصفح بعرض عرض الصورة عند كل حجم نافذة عرض. قراءة خاصية sizes: "إذا كانت نافذة العرض بحد أقصى 600 بكسل، تأخذ الصورة 100% من عرض نافذة العرض. إذا كانت نافذة العرض بحد أقصى 1200 بكسل، تأخذ الصورة 50%. وإلا، 33%."
يستخدم المتصفح معلومات sizes مع نسبة كثافة البكسل في الجهاز لحساب أي ملف يُحمّل. على هاتف بنافذة عرض 375 بكسل وشاشة 2x، يحسب المتصفح: 375 بكسل × 2 = 750 بكسل مطلوبة، فيحمّل photo-800.jpg (الأقرب فوق 750 بكسل). على سطح مكتب بنافذة عرض 1440 بكسل يعرض الصورة بـ 33vw: 1440 × 0.33 = 475 بكسل، فإن photo-800.jpg كافية لشاشة 1x، أو photo-1200.jpg لشاشة 2x.
واصفات كثافة البكسل (x)
للصور التي تُعرض دائماً بنفس حجم CSS (مثل الشعارات أو الأيقونات)، يمكنك استخدام واصفات كثافة البكسل بدلاً من واصفات العرض:
مثال: srcset مع واصفات كثافة البكسل
<img
src="logo-1x.png"
srcset="
logo-1x.png 1x,
logo-2x.png 2x,
logo-3x.png 3x
"
alt="شعار الشركة"
width="200"
height="60"
>
/* المتصفح يختار الملف المطابق لنسبة كثافة بكسل الجهاز:
- شاشة قياسية (1x): يحمّل logo-1x.png (200 بكسل)
- شاشة ريتينا (2x): يحمّل logo-2x.png (400 بكسل)
- هاتف عالي الكثافة (3x): يحمّل logo-3x.png (600 بكسل) */
x وواصفات w في نفس خاصية srcset. هما متنافيان. استخدم واصفات w مع sizes للصور المرنة العرض، وواصفات x للصور ثابتة الحجم. إذا حذفت خاصية sizes عند استخدام واصفات w، يفترض المتصفح sizes="100vw"، مما قد يسبب تحميل صور أكبر من اللازم.عنصر picture للتوجيه الفني
بينما يتيح srcset للمتصفح الاختيار بين دقات مختلفة لنفس الصورة، عنصر <picture> يمنحك تحكماً كاملاً في أي ملف صورة يُحمّل عند كل نقطة توقف. يُسمى هذا التوجيه الفني -- تقديم قصات أو تكوينات صورة مختلفة تماماً لأحجام شاشات مختلفة.
مثلاً، صورة أفقية واسعة تعمل على سطح المكتب، لكن على الهاتف، قد تريد نسخة مقصوصة بإحكام تركز على الموضوع. مع srcset وحده، يقوم المتصفح فقط بتحجيم نفس الصورة. مع <picture>، يمكنك تحديد صورة مختلفة تماماً.
مثال: التوجيه الفني مع picture
<picture>
<!-- الهاتف: نسخة شخصية مقصوصة بإحكام -->
<source
media="(max-width: 599px)"
srcset="hero-mobile.jpg"
>
<!-- الأجهزة اللوحية: قص متوسط -->
<source
media="(min-width: 600px) and (max-width: 1023px)"
srcset="hero-tablet.jpg"
>
<!-- سطح المكتب: نسخة أفقية واسعة -->
<source
media="(min-width: 1024px)"
srcset="hero-desktop.jpg"
>
<!-- احتياطي للمتصفحات التي لا تدعم picture -->
<img src="hero-desktop.jpg" alt="فريق يعمل في مكتب حديث" width="1600" height="900">
</picture>
مثال: التوجيه الفني مع srcset لتبديل الدقة
<picture>
<!-- الهاتف: نسخة مقصوصة، دقات متعددة -->
<source
media="(max-width: 767px)"
srcset="
hero-mobile-400.jpg 400w,
hero-mobile-800.jpg 800w
"
sizes="100vw"
>
<!-- سطح المكتب: النسخة الكاملة، دقات متعددة -->
<source
media="(min-width: 768px)"
srcset="
hero-desktop-800.jpg 800w,
hero-desktop-1200.jpg 1200w,
hero-desktop-1600.jpg 1600w
"
sizes="100vw"
>
<img src="hero-desktop-1200.jpg" alt="أفق مدينة بانورامي" width="1600" height="600">
</picture>
استخدام picture لاختيار التنسيق
يمكن لعنصر <picture> أيضاً تقديم تنسيقات صور مختلفة، مما يسمح لك باستخدام تنسيقات حديثة مثل WebP أو AVIF للمتصفحات التي تدعمها، مع احتياطيات JPEG أو PNG:
مثال: اختيار التنسيق مع picture
<picture>
<!-- AVIF: أفضل ضغط، أحدث تنسيق -->
<source type="image/avif" srcset="photo.avif">
<!-- WebP: ضغط ممتاز، دعم واسع -->
<source type="image/webp" srcset="photo.webp">
<!-- JPEG: احتياطي عالمي -->
<img src="photo.jpg" alt="عرض المنتج" width="800" height="600">
</picture>
/* المتصفح يفحص المصادر بالترتيب:
1. هل يمكنني عرض AVIF؟ نعم -> يحمّل photo.avif (الأصغر)
2. هل يمكنني عرض WebP؟ نعم -> يحمّل photo.webp (أصغر)
3. يعود إلى photo.jpg (الأكبر، لكن بدعم عالمي) */
صور خلفية CSS عند نقاط التوقف
للصور الزخرفية أو عناصر التصميم المحددة عبر background-image في CSS، يمكنك استخدام استعلامات الوسائط لتقديم صور مختلفة عند نقاط توقف مختلفة:
مثال: صور خلفية CSS متجاوبة
/* الهاتف: صورة خلفية صغيرة */
.hero-section {
background-image: url('hero-mobile.jpg');
background-size: cover;
background-position: center;
min-height: 300px;
}
/* الأجهزة اللوحية: صورة متوسطة */
@media (min-width: 768px) {
.hero-section {
background-image: url('hero-tablet.jpg');
min-height: 450px;
}
}
/* سطح المكتب: صورة بالدقة الكاملة */
@media (min-width: 1200px) {
.hero-section {
background-image: url('hero-desktop.jpg');
min-height: 600px;
}
}
/* شاشات ريتينا/عالية الكثافة: تقديم صور 2x */
@media (min-width: 1200px) and (min-resolution: 2dppx) {
.hero-section {
background-image: url('hero-desktop-2x.jpg');
}
}
/* استخدام image-set() للمتصفحات الحديثة */
.modern-hero {
background-image: image-set(
url('hero.avif') type('image/avif'),
url('hero.webp') type('image/webp'),
url('hero.jpg') type('image/jpeg')
);
background-size: cover;
background-position: center;
}
<img> مع نص alt مناسب بدلاً من ذلك. صور الخلفية غير مرئية لقارئات الشاشة ولا يمكن أن تحتوي على نص بديل، لذا استخدامها لصور المحتوى يخلق مشاكل في إمكانية الوصول.تضمين الفيديو المتجاوب
الفيديوهات لها نسبة عرض إلى ارتفاع ثابتة (عادةً 16:9)، لكن حاوياتها قد تكون مرنة. التحدي هو الحفاظ على نسبة عرض إلى ارتفاع الفيديو مع تغير عرض الحاوي. هناك نهجان: خدعة padding-top الكلاسيكية وخاصية aspect-ratio الحديثة.
خدعة Padding-Top الكلاسيكية
هذه التقنية تستغل حقيقة أن الحشو المبني على النسب المئوية يُحسب نسبة إلى عرض العنصر وليس ارتفاعه. لنسبة 16:9، يُحسب padding-top كـ (9 / 16) × 100 = 56.25%:
مثال: فيديو متجاوب مع خدعة Padding-Top
/* HTML:
<div class="video-wrapper">
<iframe src="https://www.youtube.com/embed/VIDEO_ID"
allowfullscreen></iframe>
</div>
*/
.video-wrapper {
position: relative;
padding-top: 56.25%; /* نسبة 16:9: (9/16)*100 */
width: 100%;
overflow: hidden;
}
.video-wrapper iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: 0;
}
/* لفيديوهات بنسبة 4:3: (3/4)*100 = 75% */
.video-wrapper-4x3 {
padding-top: 75%;
}
/* لنسبة 21:9 عريضة جداً: (9/21)*100 = 42.86% */
.video-wrapper-ultrawide {
padding-top: 42.86%;
}
نهج aspect-ratio الحديث
خاصية aspect-ratio تجعل حاويات الفيديو المتجاوبة أبسط بكثير:
مثال: فيديو متجاوب مع aspect-ratio
/* النهج الحديث: أنظف بكثير */
.video-wrapper {
position: relative;
width: 100%;
aspect-ratio: 16 / 9;
}
.video-wrapper iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: 0;
}
/* أبسط مع تنسيق iframe مباشر */
iframe.responsive-video {
width: 100%;
aspect-ratio: 16 / 9;
border: 0;
}
إطارات iframe المتجاوبة
إطارات iframe للمحتوى المضمن (الخرائط، عروض CodePen، منشورات وسائل التواصل الاجتماعي) تقدم نفس تحدي نسبة العرض إلى الارتفاع مثل الفيديوهات. نفس التقنيات تُطبق:
مثال: إطارات iframe المتجاوبة
/* حاوي iframe متجاوب عام */
.iframe-container {
width: 100%;
aspect-ratio: 16 / 9;
position: relative;
}
.iframe-container iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: 0;
}
/* تضمين خريطة: قد تريد نسبة مختلفة على الهاتف مقابل سطح المكتب */
.map-container {
width: 100%;
aspect-ratio: 1 / 1; /* مربع على الهاتف */
}
@media (min-width: 768px) {
.map-container {
aspect-ratio: 16 / 9; /* شاشة عريضة على سطح المكتب */
}
}
/* iframe بعرض كامل يحترم max-width */
.content-embed {
width: 100%;
max-width: 800px;
margin: 0 auto;
aspect-ratio: 4 / 3;
}
التحميل الكسول للصور
التحميل الكسول يؤجل تحميل الصور خارج الشاشة حتى يقترب المستخدم منها بالتمرير. هذا يحسن بشكل كبير وقت تحميل الصفحة الأولي لأن المتصفح يحمّل فقط الصور المرئية فعلاً. يوفر HTML تحميلاً كسولاً أصلياً مع خاصية loading:
مثال: التحميل الكسول الأصلي
<!-- فوري: يُحمّل مباشرة (السلوك الافتراضي) -->
<img src="hero.jpg" alt="لافتة البطل" loading="eager" width="1600" height="900">
<!-- كسول: يُحمّل عندما يمرر المستخدم بالقرب -->
<img src="photo-1.jpg" alt="صورة المعرض 1" loading="lazy" width="800" height="600">
<img src="photo-2.jpg" alt="صورة المعرض 2" loading="lazy" width="800" height="600">
<img src="photo-3.jpg" alt="صورة المعرض 3" loading="lazy" width="800" height="600">
<!-- التحميل الكسول مع srcset -->
<img
src="product-800.jpg"
srcset="product-400.jpg 400w, product-800.jpg 800w, product-1200.jpg 1200w"
sizes="(max-width: 768px) 100vw, 50vw"
alt="صورة المنتج"
loading="lazy"
width="1200"
height="800"
>
<!-- التحميل الكسول لإطارات iframe -->
<iframe src="https://www.youtube.com/embed/VIDEO_ID"
loading="lazy"
width="560"
height="315"
allowfullscreen></iframe>
loading="eager" (أو ببساطة احذف خاصية loading، حيث أن eager هو الافتراضي). التحميل الكسول للصور فوق الطي يضر فعلاً بالأداء لأن المتصفح يؤخر تحميل المحتوى الذي يحتاج المستخدم لرؤيته فوراً. للصور الحرجة فوق الطي، أضف أيضاً fetchpriority="high" لإخبار المتصفح بإعطائها الأولوية.مثال: استراتيجية أولوية التحميل الصحيحة
<!-- فوق الطي: تحميل فوري بأولوية عالية -->
<img src="hero.jpg" alt="البطل" fetchpriority="high" width="1600" height="900">
<img src="logo.png" alt="الشعار" fetchpriority="high" width="200" height="60">
<!-- تحت الطي: تحميل كسول -->
<img src="feature-1.jpg" alt="الميزة 1" loading="lazy" width="600" height="400">
<img src="feature-2.jpg" alt="الميزة 2" loading="lazy" width="600" height="400">
<img src="feature-3.jpg" alt="الميزة 3" loading="lazy" width="600" height="400">
أداء الصور: التنسيقات الحديثة
اختيار تنسيق الصورة المناسب له تأثير هائل على الأداء. التنسيقات الحديثة يمكن أن تقلل أحجام الملفات بنسبة 25-50% مقارنة بـ JPEG وPNG التقليديين، بدون فقدان جودة مرئي.
مقارنة التنسيقات
- JPEG -- التنسيق الكلاسيكي للصور الفوتوغرافية. ضغط جيد، دعم عالمي. استخدمه للصور والصور المعقدة ذات الألوان الكثيرة.
- PNG -- تنسيق بدون فقدان يدعم الشفافية. أحجام ملفات أكبر من JPEG. استخدمه للرسومات ذات الحواف الحادة والنصوص والشعارات أو عندما تحتاج للشفافية.
- WebP -- تنسيق Google الحديث. أصغر بنسبة 25-35% من JPEG بجودة مكافئة. يدعم الشفافية والرسوم المتحركة. لديه دعم ممتاز في المتصفحات (أكثر من 97% عالمياً).
- AVIF -- أحدث تنسيق، مبني على ترميز فيديو AV1. أصغر بنسبة 50% من JPEG بجودة مكافئة. يدعم الشفافية وHDR والنطاق اللوني الواسع. دعم المتصفحات ينمو بسرعة (أكثر من 92% عالمياً) لكن الترميز أبطأ.
- SVG -- تنسيق متجهي للأيقونات والشعارات والرسوم التوضيحية. قابل للتحجيم لا نهائياً بدون فقدان الجودة. حجم ملف صغير للرسومات البسيطة. غير مناسب للصور الفوتوغرافية.
مثال: تقديم تنسيقات حديثة مع احتياطي
<picture>
<source type="image/avif" srcset="photo.avif">
<source type="image/webp" srcset="photo.webp">
<img src="photo.jpg" alt="نص وصفي" width="800" height="600">
</picture>
/* المتصفح يفحص المصادر بالترتيب:
1. هل يمكنني عرض AVIF؟ نعم -> يحمّل photo.avif (الأصغر)
2. هل يمكنني عرض WebP؟ نعم -> يحمّل photo.webp (أصغر)
3. يعود إلى photo.jpg (الأكبر، لكن بدعم عالمي) */
width وheight على عناصر <img>، حتى عند استخدام CSS للتحجيم المتجاوب. هذه الخاصيات تسمح للمتصفح بحساب نسبة عرض إلى ارتفاع الصورة قبل تحميلها، مما يمنع انزياح التخطيط (Cumulative Layout Shift أو CLS). هذا مقياس أساسي في Core Web Vitals يؤثر على ترتيب البحث.SVG المتجاوب
SVG (رسومات متجهية قابلة للتحجيم) متجاوب بطبيعته لأنه يستخدم أوصافاً رياضية للأشكال بدلاً من البكسل. ومع ذلك، هناك تقنيات محددة لضمان تصرف SVG بشكل صحيح عبر أحجام نوافذ العرض المختلفة.
مثال: SVG مضمن متجاوب
<!-- SVG مضمن: استخدم viewBox، احذف width/height للتحجيم المرن -->
<svg viewBox="0 0 200 100" role="img" aria-label="شعار الشركة">
<rect x="10" y="10" width="80" height="80" fill="#2563eb" />
<text x="110" y="60" fill="#1f2937" font-size="24">العلامة</text>
</svg>
<!-- CSS للتحكم في حجم SVG -->
<style>
svg {
width: 100%;
max-width: 300px;
height: auto;
}
</style>
مثال: SVG كوسم img
<!-- SVG يُستخدم كصورة عادية -->
<img src="illustration.svg" alt="رسم توضيحي تقني" width="600" height="400">
<style>
/* صور SVG المتجاوبة تتبع نفس قواعد الصور النقطية */
img[src$=".svg"] {
max-width: 100%;
height: auto;
}
</style>
مثال: SVG يتغير عند نقاط التوقف
/* عرض مستويات تفصيل مختلفة بأحجام مختلفة */
.logo-icon .detail-elements {
display: none; /* إخفاء التفاصيل على الهاتف */
}
@media (min-width: 768px) {
.logo-icon .detail-elements {
display: block; /* عرض التفاصيل الكاملة على الشاشات الأكبر */
}
}
/* تغيير حجم SVG مع CSS */
.icon {
width: 24px;
height: 24px;
}
@media (min-width: 768px) {
.icon {
width: 32px;
height: 32px;
}
}
مثال عملي كامل
دعنا نجمع كل شيء معاً في معرض صور متجاوب واقعي يستخدم جميع التقنيات المغطاة في هذا الدرس:
مثال: معرض صور متجاوب كامل
<!-- هيكل HTML -->
<section class="gallery" aria-label="معرض الصور">
<h2>أعمالنا</h2>
<div class="gallery-grid">
<!-- صورة متجاوبة كاملة مع توجيه فني + اختيار تنسيق -->
<figure class="gallery-item gallery-item--featured">
<picture>
<source
media="(max-width: 767px)"
type="image/avif"
srcset="project1-mobile.avif"
>
<source
media="(max-width: 767px)"
type="image/webp"
srcset="project1-mobile.webp"
>
<source
media="(max-width: 767px)"
srcset="project1-mobile.jpg"
>
<source
media="(min-width: 768px)"
type="image/avif"
srcset="project1-desktop.avif"
>
<source
media="(min-width: 768px)"
type="image/webp"
srcset="project1-desktop.webp"
>
<img
src="project1-desktop.jpg"
alt="تصميم موقع تجارة إلكترونية حديث"
loading="eager"
fetchpriority="high"
width="1200"
height="800"
>
</picture>
<figcaption>إعادة تصميم التجارة الإلكترونية</figcaption>
</figure>
<!-- عناصر معرض بتحميل كسول قياسي -->
<figure class="gallery-item">
<img
src="project2-800.jpg"
srcset="project2-400.jpg 400w, project2-800.jpg 800w"
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
alt="واجهة تطبيق بنكي للهاتف"
loading="lazy"
width="800"
height="600"
>
<figcaption>تطبيق البنك</figcaption>
</figure>
</div>
</section>
<style>
/* شبكة المعرض: متجاوبة بدون استعلامات وسائط */
.gallery-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 16px;
padding: 16px;
}
/* العنصر المميز يمتد بعرض كامل على جميع الشاشات */
.gallery-item--featured {
grid-column: 1 / -1;
}
/* تحجيم صورة متسق داخل البطاقات */
.gallery-item img {
width: 100%;
aspect-ratio: 4 / 3;
object-fit: cover;
border-radius: 8px;
display: block;
}
.gallery-item--featured img {
aspect-ratio: 16 / 9;
}
/* تنسيق figure متجاوب */
.gallery-item {
margin: 0;
}
.gallery-item figcaption {
padding: 8px 0;
font-weight: 600;
}
@media (min-width: 768px) {
.gallery-grid {
gap: 24px;
padding: 24px;
}
}
</style>
تمرين عملي
ابنِ صفحة معرض أعمال متجاوبة تعرض مهاراتك في الصور والوسائط. يجب أن تتضمن الصفحة: (1) قسم بطل بصورة خلفية بعرض كامل تقدم قصات مختلفة على الهاتف مقابل سطح المكتب باستخدام عنصر <picture>. (2) صورة ملف شخصي تستخدم object-fit: cover وobject-position: center top داخل حاوي دائري. (3) معرض مشاريع بأربع صور على الأقل تستخدم srcset وsizes لتبديل الدقة، وaspect-ratio لتحجيم بطاقات متسق، وloading="lazy" للصور تحت الطي. (4) فيديو YouTube مضمن متجاوب باستخدام خاصية aspect-ratio. (5) شعار أو أيقونة SVG واحدة على الأقل تتناسب بشكل متجاوب. لجميع الصور، وفر نسخ WebP بجانب JPEG باستخدام عنصر <picture> لاختيار التنسيق. تحقق من أن صورة البطل تُحمّل فورياً مع fetchpriority="high"، بينما صور المعرض تُحمّل كسولاً. استخدم تبويب الشبكة في أدوات المطور في المتصفح للتأكد من أن أجهزة الهاتف المحمول تحمّل ملفات صور أصغر من أجهزة سطح المكتب.