اذهب إلى المحتوى

الصور في تصميم صفحات الويب المتجاوب


Bassel Alkhatib

يُمكن في تصميم الويب المتجاوب تغيير المحتوى إضافًة إلى تغيير التخطيط وفقًا لمواصفات الجهاز. يمكن عرض الصور عالية الدقة على نحوٍ ممتاز على الشاشات عالية الدقة (2x)؛ كما يُمكن أن تظهر صورةٌ عرضها 50% جيدًا على متصفحٍ عرضه 800px، بينما ستستهلك كثيرًا من المساحة على هاتفٍ ضيق، كما أن تحجيمها لملاءمة الشاشات الصغيرة سيتطلب نفس تكلفة حيّز النطاق التراسلي bandwidth.

الإدارة الفنية

025art-direction.png

تتطلب مسائلٌ أخرى إجراء تغييرات جذرية على الصور، مثل تغيير نسب الصورة، أو القص، أو حتى استبدال كامل الصورة، وتُدعى هذه التغييرات بالإدارة الفنية ويُمكن العودة إلى responsiveimages.org لمزيدٍ من الأمثلة.

الصور المتجاوبة

ربما لا يعلم الأشخاص أن الصور تُمثّل أكثر من 60٪ وسطيًا من البايتات اللازمة لتحميل صفحة ويب. سنعرض فيما يلي كيفية التعامل مع الصور الموجودة على الويب الحديث بحيث تبدو الصور رائعةً وتُحمّل على أي جهازٍ بسرعة. كما نشرح مجموعةً من المهارات والتقنيات لمكاملة الصور المتجاوبة ضمن تسلسل عمليات تطوير صفحات الويب؛ بحيث تتكيف هذه الصور وتُلائم حجوم إطارات العرض المختلفة وسيناريوهات الاستخدام المتعددة.

الصور في لغات الترميز markup

يُعدّ العنصر img من العناصر الأساسية القوية فهو ينزِّل المحتوى ويفك ترميزه ويعرضه، كما تدعم المتصفحات الحديثة طيفًا واسعًا من تنسيقات الصور. لا يختلف تضمين الصور في الأجهزة المختلفة عن تضمينها في حاسوبٍ مكتبي مع ضرورة إجراء بعض التعديلات الطفيفة أحيانًا لتحقيق تجربة استخدامٍ جيدة. يجب عمومًا الانتباه لما يلي:

  • استخدام الحجوم النسبية للصور لمنع امتدادها خارج حاويتها عن طريق الخطأ.
  • استخدام العنصر picture لتحديد صورٍ مختلفة تظهر واحدةٌ منها وفق مواصفات جهاز العرض (الإدارة الفنية).
  • استخدام السمة "مجموعة المصادر" srcset والسمة x في العنصر img لإرشاد المتصفح لاختيار الصورة الأنسب من بين كثافاتٍ مختلفة.
  • استخدام الصور السطرية inline في حال احتواء الصفحة على صورةٍ أو صورتين لتخفيض عدد طلبات تحميل ملف الصورة.

استخدام الحجم النسبي للصور

لا بُدّ من استخدام الوحدات النسبية عند تحديد عرض الصورة كي لا تمتد خارج إطار العرض عن طريق الخطأ؛ فعند تحديد العرض إلى width: 50% مثلًا، سيكون عرض الصورة دومًا 50% من عرض حاويتها وليس 50% من عرض إطار العرض أو من عرض الصورة نفسها.

يُمكن أيضًا أن نحتاج لاستخدام max-width: 100% وذلك لسماح أنماط CSS للمحتوى بالامتداد خارج حاويته.

img, embed, object, video {
  max-width: 100%;
}

يجب توفير وصفٍ مفيدٍ للصورة باستخدام السمة alt في عناصر img؛ مما يُساعد قارئات الشاشة والتقنيات المساعدة الأخرى من الوصول للموقع بسهولةٍ أكبر.

تحسين عنصر الصور img باستخدام السمة srcset للأجهزة عالية الكثافة

تُحسّن السمة srcset من أداء العنصر img، حيث توفّر مجموعة ملفات صور متعددة للاختيار منها وفقًا لمواصفات الجهاز. على غرار الدالة image-set الأساسية في أنماط CSS، تسمح السمة srcset للمتصفح باختيار الصورة الأنسب وفقًا لمواصفات الجهاز، مثل استخدام صورة 2x على شاشة عرض 2x، أو ربما لاحقًا، صورة 1x على شاشة 2x عند محدودية النطاق الترددي للشبكة المستخدمة.

<img src="photo.png" srcset="photo@2x.png 2x" ...>

تستخدم المتصفحات التي لا تدعم srcset ملف الصورة الافتراضي المُحدّد بالسمة src، لذا فمن المهم دومًا تضمين صورة 1x يُمكن عرضها على أي جهازٍ بغض النظر عن إمكاناته؛ أما في حال دعم السمة srcset، فتُحلّل قائمة الصور/الشروط المفصولة بفواصل قبل أي طلب، ومن ثم تُنزّل وتُعرض الصورة الأكثر ملاءمة.

يُمكن للشروط الموضوعة على الصور أن تحوي أي شيءٍ، مثل كثافة البكسلات والعرض والطول، إلا أن الكثافة فقط هي المدعومة حاليًا. يجب دومًا توفير صورة 2x لتحقيق التوازن بين السلوك الحالي والميزات المستقبلية لاحقًا.

الإدارة الفنية للصور المتجاوبة باستخدام العنصر picture

يُمكن تغيير الصور وفقًا لمواصفات الجهاز والمعروفة أيضًا باسم الإدارة الفنية، باستخدام العنصر picture؛ الذي يوفر إمكانية التصريح لمجموعةٍ من الصور المختلفة للاختيار منها وفقًا لمواصفات الجهاز، مثل الحجم والدقة والاتجاه وغيرها.

025art-direction.png

يتزايد دعم العنصر picture في المتصفحات، بالرغم من عدم توفره في جميعها بعد؛ ولكن يُنصح باستخدام هذا العنصر لتوافقه الكبير مع الإصدارات السابقة واحتمال استخدام المزايا التي توفّرها تقنيات الصور المتجاوبة المتوفرة في المشروع من النمط "نقص الدعم" Picturefill polyfill.

يُستخدم العنصر picture عند توفُّر الصورة بكثافاتٍ مختلفة؛ أو عندما يتطلب التصميم المتجاوب عرض صورٍ مختلفة على بعض أنواع الشاشات. وعلى غرار عنصر الفيديو video، يُمكن تضمين عدة عناصر "مصدر" source لتحديد ملفات صورٍ مختلفة اعتمادًا على استعلامات الوسائط أو تنسيق الصورة.

<picture>
  <source media="(min-width: 800px)" srcset="head.jpg, head-2x.jpg 2x">
  <source media="(min-width: 450px)" srcset="head-small.jpg, head-small-2x.jpg 2x">
  <img src="head-fb.jpg" srcset="head-fb-2x.jpg 2x" alt="a head carved out of wood">
</picture>

يُمكن معاينة مثال github.io.

يستخدم المتصفح في المثال السابق الصورة head.jpg، أو الصورة head-2x.jpg (حسب دقة الجهاز) إذا كان عرضه 800px على الأقل؛ أما إذا كان عرض المتصفح بين 450px و 800px، فيستخدم head-small.jpg، أو head-small- 2x.jpg (حسب دقة الجهاز)؛ بينما تُعرض الصورة المُحدّدة في العنصر img (والواجب تضمينه دائمًا) على الشاشات ذات العرض الأصغر من 450px، أو في حال عدم دعم العنصر picture.

الصور ذات الحجم النسبي

يُمكن أن يكون صعبًا تحديد كثافة الصور في حال عدم معرفة الحجم النهائي للصورة، خصوصًا مع الصور المُنسابة والتي يُمكن أن تمتد لتتناسب مع عرض المتصفح. يُمكن عوضًا عن تقديم حجوم وكثافات ثابتة، تحديد حجم كل صورة بضبط سمة العرض إضافًة لحجم عنصر الصورة؛ مما يسمح للمتصفح حساب كثافة البكسلات تلقائيًا واختيار الصورة الأنسب للتنزيل.

<img src="lighthouse-200.jpg" sizes="50vw"
     srcset="lighthouse-100.jpg 100w, lighthouse-200.jpg 200w,
             lighthouse-400.jpg 400w, lighthouse-800.jpg 800w,
             lighthouse-1000.jpg 1000w, lighthouse-1400.jpg 1400w,
             lighthouse-1800.jpg 1800w" alt="a lighthouse">

يُمكن معاينة المثال

يعرض المثال السابق صورةً لها نصف عرض إطار العرض sizes="50vw"‎، ويختار المتصفح الصورة المناسبة اعتمادًا على عرض المتصفح وعلى نسبة البكسلات في الجهاز وذلك بغض النظر عن حجم نافذة المتصفح. يُبين الجدول التالي بعض الأمثلة عن الصور التي سيختارها المتصفح:

عرض المتصفح نسبة البكسلات للجهاز الصورة المستخدمة الدقة الفعلية
1x 200.jpg 1 400px
2x 400.jpg 2 400px
2.5x 400.jpg 2 320px
2.67x 800.jpg 2 600px
3.125x 1000.jpg 3 640px
1.45x 800.png 1 1100px

الصور المتجاوبة والنقاط الحدية

يُمكن تغيير حجم الصورة اعتمادًا على النقاط الحدّية المُحدّدة في تخطيط الموقع. مثلًا: يُمكن تفضيل امتداد صورة على كامل عرض إطار العرض في شاشة صغيرة، مع وضعها في جزء صغير من شاشة كبيرة.

<img src="400.png" 
     sizes="(min-width: 600px) 25vw, (min-width: 500px) 50vw, 100vw"
     srcset="100.png 100w, 200.png 200w, 400.png 400w,
             800.png 800w, 1600.png 1600w, 2000.png 2000w" alt="an example image">

يُمكن معاينة المثال

تستخدم سمة الحجوم sizes في المثال السابق عدة استعلامات وسائط لتحديد حجم الصورة. يُصبح حجم الصورة 25% من عرض إطار العرض عندما يتجاوز عرض المتصفح 600px؛ بينما يُصبح 50% من عرض إطار العرض عندما يكون عرض المتصفح بين 500px و 600px؛ أما عندما يكون عرض المتصفح أقل من 500px، فتمتد الصورة على كامل عرض المتصفح.

توسيع صور المنتجات

يحتاج مستخدمو مواقع التجارة الإلكترونية لمعاينة مشاهد مُقرّبة من المنتجات بدقة عالية بهدف تفحص تفاصيل المنتج، كما تؤكد الدراسات الإحباط الكبير لهؤلاء المستخدمين إذا لم يتمكنوا من ذلك.

يوفر موقع J. Crew مثالًا جيدًا للصور القابلة للنقر والتوسيع حيث يظهر على كل صورة شريط صغير (يختفي عند النقر) يُعلّم المستخدم بإمكانية النقر على الصورة لتكبيرها ومعاينة تفاصيلها.

027sw-make-images-expandable-good.png

تقنيات أخرى مع الصور

الصور المضغوطة

توفر تقنيات الصور المضغوطة compressive image technique صورًا مضغوطة 2x تُناسب جميع الأجهزة مهما كانت إمكاناتها؛ حيث ينخفض حجم الصور كثيرًا (حسب نوع الصورة ودرجة الضغط) مع عدم ملاحظة أي تغيير في جودة الصورة. ويُمكن معاينة مثال compressive.html

يجب توخي الحذر عند استخدام التقانات الضاغطة، حيث تتطلب ذاكرةً أكبر ومعالجةً أكثر لفك الضغط. يُعدّ تغيير حجم الصور الكبيرة لملاءمة الشاشات الصغيرة أمرًا مُكلفًا ويُمكن أن يكون مرهقًا خصوصًا للأجهزة قليلة الإمكانات ذات الذاكرة الصغيرة والمعالجة المحدودة.

استبدال الصور باستخدام JavaScript

يُمكن استخدام سكريبت جافا لفحص قدرات الجهاز ومن ثم إجراء الأنسب؛ حيث يُمكن مثًلا معرفة نسبة بكسلات الجهاز باستخدام window.devicePixelRatio؛ كما يُمكن معرفة طول الشاشة وعرضها؛ إضافًة لإمكانية فحص ميزات الاتصال الشبكي باستخدام navigator.connection أو إجراء طلبٍ مزيف. وعند الحصول على جميع هذه المعلومات، ستُحدّد الصورة المناسبة للتحميل.

يُعدّ تأخير تحميل الصورة حتى انتهاء عمليات الفحص والتحقق أحد سلبيات استخدام JavaScript؛ مما يعني أن تحميل الصور لن يبدأ إلا بعد تشغيل حدث تحميل الصفحة pageload. علاوًة على ذلك، يُمكن أن يُنزِّل المتصفح كلًا من الصور 1x و 2x مما يؤدي لزيادة حجم الصفحة.

الصور السطرية- الصور النقطية والصور المتجهة

تُنشأ الصور وتُخزّن باستخدام طريقتين مختلفتين تمامًا مما ينعكس على طريقة نشر الصور على نحوٍ متجاوب.

الصور النقطية: مثل الصور الفوتوغرافية وغيرها، والتي تُمثّل بشبكةٍ من نقاط الألوان (البكسلات). تُنتِج الكاميرات والماسحات الضوئية الصور النقطية عادًة، كما يُمكن إنتاجها باستخدام عناصر الحاويات canavas في HTML. تُستخدم التنسيقات، مثل PNG و JPEG و WebP لتخزين هذا النوع من الصور.

الصور المتجهة: تُعرّف هذه الصور باستخدام مجموعة من المنحنيات والخطوط والأشكال وألوان التعبئة والتدرجات اللونية، مثل الشعارات logo والرسومات الخطية. يُمكن إنشاء الصور المتجهة باستخدام برامجٍ متخصصة، مثل Adobe Illustrator أو Inkscape، أو استخدام لغة ترميزٍ معينة، مثل لغة الرسومات المتجهة القابلة للتحجيم Scalable Vector Graphics.

الرسومات المتجهة SVG القابلة للتحجيم

تُمكّن الرسومات SVG من تضمين رسوماتٍ متجهةٍ متجاوبة في صفحة ويب. تُعدّ إمكانية المستعرض عرض صورةٍ متجهة بأي حجم من أهم ميزات تنسيقات الملفات المتجهة موازنةً مع تنسيقات الملفات النقطية. كما تصف تنسيقات متجهات SVG هندسة الصورة (أي كيفية بنائها من الخطوط والمنحنيات والألوان وما إلى ذلك). على النقيض من ذلك، لا تحتوي التنسيقات النقطية إلا على معلوماتٍ حول نقاط الألوان، مما يتوجب على المتصفح تخمين كيفية ملء الفراغات (البكسلات الناقصة) عند عملية تحجيم الصورة.

يُظهر الشكل التالي نسختين من نفس الصورة: صورة PNG على اليسار و SVG على اليمين. تبدو الصورة SVG رائعًة بأي حجم، بينما تزداد ضبابية الصورة PNG مع ازدياد عرض الشاشة.

See the Pen Images SVG vs. PNG by Hsoub (@Hsoub) on CodePen.

يُمكن تنسيق الصور السطرية باستخدام تنسيق SVG، أو Data URI لتخفيض عدد طلبات ملف الصورة التي تفعلها الصفحة. بمعاينة المثال التالي، يظهر تعريف كلا الشعارين سطريًا باستخدام تنسيقي SVG و Data URI.

See the Pen Untitled by Hsoub (@Hsoub) on CodePen.

تتمتع رسومات SVG بدعمٍ كبير على الأجهزة المحمولة والحواسيب المكتبية، كما يُمكن أن تُخفّض أدوات التحسين optimization tools كثيرًا من حجم ملف صورة SVG. يبدو كلا الشعارين SVG التاليين متطابقين، إلا أن لأحدهما حجم 3 كيلوبايت، وللآخر حجم 2 كيلوبايت فقط.

See the Pen Images SVG by Hsoub (@Hsoub) on CodePen.

روابط البيانات

توفّر روابط البيانات Data URIs طريقةً لتضمين ملف (ملف صورة مثلًا) سطريًا inline عن طريق ضبط سمة المصدر src للعنصر img باستخدام سلسلة نصية مُرمزة "Base64" ومع التنسيق التالي:

<img src="data:image/svg+xml;base64,[data]">

مثلًا: تكون بداية الشيفرة للشعار HTML5 السابق على النحو التالي (طول الشيفرة الكلي أكثر من 5000 محرف):

<img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiB
BZG9iZSBJbGx1c3RyYXRvciAxNi4wLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW ...">

توفِّر مثل الأداة المتاحة jpillora.com/base64-encoder إمكانية تحويل أي ملفٍ ثنائي، مثل الصور إلى روابط بيانات؛ حيث يكفي سحب ملف الصورة وإفلاته على الأداة. وعلى غرار الرسومات SVG، تُدعم روابط البيانات جيدًا من قِبل متصفحات الأجهزة المحمولة والحواسيب المكتبية.

النمط السطري في CSS

يُمكن وضع روابط البيانات والرسومات SVG بنمطٍ سطري inline في CSS، حيث تَدعم متصفحات الأجهزة المحمولة والحواسيب المكتبية هذا النمط. يُبين الشكل التالي صورتين (تبدوان متطابقتين) موضوعتين مثل صور خلفية في CSS الأولى باستخدام روابط بيانات والثانية باستخدام SVG.

<span class="side-by-side" id="data_uri"></span>
<span class="side-by-side" id="svg"></span>

<style>
.side-by-side {
   display: inline-block;
   margin: 0 20px 0 0;
   width: 45%;
}

span#data_uri {
   background: url(data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%3E%0D%0A%3C%21--%20Generator%3A%20Adobe%20Illustrator%2016.0.0%2C%20SVG%20Export%20Plug-In%20.%20SVG%20Version%3A%206.00%20Build%200%29%20%20--%3E%0D%0A%3C%21DOCTYPE%20svg%20PUBLIC%20%22-%2F%2FW3C%2F%2FDTD%20SVG%201.1%2F%2FEN%22%20%22http%3A%2F%2Fwww.w3.org%2FGraphics%2FSVG%2F1.1%2FDTD%2Fsvg11.dtd%22%3E%0D%0A%3Csvg%20version%3D%221.1%22%20id%3D%22Layer_1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%0D%0A%09%20width%3D%22396.74px%22%20height%3D%22560px%22%20viewBox%3D%22281.63%200%20396.74%20560%22%20enable-background%3D%22new%20281.63%200%20396.74%20560%22%20xml%3Aspace%3D%22preserve%22%0D%0A%09%3E%0D%0A%3Cg%3E%0D%0A%09%3Cg%3E%0D%0A%09%09%3Cg%3E%0D%0A%09%09%09%3Cpolygon%20fill%3D%22%23E44D26%22%20points%3D%22409.737%2C242.502%20414.276%2C293.362%20479.828%2C293.362%20480%2C293.362%20480%2C242.502%20479.828%2C242.502%20%09%09%09%0D%0A%09%09%09%09%22%2F%3E%0D%0A%09%09%09%3Cpath%20fill%3D%22%23E44D26%22%20d%3D%22M281.63%2C110.053l36.106%2C404.968L479.757%2C560l162.47-45.042l36.144-404.905H281.63z%20M611.283%2C489.176%0D%0A%09%09%09%09L480%2C525.572V474.03l-0.229%2C0.063L378.031%2C445.85l-6.958-77.985h22.98h26.879l3.536%2C39.612l55.315%2C14.937l0.046-0.013v-0.004%0D%0A%09%09%09%09L480%2C422.35v-79.32h-0.172H368.853l-12.207-136.871l-1.189-13.325h124.371H480v-49.668h162.17L611.283%2C489.176z%22%2F%3E%0D%0A%09%09%09%3Cpolygon%20fill%3D%22%23F16529%22%20points%3D%22480%2C192.833%20604.247%2C192.833%20603.059%2C206.159%20600.796%2C231.338%20599.8%2C242.502%20599.64%2C242.502%20%0D%0A%09%09%09%09480%2C242.502%20480%2C293.362%20581.896%2C293.362%20595.28%2C293.362%20594.068%2C306.699%20582.396%2C437.458%20581.649%2C445.85%20480%2C474.021%20%0D%0A%09%09%09%09480%2C474.03%20480%2C525.572%20611.283%2C489.176%20642.17%2C143.166%20480%2C143.166%20%09%09%09%22%2F%3E%0D%0A%09%09%09%3Cpolygon%20fill%3D%22%23F16529%22%20points%3D%22540.988%2C343.029%20480%2C343.029%20480%2C422.35%20535.224%2C407.445%20%09%09%09%22%2F%3E%0D%0A%09%09%09%3Cpolygon%20fill%3D%22%23EBEBEB%22%20points%3D%22414.276%2C293.362%20409.737%2C242.502%20479.828%2C242.502%20479.828%2C242.38%20479.828%2C223.682%20%0D%0A%09%09%09%09479.828%2C192.833%20355.457%2C192.833%20356.646%2C206.159%20368.853%2C343.029%20479.828%2C343.029%20479.828%2C293.362%20%09%09%09%22%2F%3E%0D%0A%09%09%09%3Cpolygon%20fill%3D%22%23EBEBEB%22%20points%3D%22479.828%2C474.069%20479.828%2C422.4%20479.782%2C422.413%20424.467%2C407.477%20420.931%2C367.864%20%0D%0A%09%09%09%09394.052%2C367.864%20371.072%2C367.864%20378.031%2C445.85%20479.771%2C474.094%20480%2C474.03%20480%2C474.021%20%09%09%09%22%2F%3E%0D%0A%09%09%09%3Cpolygon%20points%3D%22343.784%2C50.229%20366.874%2C50.229%20366.874%2C75.517%20392.114%2C75.517%20392.114%2C0%20366.873%2C0%20366.873%2C24.938%20%0D%0A%09%09%09%09343.783%2C24.938%20343.783%2C0%20318.544%2C0%20318.544%2C75.517%20343.784%2C75.517%20%09%09%09%22%2F%3E%0D%0A%09%09%09%3Cpolygon%20points%3D%22425.307%2C25.042%20425.307%2C75.517%20450.549%2C75.517%20450.549%2C25.042%20472.779%2C25.042%20472.779%2C0%20403.085%2C0%20%0D%0A%09%09%09%09403.085%2C25.042%20425.306%2C25.042%20%09%09%09%22%2F%3E%0D%0A%09%09%09%3Cpolygon%20points%3D%22508.537%2C38.086%20525.914%2C64.937%20526.349%2C64.937%20543.714%2C38.086%20543.714%2C75.517%20568.851%2C75.517%20568.851%2C0%20%0D%0A%09%09%09%09542.522%2C0%20526.349%2C26.534%20510.159%2C0%20483.84%2C0%20483.84%2C75.517%20508.537%2C75.517%20%09%09%09%22%2F%3E%0D%0A%09%09%09%3Cpolygon%20points%3D%22642.156%2C50.555%20606.66%2C50.555%20606.66%2C0%20581.412%2C0%20581.412%2C75.517%20642.156%2C75.517%20%09%09%09%22%2F%3E%0D%0A%09%09%09%3Cpolygon%20fill%3D%22%23FFFFFF%22%20points%3D%22480%2C474.021%20581.649%2C445.85%20582.396%2C437.458%20594.068%2C306.699%20595.28%2C293.362%20581.896%2C293.362%20%0D%0A%09%09%09%09480%2C293.362%20479.828%2C293.362%20479.828%2C343.029%20480%2C343.029%20540.988%2C343.029%20535.224%2C407.445%20480%2C422.35%20479.828%2C422.396%20%0D%0A%09%09%09%09479.828%2C422.4%20479.828%2C474.069%20%09%09%09%22%2F%3E%0D%0A%09%09%09%3Cpolygon%20fill%3D%22%23FFFFFF%22%20points%3D%22479.828%2C242.38%20479.828%2C242.502%20480%2C242.502%20599.64%2C242.502%20599.8%2C242.502%20600.796%2C231.338%20%0D%0A%09%09%09%09603.059%2C206.159%20604.247%2C192.833%20480%2C192.833%20479.828%2C192.833%20479.828%2C223.682%20%09%09%09%22%2F%3E%0D%0A%09%09%3C%2Fg%3E%0D%0A%09%3C%2Fg%3E%0D%0A%3C%2Fg%3E%0D%0A%3C%2Fsvg%3E%0D%0A) no-repeat;
   background-size: cover;
   height: 484px;
}

span#svg {
   background: url(data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' version='1.1' x='0px' y='0px' width='50%' height='560px' viewBox='281.63 0 396.74 560' enable-background='new 281.63 0 396.74 560' xml:space='preserve'><g><g><g><polygon fill='#E44D26' points='409.7,242.5 414.3,293.4 479.8,293.4 480,293.4 480,242.5 479.8,242.5'/><path fill='#E44D26' d='M281.63 110.053l36.106 404.968L479.757 560l162.47-45.042l36.144-404.905H281.63z M611.283 489.2 L480 525.572V474.03l-0.229 0.063L378.031 445.85l-6.958-77.985h22.98h26.879l3.536 39.612l55.315 14.937l0.046-0.013v-0.004 L480 422.35v-79.32h-0.172H368.853l-12.207-136.871l-1.189-13.325h124.371H480v-49.668h162.17L611.283 489.176z'/><polygon fill='#F16529' points='480,192.8 604.2,192.8 603.1,206.2 600.8,231.3 599.8,242.5 599.6,242.5 480,242.5 480,293.4 581.9,293.4 595.3,293.4 594.1,306.7 582.4,437.5 581.6,445.9 480,474 480,474 480,525.6 611.3,489.2 642.2,143.2 480,143.2'/><polygon fill='#F16529' points='541,343 480,343 480,422.4 535.2,407.4'/><polygon fill='#EBEBEB' points='414.3,293.4 409.7,242.5 479.8,242.5 479.8,242.4 479.8,223.7 479.8,192.8 355.5,192.8 356.6,206.2 368.9,343 479.8,343 479.8,293.4'/><polygon fill='#EBEBEB' points='479.8,474.1 479.8,422.4 479.8,422.4 424.5,407.5 420.9,367.9 394.1,367.9 371.1,367.9 378,445.9 479.8,474.1 480,474 480,474'/><polygon points='343.8,50.2 366.9,50.2 366.9,75.5 392.1,75.5 392.1,0 366.9,0 366.9,24.9 343.8,24.9 343.8,0 318.5,0 318.5,75.5 343.8,75.5'/><polygon points='425.3,25 425.3,75.5 450.5,75.5 450.5,25 472.8,25 472.8,0 403.1,0 403.1,25 425.3,25'/><polygon points='508.5,38.1 525.9,64.9 526.3,64.9 543.7,38.1 543.7,75.5 568.9,75.5 568.9,0 542.5,0 526.3,26.5 510.2,0 483.8,0 483.8,75.5 508.5,75.5'/><polygon points='642.2,50.6 606.7,50.6 606.7,0 581.4,0 581.4,75.5 642.2,75.5'/><polygon fill='#FFFFFF' points='480,474 581.6,445.9 582.4,437.5 594.1,306.7 595.3,293.4 581.9,293.4 480,293.4 479.8,293.4 479.8,343 480,343 541,343 535.2,407.4 480,422.4 479.8,422.4 479.8,422.4 479.8,474.1'/><polygon fill='#FFFFFF' points='479.8,242.4 479.8,242.5 480,242.5 599.6,242.5 599.8,242.5 600.8,231.3 603.1,206.2 604.2,192.8 480,192.8 479.8,192.8 479.8,223.7'/></g></g></g></svg>) no-repeat;
   background-size: cover;
   height: 484px;
}

</style>

الناتج:

 

الإيجابيات والسلبيات

رغم طول الشيفرة للصور، لاسيما عند استخدام روابط البيانات، فإنها تؤدي للتقليل من طلبات HTTP؛ حيث يُمكن تحميل صفحةٍ تحتوي صورًا وأنماط CSS وسكريبت جافا مرةً واحدةً فقط.

من أهم سلبيات هذه الطريقة:

  • يُمكن أن يستغرق إظهار الصور مع روابط بيانات وقتًا أطول بكثير من الصور مع مصدر src خارجي على الهواتف المحمولة.
  • يُمكن أن تزيد روابط البيانات من حجم صفحة HTML كثيرًا.
  • يُمكن أن تزيد من تعقيد الشيفرة وتسلسل خطوات العمل في إنشاء الصفحة.
  • زيادة حجم روابط البيانات بحوالي 30% عن حجم الملف الثنائي، وبالتالي لن تُخفف هذه الطريقة من حجم التنزيل الكلي.
  • غير مدعومة أبدًا في IE6 و IE7، مع توفُّر دعمٍ جزئي في IE8.
  • لا تعود مسألة تخفيض عدد الطلبات ملحة عند استخدام HTTP/2.

نحتاج دومًا لاختبار ما يعمل على نحوٍ أفضل لتحقيق التجاوب الجيد. يُمكن استخدام أدوات المطور لقياس حجم الملف المُنزّل وعدد الطلبات ووقت الاستجابة الكلي. قد تكون روابط البيانات اختيارًا موفقًا للصور النقطية لصفحةٍ رئيسة تحتوي صورةً واحدةً أو اثنتين غير مستخدمتين في أماكن أخرى في الموقع؛ أما عند الحاجة لصورٍ سطرية متجهة، تكون رسومات SVG هي الخيار الأفضل.

الصور في أنماط CSS

تُعدّ خاصية الخلفية background في CSS أداةً مهمةً لإضافة صورٍ معقدة إلى العناصر؛ حيث أنها تُسهّل إضافة صورٍ متعددة وتكرارها وغير ذلك من الأمور؛ كما تزداد قوة هذه الخاصية عند دمجها مع استعلامات الوسائط، مما يتيح تحميل الصوره شرطيًا وفقًا لدقة الشاشة وحجم إطار العرض وغير ذلك من مواصفات الجهاز.

  • يجب تغيير خاصية صورة الخلفية background-image في CSS لأجهزة العرض عالية الدقة، وذلك باستخدام استعلامات الوسائط مع الدقة الأدنى min-resolution و نسبة البكسلات الأدنى webkit-min-device-pixel-ratio-.
  • يجب استخدام مجموعة المصادر srcset لتوفير صورٍ عالية الدقة إضافًة إلى الصورة 1x في الشيفرة.
  • يجب التدقيق في التأثير على الأداء عند استخدام تقنيات استبدال الصور في سكريبت جافا، وعند توفير صورٍ مضغوطةٍ عالية الدقة لأجهزةٍ ذات دقة منخفضة.

استخدام استعلامات الوسائط للتحميل الشرطي للصور أو للإدارة الفنية

يُمكن استخدام استعلامات الوسائط لتغيير تخطيط الصفحة، كما يُمكن استخدامها أيضًا لتحميل الصور شرطيًا، أو لتوفير الإدارة الفنية وفقًا لعرض إطار العرض.

يُظهر المثال التالي طلب تنزيل الملف small.png فقط ووضعه في محتوى الحاوية div على الشاشات الصغيرة؛ أما على الشاشات الأكبر، فيكون لخلفية جسم الصفحة صورة (background-image: url(body.png، وللحاوية صورةٌ أخرى (background-image: url(large.png.

.example {
  height: 400px;
  background-image: url(small.png);
  background-repeat: no-repeat;
  background-size: contain;
  background-position-x: center;
}

@media (min-width: 500px) {
  body {
    background-image: url(body.png);
  }
  .example {
    background-image: url(large.png);
  }
}

يُمكن معاينة المثال السابق.

استخدام image-set لتوفير صور عالية الدقة

تُحسّن الدالة ()image-set من أداء خاصية الخلفية background عن طريق توفير مجموعةٍ متعدّدة من الصور وفقًا لمواصفات الجهاز المختلفة؛ مما يسمح للمتصفح باختيار أفضل صورة اعتمادًا على خصائص الجهاز، حيث يمكن مثلًا استخدام صورة 2x على جهاز 2x وصورة 1x على جهاز 2x عند محدودية حيز النطاق التراسلي للشبكة.

background-image: image-set(
  url(icon1x.jpg) 1x,
  url(icon2x.jpg) 2x
);

يقيس المتصفح الصورة المناسبة إضافًة إلى تنزيلها، حيث يفترض المتصفح أن حجم الصور 2x أكبر مرتين من الصور 1x، وبالتالي يُخفَّض حجم الصورة 2x بنسبة 2، بحيث تظهر الصورة بنفس الحجم على الصفحة.

يجب توفير صورةٍ احتياطية لاستخدامها في حالة عدم توفر الدعم للدالة ()image-set، حيث ما زال دعم هذه الدالة جديدًا ومتوفرًا على كلٍ من Chrome و Safari فقط مع بادئة محرك المتصفح webkit-. ألقِ نظرةً على ما يلي على سبيل المثال:

.sample {
  width: 128px;
  height: 128px;
  background-image: url(icon1x.png);
  background-image: -webkit-image-set(  
    url(icon1x.png) 1x,  
    url(icon2x.png) 2x  
  );  
  background-image: image-set(  
    url(icon1x.png) 1x,  
    url(icon2x.png) 2x  
  );
}

يمكن معاينة المثال السابق.

تطلب الشيفرة السابقة تحميل الصورة المناسبة على المتصفحات التي تدعم الدالة ()image-set؛ وإلا فتُستخدم الصورة 1x. وبهذا ستحصل المتصفحات التي لا تدعم الدالة على الصور 1x.

استخدام استعلامات الوسائط لتوفير صور عالية الدقة أو الإدارة الفنية

يُمكن لاستعلامات الوسائط إنشاء قواعدٍ بناءً على نسبة بكسلات الجهاز device pixel ratio، مما يُمكّن من توفير صورٍ مختلفة لشاشات 1x وشاشات 2x.

@media (min-resolution: 2dppx),
(-webkit-min-device-pixel-ratio: 2)
{
  /* الأنماط عالية الكثافة والمصادر هنا */
}

تدعم المتصفحات Chrome و Firefox و Opera معيار الدقة الأدنى (min-resolution: 2dppx)؛ بينما يتطلب كلٌ من متصفحي Safari و Android كتابة القيمة بدون الوحدة dppx.

يجب الانتباه إلى حدوث تحميل هذه الأنماط فقط عند مطابقة الجهاز لاستعلام الوسائط، وبالتالي يجب تحديد هذه الأنماط من أجل الحالة الأساسية، وهذا يضمن عرض شيءٍ ما إذا كان المتصفح لا يدعم استعلامات الوسائط الخاصة بالدقة.

.sample {
  width: 128px;
  height: 128px;
  background-image: url(icon1x.png);
}

@media (min-resolution: 2dppx), /* Standard syntax */ 
(-webkit-min-device-pixel-ratio: 2)  /* Safari & Android Browser */ 
{
  .sample {
    background-size: contain;
    background-image: url(icon2x.png);
  }
}

يمكن معاينة المثال السابق. ويُمكن أيضًا استخدام خاصية العرض الأدنى min-width لإظهار صورٍ بديلة اعتمادًا على حجم إطار العرض؛ حيث تتمتع هذه التقنية بميزة عدم تنزيل الصورة في حال عدم تحقق استعلام الوسائط. على سبيل المثال: تُنزّل الصورة bg.png وتوضع في الجسم body، إذا كان عرض المتصفح أكبر أو يساوي 500px فقط:

@media (min-width: 500px) {
  body {
    background-image: url(bg.png);
  }
}

استخدام رسومات SVG للأيقونات

تُستخدم الرسومات المتجهة SVG لإضافة الأيقونات للصفحة عندما يكون ذلك مُمكنًا، أو المحارف unicode في بعض الحالات.

استبدال الأيقونات البسيطة بـالمحارف unicode

يدعم الكثير من الخطوط المحارف الرسومية unicode، والتي يُمكن استخدامها عوضًا عن الصور لا سيما وأنها على خلاف الصور تظهر جيدًا مهما كان حجمها.

تتضمن المحارف الرسومية إضافًة إلى المحارف العادية، رموز الأسهم (←) والمعاملات الرياضية (√) والأشكال الهندسية (★) وصور التحكم (▶) والعلامات الموسيقية (♬) والأحرف اليونانية (Ω) وحتى قطع الشطرنج ( ♞).

تُضمّن هذه المحارف بنفس طريقة تدوين الكائنات على النحو التالي: XXXX&#؛ حيث يُمثّل XXXX رقم محرف unicode. ألقِ نظرةً على المثال التالي:

You're a super &#9733;

والذي يُظهِر:

You're a super ★

استبدال الأيقونات المعقدة برسومات SVG

يُمكن استخدام رسومات SVG للأيقونات الأكثر تعقيدًا؛ نظرًا لأن هذه الرسومات خفيفة وسهلة الاستخدام عمومًا، كما يُمكن تصميمها باستخدام أنماط CSS. وتتمتع بالمزايا التالية موزانةً مع الصور النقطية:

  • يُمكن تحجيم الرسومات المتجهة بلا حدود.
  • يُمكن استخدام تأثيرات CSS مثل اللون والتظليل والشفافية والتحريك مباشرةً.
  • يُمكن تضمين هذه الرسومات سطريًا inline.
  • توفر دلالة واضحة.
  • توفر إمكانية وصول أفضل مع استخدام السمات المناسبة.
With SVG icons, you can either add icons using inline SVG, like 
this checkmark:
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
       xmlns:xlink="http://www.w3.org/1999/xlink" 
       width="32" height="32" viewBox="0 0 32 32">
    <path d="M27 4l-15 15-7-7-5 5 12 12 20-20z" fill="#000000"></path>
  </svg>
or by using an image tag, like this credit card icon:
<img src="credit.svg">.

يُمكن معاينة المثال السابق.

إرشادات استخدام الخطوط للأيقونات

يشيع استخدام الخطوط للأيقونات لسهولة استخدامها، إلا أن لها بعض العيوب موزانةً مع أيقونات رسومات SVG:

  • تُنشَأ باستخدام رسوميات مُتجهة، مما يُمكّن من تحجيمها بلا حدود؛ ولكن يُمكن أن تكون غير مصقولة، مما يُعطي أحيانًا أيقونات غير دقيقة كما هو متوقع منها أن تكون.
  • لا توفِّر دعمًا كاملًا لأنماط CSS.
  • يُمكن أن يكون تحقيق التوضع المثالي للبيكسل أمرًا صعبًا اعتمادًا على ارتفاع الخط وتباعد المحارف وغير ذلك.
  • لا توفر الدلالة semantic، مما يجعل من الصعب استخدامها مع قارئات الشاشة أو التقنيات المساعدة الأخرى.
  • يُمكن أن ينتج عن استخدام مجموعةٍ فرعيةٍ صغيرةٍ فقط منها حجم ملفٍ كبير ما لم يُحدّد نطاقها صحيحًا.

يُبين الشكل التالي مثالًا لصفحة تستخدم الخطوط FontAwesome:

031icon-fonts.png

With Font Awesome, you can either add icons by using a unicode
entity, like this HTML5 logo (<span class="awesome"></span>)
or by adding special classes to an <i> element like the CSS3
logo (<i class="fa fa-css3"></i>).

يُمكن معاينة المثال السابق.

تتوفر المئات من خطوط الأيقونات المجانية والمدفوعة بما في ذلك Font Awesome و Pictos و Glyphicons.

يجب التأكد من التوازن بين طلبات HTTP الإضافية وحجم الملف حين الحاجة للأيقونات؛ حيث يُفضل استخدام صورةٍ، أو مجموعة صور مُضمّنة في صورةٍ واحدة image sprite في حال الحاجة لعددٍ قليل من الأيقونات.

تحسين الصور لتحقيق الأداء الأمثل

تُشكّل الصور غالبًا العدد الأكبر من البايتات المُنزّلة كما أنها تشغل قسمًا كبيرًا من المساحة المرئية على الصفحة. وبالنتيجة، يؤدي تحسين الصور إلى تخفيض عدد البايتات اللازم وبالتالي تحسين أداء الموقع؛ فكلما انخفض عدد البايتات الواجب تنزيلها، انخفض التنافس على حجز حيّز النطاق التراسلي، وزادت سرعة التحميل والعرض.

  • يجب عدم اختيار تنسيق الصورة عشوائيًا، بل يجب فهم التنسيقات المختلفة المتاحة واستخدام التنسيق الأنسب.
  • يجب تضمين أدوات تحسين الصور وضغطها في سير العمل على الموقع لتخفيض حجم الملفات.
  • يُمكن تقليل عدد طلبات http عن طريق وضع الصور المُستخدمة على نحوٍ متكرر في حاوية صور image sprites.
  • يُمكن تحسين زمن تحميل الصفحة الأولى والتخفيف من وزنها بتحميل الصور فقط عند الوصول إليها.

اختيار التنسيق الصحيح

يجب الانتباه لنوعين من الصور، وهما: الصور المتجهة و الصور النقطية. ونحتاج اختيار تنسيق الضغط المناسب بالنسبة للصور النقطية، مثل GIF و PNG و JPG.

الصور النقطية: مثل الصور الفوتوغرافية وغيرها، والتي تُمثّل بشبكةٍ من نقاط الألوان (البكسلات). تُنتج الكاميرات والماسحات الضوئية الصور النقطية عادًة، كما يُمكن إنتاجها باستخدام عناصر الحاويات canavas في HTML؛ وكلما زاد حجم الصورة، زاد حجم الملف أيضًا. عندما يتغير حجم الصورة إلى حجمٍ أكبر من حجمها الأصلي، تُصبح الصور النقطية ضبابية، لأن المتصفح يحتاج إلى تخمين كيفية ملء البكسلات الناقصة.

الصور المُتجهة: تُعرّف هذه الصور باستخدام مجموعةٍ من المنحنيات والخطوط والأشكال وألوان التعبئة والتدرجات اللونية، مثل الشعارات logo والرسومات الخطية، ويُمكن إنشاؤها باستخدام برامجٍ متخصصة، مثل Adobe Illustrator أو Inkscape؛ وتُحفَظ بتنسيقٍ متجه، مثل SVG. نظرًا لأن الصور المتجهة مبنية على عناصر أولية بسيطة، يُمكن تحجيمها دون أي خسارةٍ في الجودة، أو تغييرٍ في حجم الملف.

من المهم الانتباه لمنشأ الصورة (نقطية أو متجهة) والمحتوى (الألوان، التحريك، النص،..) عند اختيار التنسيق المناسب. لا يوجد تنسيقٌ واحدٌ يُناسب جميع أنواع الصور؛ إذ لكل تنسيق نقاط قوة وضعف.

من الإرشادات الأساسية لاختيار التنسيق المناسب:

  • استخدام JPG للصور الفوتوغرافية.
  • استخدام الرسوميات SVG للرسومات المتجهة والرسومات ذات الألوان الصلبة مثل الأيقونات والخطوط الفنية؛ وفي حال كان الرسم المتجه غير متاح، يُمكن تجربة التنسيقات WebP، أوPNG.
  • استخدام PNG عوضًا عن GIF، لأنها تتيح المزيد من الألوان وتوفر نسب ضغط أفضل.
  • استخدام عنصر الفيديو <video> للحصول على زمن تحريك أطول، والذي يوفر أيضًا نوعية صور أفضل، إضافًة لتحكُّم المستخدم في تشغيل العرض.

تخفيض حجم الملف

يُمكن تخفيض حجم ملف الصورة إلى حدٍ كبير عن طريق "المعالجة اللاحقة" للصور بعد حفظها. يتوفر العديد من الأدوات المتاحة لضغط الصور مع ضياع بعض البيانات أو بدون ضياع؛ ومنها متاحٌ على الويب؛ ومنها على هيئة برامج ذات واجهات رسومية أو سطور أوامر. من الأفضل تضمين عمليات تحسين الصور على نحوٍ مؤتمت ضمن سير العمل في بناء الموقع.

تتوفر العديد من الأدوات ذات الأداء العالي والتي تضغط الصور دون ضياعٍ لبيانات الملفات JPG و PNG، وبدون أي تأثير على جودة الصورة. يُمكن استخدام الأدوات jpegtran أو jpegoptim (متوفر على لينكس Linux فقط؛ ويجب تشغيله مع خيار إزالة الكل strip-all--) للصور JPG؛ بينما يُمكن استخدام OptiPNG أو PNGOUT للصور PNG.

استخدام تتابع الصور

تسمح تقنية التتابع CSS spriting بدمج مجموعةٍ من الصور في "صورةٍ واحدة sprite sheet". يُمكن بعد ذلك انتقاء صورةٍ منها للعرض عن طريق تحديد الصورة الخلفية لعنصر sprite sheet مع تحديد الإزاحة المناسبة لعرض الجزء المطلوب.

032sprite-sheet.png

.sprite-sheet {
  background-image: url(sprite-sheet.png);
  width: 40px;
  height: 25px;
}

.google-logo {
  width: 125px;
  height: 45px;
  background-position: -190px -170px;
}

.gmail {
  background-position: -150px -210px; 
}

.maps {
  height: 40px;
  background-position: -120px -165px;
}

يُمكن معاينة المثال السابق.

يُخفّض التتابع من عدد التنزيلات المطلوبة للحصول على صور متعدّدة مع السماح بالتخزين المؤقت لها.

استخدام التحميل الكسول

يُمكن أن يؤدي استخدام التحميل الكسول إلى تسريعٍ كبير لتحميل الصفحات الطويلة، التي تتضمن العديد من الصور الموجودة أسفل الجزء المرئي من الصفحة، عن طريق تحميلها؛ إما عند الحاجة لعرضها؛ أو عند انتهاء تحميل المحتوى الأساسي وعرضه. يُمكن أن يؤدي استخدام التحميل الكسول إلى إنشاء تجارب تمرير لا نهائية إضافًة لتحسين الأداء.

يجب توخي الحذر عند إنشاء صفحات تمرير لا نهائية، لأن المحتوى يُحمّل عندما يُصبح مرئيًا فقط مما يجعل محركات البحث غير قادرةٍ على رؤية هذا المحتوى إطلاقًا. علاوًة على ذلك، فإن المستخدمين الذين يبحثون عن المعلومات التي يتوقعون رؤيتها في التذييل لا يرونه (أي التذييل) أبدًا نظرًا تحميل المحتوى الجديد دائمًا.

تجنب الصور نهائيا

يُمكن في بعض الحالات أن تكون الصورة الأفضل ليست صورةً على الإطلاق. يجب استخدام الإمكانات الأصلية للمتصفح لتوفير الوظائف نفسها أو وظائف مشابهة. تنشئ المستعرضات اليوم عناصرًا مرئية كانت تتطلب صورًا سابقًا؛ مما يعني أن المتصفحات لم تعد بحاجةٍ إلى تنزيل ملفات صور منفصلة، وبالتالي تتجنب حجم الصور غير الملائم. يُمكن استخدام خطوط يونيكود unicode أو خطوط الأيقونات الخاصة لعرض الأيقونات.

وضع النص في الشيفرة عوضا عن تضمينه في الصور

يجب أن يكون النص نصًا وليس مُضمّنًا في الصور كلما كان ذلك مُمكنًا؛ حيث يؤدي استخدام الصور للعناوين الرئيسية أو وضع معلومات الاتصال، مثل أرقام الهواتف أو العناوين في الصور إلى منع المستخدمين من نسخ المعلومات ولصقها؛ كما أن ذلك يجعل المعلومات غير متاحة لبرامج قراءة الشاشة وغير متجاوبة. عوضًا عن ذلك، يُمكن وضع النص في الشيفرة واستخدام خطوط الويب المتاحة لتحقيق النمط المطلوب.

استخدام أنماط CSS لاستبدال الصور

يُمكن للمتصفحات الحديثة استخدام خصائص CSS لإنشاء أنماط كانت تتطلب صورًا سابقًا. يُمكن مثلًا إنشاء التدرجات اللونية المعقدة باستخدام خاصية الخلفية background؛ ويُمكن إنشاء الظلال باستخدام صندوق الظلال box-shadow؛ كما يُمكن إضافة الزوايا المستديرة باستخدام خاصية نصف قطر الحدود border-radius.

033font.png

<style>
  div#noImage {
    color: white;
    border-radius: 5px;
    box-shadow: 5px 5px 4px 0 rgba(9,130,154,0.2);
    background: linear-gradient(rgba(9, 130, 154, 1), rgba(9, 130, 154, 0.5));
  }
</style>

يجب الانتباه إلى أن استخدام هذه التقنيات يتطلب عدة دورات للإظهار؛ مما يُعدّ أمرًا مرهقًا على الهواتف المحمولة. سيُفقِد الإفراط في الاستخدام أي فائدةٍ مكتسبة، إضافًة إلى إعاقة الأداء.

ترجمة -وبتصرف- للمقالة Images للمؤلف: Pete LePage.

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...