صور عالية لكل بوصة (DPI) لكثافة وحدات البكسل المتغيّرة

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

  • مجموعة كبيرة من الأجهزة ذات أشكال مختلفة
  • معدّل نقل البيانات للشبكة وعمر البطارية محدودان

في ما يتعلّق بالصور، يهدف مطوّرو تطبيقات الويب إلى عرض الصور الأعلى جودة بأكبر قدر ممكن من الكفاءة. ستتناول هذه المقالة بعض الأساليب المفيدة لإجراء ذلك اليوم وفي القريب المستقبل.

تجنَّب استخدام الصور إن أمكن.

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

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

الخلفية

لمحة قصيرة جدًا عن كثافة العرض

في الأيام الأولى، كانت كثافة وحدات البكسل في شاشات الكمبيوتر تبلغ 72 أو 96 نقطة لكل بوصة (نقطة لكل بوصة).

تحسّنت كثافة البكسل في الشاشات تدريجيًا، ويعود ذلك إلى حد كبير إلى حالة استخدام الأجهزة الجوّالة، حيث يضع المستخدمون هواتفهم عمومًا أقرب إلى وجوههم، ما يجعل البكسل أكثر ظهورًا. بحلول عام 2008، أصبحت الهواتف التي تبلغ دقتها 150 نقطة لكل بوصة هي القاعدة الجديدة. استمرّ اتجاه زيادة كثافة الشاشة، وأصبحت هواتف اليوم الجديدة مزوّدة بشاشات بدقة 300 نقطة لكل بوصة (تُطلق عليها Apple اسم "Retina").

إنّ الشاشة التي لا تظهر فيها وحدات البكسل مطلقًا هي الشاشة المثالية. بالنسبة إلى شكل الهاتف، قد يكون الجيل الحالي من شاشة Retina/HiDPI قريبًا من هذا المستوى المثالي. ولكن من المرجّح أن تواصل فئات الأجهزة والأجهزة القابلة للارتداء الجديدة، مثل Project Glass، زيادة كثافة البكسل.

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

Baboon 1x
Baboon 2x
ببغاوات بكثافات بكسل مختلفة

وحدات البكسل على الويب

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

عالجت مواصفات HTML هذه المشكلة مؤخرًا من خلال تحديد بكسل مرجعي يستخدمه المصنّعون لتحديد حجم بكسل CSS.

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

احتساب نسبة وحدات البكسل على الجهاز

لنفترض أنّ هاتفًا ذكيًا يحتوي على شاشة بحجم بكسل فعلي يبلغ 180 بكسل لكل بوصة (ppi). تستغرق عملية احتساب نسبة وحدات البكسل على الجهاز ثلاث مراحل:

  1. قارِن المسافة الفعلية التي يتم فيها تثبيت الجهاز مع المسافة لوحدة البكسل المرجعية.

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

  2. اضرب نسبة المسافة في الكثافة العادية (96ppi) للحصول على كثافة البكسل المثالية للمسافة المحدّدة.

    ‫idealPixelDensity = (28/18) * 96 = 150 بكسل لكل بوصة (تقريبًا)

  3. احسب نسبة كثافة وحدات البكسل الفعلية إلى كثافة وحدات البكسل المثالية للحصول على نسبة وحدات البكسل على الجهاز.

    devicePixelRatio = 180/150 = 1.2

كيفية احتساب devicePixelRatio
مخطّط بياني يعرض بكسلًا زاويًا مرجعيًا واحدًا للمساعدة في توضيح كيفية احتساب devicePixelRatio

وبالتالي، عندما يحتاج المتصفّح إلى معرفة كيفية تغيير حجم صورة لتلائم الشاشة وفقًا لدرجة الدقة المثالية أو العادية، يشير المتصفّح إلى نسبة وحدات البكسل على الجهاز التي تبلغ 1.2، ما يعني أنّه لكل بكسل مثالي، يحتوي هذا الجهاز على 1.2 بكسل فعلي. في ما يلي الصيغة للتحويل بين وحدات البكسل المثالية (على النحو المحدّد في مواصفات الويب) ووحدات البكسل الفعلية (النقاط على شاشة الجهاز):

physicalPixels = window.devicePixelRatio * idealPixels

في السابق، كان مورّدو الأجهزة يميلون إلى تقريب devicePixelRatios (DPR). تُظهر أجهزة iPhone وiPad من Apple نسبة عرض إلى ارتفاع تبلغ 1، بينما تُظهر الأجهزة المزوّدة بشاشة Retina نسبة عرض إلى ارتفاع تبلغ 2. تنص مواصفات CSS على ما يلي:

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

من بين الأسباب التي تجعل النسب المستديرة أفضل هو أنّها قد تؤدي إلى استخدام عدد أقل من العناصر المرئية على مستوى البكسل الفرعي.

ومع ذلك، فإنّ الواقع في ما يتعلّق بالأجهزة الأفقية أكثر تنوعًا، وغالباً ما تكون هواتف Android ذات نسبة عرض إلى ارتفاع تبلغ 1.5. يمتلك جهاز Nexus 7 اللوحي معدل نقل بيانات يبلغ ~1.33، وقد تمّ الوصول إليه من خلال عملية حسابية مشابهة للتي سبق ذكرها. من المتوقّع أن نطرح هذه الميزة على المزيد من الأجهزة في المستقبل. وبناءً على ذلك، يجب ألّا تفترض أبدًا أنّ عملائك سيحصلون على معدّلات أرباح مثبّتة.

نظرة عامة على تقنيات الصور بدقة عالية الكثافة

هناك العديد من الأساليب لحلّ مشكلة عرض أفضل الصور بأسرع وقت ممكن، وتندرج هذه الأساليب بشكل عام ضمن فئتين:

  1. تحسين الصور الفردية
  2. تحسين الاختيار بين صور متعددة

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

  • صورة HiDPI مضغوطة بشدة
  • تنسيق الصورة رائع جدًا
  • تنسيق الصورة المتقدّمة

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

  • JavaScript
  • التسليم من جهة الخادم
  • طلبات الاستعلام عن الوسائط في CSS
  • ميزات المتصفّح المضمّنة (image-set()، <img srcset>)

صورة HiDPI مضغوطة بشدة

تشكّل الصور حاليًا نسبة% 60 من معدل نقل البيانات المستخدَم في تنزيل موقع إلكتروني عادي. ومن خلال عرض صور بدقة عالية لجميع العملاء، سن يزيد هذا العدد. ما هو حجم الزيادة المتوقعة؟

أجريتُ بعض الاختبارات التي أدّت إلى إنشاء أجزاء من الصور بحجمَين 1x و2x بجودة JPEG ‏90 و50 و20. في ما يلي النص البرمجي لوحدة التحكّم في النظام الذي استخدمته (باستخدام ImageMagick) لإنشاء هذه الصور:

مثال 1 على مربّعات الشاشة مثال 2 على مربّعات مثال على مربّعات البيانات 3
عيّنات من الصور بدرجات مختلفة من الضغط وكثافة بكسل

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

بالطبع، إنّ عرض صور ذات جودة منخفضة ودرجة ضغط عالية بمقدار مرتين على الأجهزة التي تعمل بمقدار مرتين هو أسوأ من عرض صور ذات جودة أعلى، ويؤدي الأسلوب المذكور أعلاه إلى فرض عقوبات على جودة الصورة. إذا قارنت بين الجودة: 90 صورة والجودة: 20 صورة، ستلاحظ انخفاضًا في الوضوح و زيادة في الحبيبات. قد لا تكون هذه العناصر مقبولة في الحالات التي تتعلّق بصور عالية الجودة (مثل تطبيق لعرض الصور)، أو لمطوّري التطبيقات الذين لا يريدون تقديم أي تنازلات.

تم إجراء المقارنة أعلاه بالكامل باستخدام ملفات JPEG مضغوطة. تجدر الإشارة إلى أنّ هناك العديد من المفاضلات بين تنسيقات الصور التي يتم استخدامها على نطاق واسع (JPEG وPNG وGIF)، ما ينقلنا إلى…

تنسيق الصورة رائع جدًا

WebP هو تنسيق صور جذاب يضغط الصور بشكل جيد جدًا مع الحفاظ على دقتها العالية. بالطبع، لم يتم تطبيقه في كل مكان بعد.

يمكنك التحقّق من توفّر WebP من خلال JavaScript. يمكنك تحميل صورة بحجم 1 بكسل من خلال data-uri، والانتظار إلى أن يتم تشغيل أحداث loaded أو error، ثم التحقّق من صحة الحجم. يتضمّن Modernizr نصًا برمجيًا لرصد الميزات مماثلاً، وهو متاح من خلال Modernizr.webp.

ومع ذلك، هناك طريقة أفضل لإجراء ذلك وهي في CSS مباشرةً باستخدام دالة image()‎. إذا كانت لديك صورة WebP وصورة JPEG احتياطية، يمكنك كتابة ما يلي:

#pic {
  background: image("foo.webp", "foo.jpg");
}

هناك بعض المشاكل في هذا النهج. أولاً، لم يتم تنفيذ image() على نطاق واسع على الإطلاق. ثانيًا، على الرغم من أنّ ضغط WebP يتفوق على JPEG، إلا أنّه لا يزال يُحسِّن الأداء بشكل تدريجي نسبيًا، ويقل حجمه بنسبة% 30 تقريبًا استنادًا إلى معرض WebP هذا. وبالتالي، فإنّ WebP وحده ليس كافيًا لحلّ مشكلة كثافة البكسل العالية.

تنسيقات الصور المتدرّجة

توفّر تنسيقات الصور التدريجية، مثل JPEG 2000 وProgressive JPEG وProgressive PNG وGIF، ميزة (مثيرة للجدل إلى حدّ ما) وهي ظهور الصورة في مكانها قبل تحميلها بالكامل. وقد تؤدي إلى زيادة بعض الأحجام، على الرغم من توفّر أدلة متعارضة حول ذلك. ادّعى جينيفر أتووود أنّ الوضع التدريجي "يضيف حوالي% 20 إلى حجم صور PNG، ويضيف حوالي% 10 إلى حجم صور JPEG وGIF". ومع ذلك، ادّعى ستويان ستيفانوف أنّ الوضع التدريجي أكثر فعالية (في معظم الحالات) بالنسبة إلى الملفات الكبيرة.

تبدو الصور التدريجية واعدة جدًا للوهلة الأولى في سياق عرض الصور بأعلى جودة ممكنة في أسرع وقت ممكن. والفكرة هي أنّه يمكن للمتصفح التوقف عن تنزيل الصورة وفك ترميزها بعد أن يعلم أنّ البيانات الإضافية لن تزيد من جودة الصورة (أي أنّ كل تحسينات الدقّة تكون على مستوى البكسل الفرعي).

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

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

أخيرًا، من القيود الواضحة لهذا النهج أنّه لا يمكنك اختيار الصورة التي تريد تحميلها، بل يمكنك فقط تحميل صور مختلفة بدرجة دقة مختلفة للصورة نفسها. نتيجةً لذلك، لا يعالج ذلك حالة استخدام "اتجاه الفن".

استخدام JavaScript لتحديد الصورة المطلوب تحميلها

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

هناك مليون مكتبة JavaScript تقريبًا تؤدي مهمة مماثلة لما سبق، ولكن للأسف، لا تُعدّ أيّ منها ملفًّا بارزًا بشكلٍ خاص.

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

تحديد الصورة المطلوب تحميلها على الخادم

يمكنك تأجيل القرار إلى جانب الخادم من خلال كتابة معالجات طلبات مخصّصة لكل صورة تقدّمها. سيتحقّق معالِج مثل هذا من توفّر شاشة Retina استنادًا إلى User-Agent (المعلومة الوحيدة التي يتم نقلها إلى الخادم). بعد ذلك، استنادًا إلى ما إذا كان المنطق من جهة الخادم يريد عرض مواد عرض بدرجة عالية من الدقة، يمكنك تحميل مادة العرض المناسبة (التي تم تسميتها وفقًا لبعض الاصطلاحات المعروفة).

لا يقدّم User-Agent بالضرورة معلومات كافية لتحديد ما إذا كان يجب أن يتلقّى الجهاز صورًا عالية أو منخفضة الجودة. من الواضح أيضًا أنّ أيّ محتوى مرتبط بعلامة User-Agent هو عملية اختراق ويجب تجنّبه إن أمكن.

استخدام طلبات البحث عن الوسائط في CSS

بما أنّ طلبات الاستعلام عن الوسائط في CSS تصفية، فهي تتيح لك التعبير عن نيتك، وتسمح للمتصفّح باتخاذ الإجراء المناسب نيابةً عنك. بالإضافة إلى الاستخدام الأكثر شيوعًا لطلبات البحث عن الوسائط، وهو مطابقة حجم الجهاز، يمكنك مطابقة devicePixelRatio أيضًا. طلب البحث المرتبط بالوسائط هو device-pixel-ratio، ويتضمّن الصيغتين الأدنى والأعلى المرتبطة به، كما هو متوقّع. إذا كنت تريد تحميل صور عالية الكثافة (DPI) وتجاوزت نسبة بكسل الجهاز الحدّ المسموح به، إليك الإجراءات التي يمكنك اتّخاذها:

#my-image { background: (low.png); }

@media only screen and (min-device-pixel-ratio: 1.5) {
  #my-image { background: (high.png); }
}

يصبح الأمر أكثر تعقيدًا عند استخدام جميع بادئات المورّدين معًا، خاصةً بسبب الاختلافات الكبيرة في مواضع بادئتَي "min" و "max":

@media only screen and (min--moz-device-pixel-ratio: 1.5),
    (-o-min-device-pixel-ratio: 3/2),
    (-webkit-min-device-pixel-ratio: 1.5),
    (min-device-pixel-ratio: 1.5) {

  #my-image {
    background:url(high.png);
  }
}

باستخدام هذا الأسلوب، يمكنك استعادة مزايا تحليل "النظر إلى المستقبل" التي فقدتها باستخدام حلّ JavaScript. يمكنك أيضًا الاستفادة من مرونة اختيار نقاط بدء التحميل المتوافق مع الأجهزة الجوّالة (على سبيل المثال، يمكنك الحصول على صور بكثافة بكسل منخفضة ومتوسطة وعالية)، وهي ميزة لم تكن متاحة باستخدام النهج من جهة الخادم.

لا يزال هذا الإجراء غير عملي إلى حدٍ ما، ويؤدي إلى استخدام ملف CSS ذو مظهر غريب (أو يتطلّب معالجة مسبقة). يقتصر هذا النهج أيضًا على سمات CSS، لذا لا تتوفّر طريقة لضبط <img src>، ويجب أن تكون صورك جميعها عناصر لها خلفية. أخيرًا، من خلال الاعتماد بشكل صارم على نسبة كثافة وحدات البكسل في الجهاز، قد تواجه حالات ينتهي فيها هاتفك الذكي المزوّد بدرجة دقة عالية بتحميل مادة عرض صورة كبيرة بمقدار ضعف أثناء استخدام اتصال EDGE. هذه ليست أفضل تجربة للمستخدم.

استخدام ميزات المتصفّح الجديدة

لقد دارت الكثير من المناقشات مؤخرًا حول توافق منصات الويب مع مشكلة الصور ذات الكثافة العالية للنقاط. دخلت Apple مؤخرًا إلى هذا المجال، وأضافت دالة CSS image-set() إلى WebKit. نتيجةً لذلك، يتيح كل من Safari وChrome استخدام هذه الميزة. بما أنّها دالة CSS، لا تعالج image-set() المشكلة في علامات <img>. أدخِل @srcset، الذي يعالج هذه المشكلة ولكنّه (في وقت pennedكتابة هذه المقالة) لا يتضمّن أي عمليات تنفيذ مرجعية (حتى الآن). يتناول القسم التالي بالتفصيل image-set وsrcset.

ميزات المتصفّح لتوفير كثافة بكسل عالية

في النهاية، يعتمد القرار الذي تتّخذه بشأن المنهج الذي ستتبعه على متطلباتك المحدّدة. ومع ذلك، تجدر الإشارة إلى أنّ جميع ال approaches المذكورة أعلاه لها عيوب. في المستقبل، بعد أن تصبح علامة image-set وsrcset متوافقة على نطاق واسع، ستكونان الحلول المناسبة لهذه المشكلة. في الوقت الحالي، لنطّلِع على بعض أفضل الممارسات التي يمكن أن تقربنا من هذا المخطّط المثالي قدر الإمكان.

أولاً، ما هو الفرق بين هذين الإجراءَين؟ حسنًا، image-set() هي دالّة CSS مناسبة للاستخدام كقيمة لسمة CSS للخلفية. srcset هي سمة خاصة بعناصر <img>، لها بنية مشابهة. تتيح لك كلتا العلامتَين تحديد بيانات الصور، ولكنّ السمة srcset تتيح لك أيضًا ضبط الصورة التي سيتم تحميلها استنادًا إلى حجم مساحات العرض.

أفضل الممارسات المتعلّقة بمجموعة الصور

تتوفّر دالة image-set() في CSS مع البادئة -webkit-image-set(). إنّ بنية الجملة بسيطة جدًا، إذ تستخدِم بيان صورة واحدًا أو أكثر مفصولًا بفواصل، ويتألّف من سلسلة عنوان URL أو دالة url() متبوعة بدرجة الدقة المرتبطة. على سبيل المثال:

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

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

بالإضافة إلى تحميل الصورة الصحيحة، سيغيّر المتصفّح حجمها وفقًا لذلك. بعبارة أخرى، يفترض المتصفّح أنّ الصورتَين أكبر مرتين من الصور ذات الحجم العادي، لذا سيقلّل حجم الصورة التي تبلغ مرتين حجم الصورة العادية بمقدار مرتين، لكي تظهر الصورة بالحجم نفسه على الصفحة.

بدلاً من تحديد 1x أو 1.5x أو Nx، يمكنك أيضًا تحديد كثافة بكسل معيّنة للجهاز بالنقاط لكل بوصة.

يعمل هذا الإجراء بشكل جيد، باستثناء المتصفّحات التي لا تتيح استخدام السمة image-set ، والتي لن تعرض أي صورة على الإطلاق. هذا أمر سيئ بوضوح، لذا يجب استخدام عنصر احتياطي (أو سلسلة من العناصر الاحتياطية) لحلّ هذه المشكلة:

background-image: url(icon1x.jpg);
background-image: -webkit-image-set(
  url(icon1x.jpg) 1x,
  url(icon2x.jpg) 2x
);
/* This will be useful if image-set gets into the platform, unprefixed.
    Also include other prefixed versions of this */
background-image: image-set(
  url(icon1x.jpg) 1x,
  url(icon2x.jpg) 2x
);

سيؤدي ما سبق إلى تحميل مادة العرض المناسبة في المتصفّحات التي تتيح استخدام التنسيق image-set، وسيتم الرجوع إلى مادة العرض ذات المقاس العادي في حال عدم توفّر هذا التنسيق. يُرجى العِلم أنّه مع أنّ استخدام متصفّح image-set() منخفض، ستحصل معظم وكلاء المستخدمين على مادة العرض ذات الحجم العادي.

يستخدم هذا العرض التوضيحي image-set() لتحميل الصورة الصحيحة، مع الرجوع إلى مادة العرض ذات الحجم العادي إذا لم تكن دالة CSS هذه متوافقة.

في هذه المرحلة، قد تتساءل لماذا لا يتم استخدام polyfill (أي إنشاء بديل لـ JavaScript) في image-set() وحلّ المشكلة؟ لقد تبيّن أنّه من الصعب جدًا تنفيذ حلول polyfill فعّالة لوظائف CSS. (للاطّلاع على شرح مفصّل لسبب ذلك، يُرجى الاطّلاع على هذه المناقشة حول أسلوب www).

سمة srcset للصور

في ما يلي مثال على srcset:

<img alt="my awesome image"
  src="banner.jpeg"
  srcset="banner-HD.jpeg 2x, banner-phone.jpeg 640w, banner-phone-HD.jpeg 640w 2x">

كما ترى، بالإضافة إلى تعريفات x التي يوفّرها image-set، يأخذ عنصر srcset أيضًا قيم w وh اللتين تتوافقان مع حجم مساحة العرض، في محاولة عرض النسخة الأكثر صلةً. ينطبق الإعداد أعلاه على عرض banner-phone.jpeg على الأجهزة التي يقلّ عرض إطار العرض فيها عن 640 بكسل، وbanner-phone-HD.jpeg على الأجهزة التي تتضمّن شاشة صغيرة بدرجة كثافة عالية، banner-HD.jpeg على الأجهزة التي تتضمّن شاشة بدرجة كثافة عالية وأكبر من 640 بكسل، و banner.jpeg على جميع الأجهزة الأخرى.

استخدام عنصر image-set لعناصر الصور

بما أنّ سمة srcset في عناصر img لا يتم تنفيذها في معظم المتصفّحات، قد يكون من المغري استبدال عناصر img بعناصر <div>s التي تتضمّن خلفيات واستخدام أسلوب مجموعة الصور. سيؤدي ذلك إلى تحقيق النتيجة المطلوبة، مع مراعاة بعض المحاذير. ويتمثل العيب هنا في أنّ العلامة <img> لها قيمة دلالية طويلة الأمد. من الناحية العملية، يكون هذا الأمر مهمًا في الغالب لزاحف الويب ولأسباب تسهيل الاستخدام.

إذا انتهى بك الأمر باستخدام -webkit-image-set، قد تميل إلى استخدام سمة CSS background. ويتمثل عيب هذا النهج في أنّك تحتاج إلى تحديد حجم الصورة، وهو غير معروف إذا كنت تستخدم صورة ليست بحجم 1x. بدلاً من ذلك، يمكنك استخدام سمة CSS للمحتوى على النحو التالي:

<div id="my-content-image"
  style="content: -webkit-image-set(
    url(icon1x.jpg) 1x,
    url(icon2x.jpg) 2x);">
</div>

سيؤدي ذلك إلى تغيير حجم الصورة تلقائيًا استنادًا إلى devicePixelRatio. اطّلِع على هذا المثال على استخدام هذه الطريقة، مع إضافة خيار احتياطي إضافي إلى url() للمتصفّحات التي لا تتوافق مع image-set.

إضافة polyfill إلى srcset

من الميزات المفيدة في srcset أنّه يتضمّن بديلاً طبيعيًا. في حال عدم تنفيذ سمة srcset، يعرف جميع المتصفّحات كيفية معالجة سمة src. وبما أنّها مجرد سمة HTML، من الممكن إنشاء polyfills باستخدام JavaScript.

تأتي هذه الإضافة مع اختبارات وحدات لضمان أنّها أقرب ما يمكن إلى المواصفات. بالإضافة إلى ذلك، هناك عمليات تحقّق متوفّرة تمنع polyfill من تنفيذ أي رمز برمجي في حال تم تنفيذ srcset بشكل أصلي.

في ما يلي عرض توضيحي لتطبيق polyfill.

الخاتمة

ما مِن حلّ سحري لحلّ مشكلة الصور ذات عدد نقاط عالية لكل بوصة.

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

لكل من JS وCSS واستخدام الخادم نقاط قوته وعيوبه. ومع ذلك، فإنّ النهج الأكثر تفاؤلاً هو الاستفادة من ميزات ال browser الجديدة. على الرغم من أنّ image-set وsrcset لا يزالان غير متوافقَين مع بعض المتصفحات، هناك بدائل مناسبة لاستخدامها اليوم.

باختصار، إليك اقتراحاتي: