من ميزات منظومة الأجهزة المعقدة الحالية أنّه يتوفّر نطاق واسع جدًا من كثافات وحدات البكسل في الشاشة. تتميز بعض الأجهزة بشاشات عالية الدقة، في حين تبقى دقة شاشات الأجهزة الأخرى متأخرة. على مطوّري التطبيقات توفير مجموعة من كثافات البكسل، ما قد يشكّل تحديًا كبيرًا. على الويب المتوافق مع الأجهزة الجوّالة، تتفاقم الصعوبات بسبب عدة عوامل:
- مجموعة كبيرة من الأجهزة ذات أشكال مختلفة
- معدّل نقل البيانات للشبكة وعمر البطارية محدودان
في ما يتعلّق بالصور، يهدف مطوّرو تطبيقات الويب إلى عرض الصور الأعلى جودة بأكبر قدر ممكن من الكفاءة. ستتناول هذه المقالة بعض الأساليب المفيدة لإجراء ذلك اليوم وفي القريب المستقبل.
تجنَّب استخدام الصور إن أمكن.
قبل فتح هذه العلبة التي تحتوي على عدد كبير من المشاكل، تذكَّر أنّ الويب يتضمّن العديد من التقنيات القوية التي لا تعتمد إلى حد كبير على الدقة وكثافة البكسل. على وجه التحديد، سيتم عرض النص وSVG ومعظم صفحات CSS "ببساطة" بسبب ميزة تكبير وحدات البكسل التلقائية على الويب (من خلال devicePixelRatio).
ومع ذلك، لا يمكنك دائمًا تجنُّب استخدام الصور المخصّصة للطباعة. على سبيل المثال، قد تحصل على أصول يصعب نسخها بتنسيق SVG/CSS الخالص أو إذا كنت تتعامل مع صورة فوتوغرافية. على الرغم من أنّه يمكنك تحويل الصورة إلى SVG تلقائيًا، لا يُنصح بتحويل الصور الفوتوغرافية إلى صور متّجهة، لأنّ الإصدارات الموسّعة لا تبدو عادةً جيدة.
الخلفية
لمحة قصيرة جدًا عن كثافة العرض
في الأيام الأولى، كانت كثافة وحدات البكسل في شاشات الكمبيوتر تبلغ 72 أو 96 نقطة لكل بوصة (نقطة لكل بوصة).
تحسّنت كثافة البكسل في الشاشات تدريجيًا، ويعود ذلك إلى حد كبير إلى حالة استخدام الأجهزة الجوّالة، حيث يضع المستخدمون هواتفهم عمومًا أقرب إلى وجوههم، ما يجعل البكسل أكثر ظهورًا. بحلول عام 2008، أصبحت الهواتف التي تبلغ دقتها 150 نقطة لكل بوصة هي المعيار الجديد. استمرّ اتجاه زيادة كثافة الشاشة، وأصبحت هواتف اليوم الجديدة مزوّدة بشاشات بدقة 300 نقطة لكل بوصة (تُطلق عليها Apple اسم "Retina").
إنّ الشاشة التي لا تظهر فيها وحدات البكسل على الإطلاق هي الشاشة المثالية. بالنسبة إلى شكل الهاتف، قد يكون الجيل الحالي من شاشة Retina/HiDPI قريبًا من هذا المستوى المثالي. ولكن من المرجّح أن تواصل فئات الأجهزة والأجهزة القابلة للارتداء الجديدة، مثل Project Glass، زيادة كثافة البكسل.
من الناحية العملية، من المفترض أن تظهر الصور ذات الكثافة المنخفضة بالشكل نفسه على الشاشات الجديدة مقارنةً بالقديمة، ولكن مقارنةً بالصور الواضحة ذات الكثافة العالية التي اعتاد المستخدمون رؤيتها، تبدو الصور ذات الكثافة المنخفضة مزعجة ومموّهة. في ما يلي محاكاة تقريبية لشكل صورة بحجم 1x على شاشة بحجم 2x. في المقابل، تبدو الصورة المكبّرة مرتين جيدة جدًا.
هواتف Pixel على الويب
عند تصميم الويب، كانت كثافة 99% من الشاشات 96 نقطة في البوصة (أو كانت تُفترض أن تكون)، ولم يتم توفير سوى القليل من الأحكام للاختلاف في هذا الشأن. بسبب الاختلاف الكبير في أحجام الشاشات وكثافتها، احتجنا إلى طريقة قياسية لجعل الصور تبدو جيدة على مختلف كثافات الشاشات وأبعادها.
عالجت مواصفات HTML هذه المشكلة مؤخرًا من خلال تحديد بكسل مرجعي يستخدمه المصنّعون لتحديد حجم بكسل CSS.
باستخدام وحدة البكسل المرجعية، يمكن لجهة التصنيع تحديد حجم وحدة البكسل الفعلية للجهاز مقارنةً بوحدة البكسل العادية أو المثالية. وتُعرف هذه النسبة باسم نسبة وحدات البكسل على الجهاز.
احتساب نسبة وحدات البكسل على الجهاز
لنفترض أنّ هاتفًا ذكيًا يحتوي على شاشة بحجم بكسل فعلي يبلغ 180 بكسل لكل بوصة (ppi). تستغرق عملية احتساب نسبة وحدات البكسل على الجهاز ثلاث مراحل:
قارِن المسافة الفعلية التي يتم فيها تثبيت الجهاز مع المسافة لوحدة البكسل المرجعية.
وفقًا للمواصفات، نعلم أنه عند قياس 28 بوصة، يكون المثالي هو 96 بكسل لكل بوصة. ومع ذلك، بما أنّه هاتف ذكي، يمسك المستخدمون بالجهاز بشكلٍ أقرب إلى وجوههم مقارنةً بالكمبيوتر المحمول. لنقدّر تلك المسافة بمقدار 18 بوصة.
اضرب نسبة المسافة بالكثافة القياسية (96 بكسل في البوصة) للحصول على كثافة البكسل المثالية للمسافة المحددة.
idealPixelDensity = (28/18) * 96 = 150 بكسل لكل بوصة (تقريبًا)
احسب نسبة كثافة وحدات البكسل الفعلية إلى كثافة وحدات البكسل المثالية للحصول على نسبة وحدات البكسل على الجهاز.
devicePixelRatio
= 180/150 = 1.2
وبالتالي، عندما يحتاج المتصفّح إلى معرفة كيفية تغيير حجم صورة لتلائم الشاشة وفقًا لدرجة الدقة المثالية أو العادية، يشير المتصفّح إلى نسبة وحدات البكسل على الجهاز التي تبلغ 1.2، ما يعني أنّه لكل بكسل مثالي، يحتوي هذا الجهاز على 1.2 بكسل فعلي. في ما يلي صيغة المزج بين وحدات البكسل المثالية (كما هو موضح في مواصفات الويب) ووحدات البكسل المادية (النقاط على شاشة الجهاز):
physicalPixels = window.devicePixelRatio * idealPixels
في السابق، كان مورّدو الأجهزة يميلون إلى تقريب devicePixelRatios
(DPR). تُظهر أجهزة iPhone وiPad من Apple نسبة عرض إلى ارتفاع تبلغ 1، بينما تُظهر الأجهزة المزوّدة بشاشة Retina
نسبة عرض إلى ارتفاع تبلغ 2. تنص مواصفات CSS على ما يلي:
تشير وحدة البكسل إلى العدد الكامل لوحدات البكسل في الجهاز الذي يقترب بشكلٍ أفضل من وحدات البكسل المرجعية.
من بين الأسباب التي تجعل النسب المستديرة أفضل هو أنّها قد تؤدي إلى استخدام عدد أقل من العناصر المرئية على مستوى البكسل الفرعي.
ومع ذلك، فإنّ الواقع في ما يتعلّق بالأجهزة الأفقية أكثر تنوعًا، وغالباً ما تكون هواتف Android ذات نسبة عرض إلى ارتفاع تبلغ 1.5. يحتوي الجهاز اللوحي Nexus 7 على معدل تكرار DPR يبلغ حوالي 1.33، وقد تم الوصول إليه عن طريق عملية حسابية مشابهة لتلك المذكورة أعلاه. من المتوقّع أن نطرح هذه الميزة على المزيد من الأجهزة في المستقبل. وبناءً على ذلك، يجب ألّا تفترض أبدًا أنّ عملائك سيحصلون على معدّلات أرباح مثبّتة.
نظرة عامة على تقنيات الصور بدقة عالية الكثافة
هناك العديد من الأساليب لحلّ مشكلة عرض أفضل الصور بأسرع وقت ممكن، وتندرج هذه الأساليب بشكل عام ضمن فئتين:
- تحسين الصور الفردية
- تحسين الاختيار بين صور متعددة
طرق استخدام صورة واحدة: استخدِم صورة واحدة، ولكن احرص على استخدامها بطريقة ذكية. ولهذه الأساليب عيب، إذ أنك ستتضحى بأدائك، لأنك ستنزِّل صور HiDPI حتى على الأجهزة القديمة ذات عدد النقاط لكل بوصة (DPI) الأقل. في ما يلي بعض الأساليب المتعلّقة بالحالة التي تتضمّن صورة واحدة:
- صورة HiDPI مضغوطة بشدة
- تنسيق الصورة رائع جدًا
- تنسيق الصورة المتقدّمة
طرق استخدام صور متعددة: استخدِم صورًا متعددة، ولكن اتّبِع أسلوبًا ذكيًا لاختيار الصور التي تريد تحميلها. لهذه الأساليب أعباء عامة متأصلة في المطور لإنشاء إصدارات متعددة من نفس الأصول ثم اكتشاف استراتيجية القرار. في ما يلي الخيارات المتاحة:
- JavaScript
- التسليم من جهة الخادم
- طلبات الاستعلام عن الوسائط في CSS
- ميزات المتصفّح المضمَّنة (
image-set()
و<img srcset>
)
صورة HiDPI مضغوطة بشدة
تشكّل الصور حاليًا نسبة كبيرة تبلغ %60 من معدل نقل البيانات المستخدَم في تنزيل موقع إلكتروني عادي. ومن خلال عرض صور بدقة عالية لجميع العملاء، سن يزيد هذا العدد. كم سيكون حجمه أكبر؟
أجريتُ بعض الاختبارات التي أدّت إلى إنشاء أجزاء من الصور بحجمَين 1x و2x بجودة JPEG 90 و50 و20. في ما يلي النص البرمجي Shell الذي استخدمته (باستخدام ImageMagick) لإنشاء المحتوى:
من خلال هذه العينة الصغيرة غير العلمية، يبدو أنّ ضغط الصور الكبيرة يقدّم توازنًا جيدًا بين الجودة والحجم. بالنسبة إليّ، تبدو الصور المضغوطة بشدة مرتين أفضل من الصور غير المضغوطة مرتين.
بالطبع، إنّ عرض صور ذات جودة منخفضة ودرجة ضغط عالية بمقدار مرتين على الأجهزة التي تعمل بمقدار مرتين أسوأ من عرض صور ذات جودة أعلى، ويؤدي الأسلوب المذكور أعلاه إلى فرض عقوبات على جودة الصورة. عند مقارنة الجودة: 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>
، ويجب أن تكون صورك
جميعها عناصر لها خلفية. أخيرًا، من خلال الاعتماد المكثّف على نسبة وحدات البكسل في الأجهزة، قد ينتهي بك الأمر في مواقف قد ينتهي فيها هاتفك الذكي
بدرجات أعلى لكل بوصة إلى تنزيل مادة عرض صور ضخمة بحجم 2x أثناء استخدام
اتصال EDGE. هذه ليست أفضل تجربة للمستخدم.
استخدام ميزات المتصفّح الجديدة
جرت مناقشات كثيرة مؤخرًا حول دعم منصة الويب
لمشكلة ارتفاع عدد النقاط لكل بوصة (DPI). اقتحمت شركة Apple مؤخرًا المجال، وجلبت دالة image-set() CSS إلى WebKit. نتيجةً لذلك، يتيح كل من
Safari وChrome استخدام هذه الميزة. بما أنّها دالة CSS، لا تعالج image-set()
المشكلة في علامات <img>
. أدخِل
@srcset، الذي يعالج هذه المشكلة ولكنّه (في وقت pennedكتابة هذه المقالة) لا يتضمّن أي عمليات تنفيذ مرجعية (حتى الآن). يتناول القسم التالي بالتفصيل image-set
وsrcset
.
ميزات المتصفّح لتوفير كثافة بكسل عالية
في النهاية، يعتمد القرار الذي تتّخذه بشأن المنهج الذي ستتبعه على
متطلباتك المحدّدة. ومع ذلك، ضع في اعتبارك أن جميع
الأساليب المذكورة أعلاه لها عيوب. في المستقبل، بعد أن تصبح 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، والأخرى لشاشات 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()
، سيحصل معظم برامج وكيل المستخدم على مادة العرض 1x.
يستخدم هذا العرض التوضيحي 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 تتناسب مع حجم إطار العرض، لمحاولة عرض النسخة الأكثر صلة. سيؤدي ذلك أعلاه إلى عرض البانر-phone.jpeg للأجهزة التي يكون عرض إطار العرض فيها أقل من 640 بكسل، وBanner-phone-HD.jpeg للأجهزة التي تتميز بارتفاع DPI في الشاشة الصغيرة، وBanner-HD.jpeg للأجهزة ذات DPI العالية ذات شاشات أكبر من 640 بكسل وbanner.jpeg لكل شيء آخر.
استخدام مجموعة الصور لعناصر الصورة
بما أنّ سمة srcset في عناصر img لا يتم تنفيذها في معظم
المتصفّحات، قد يكون من المغري استبدال عناصر img بعناصر <div>
s
التي تتضمّن خلفيات واستخدام أسلوب مجموعة الصور. سينجح هذا،
مع المحاذير. ويتمثل العيب هنا في أنّ العلامة <img>
لها قيمة دلالية لعدة سنوات. من الناحية العملية، يكون هذا الأمر مهمًا في الغالب لزاحف الويب
ولأسباب تسهيل الاستخدام.
إذا استخدمت -webkit-image-set
في النهاية، قد تحاول استخدام
خاصية CSS للخلفية. ويتمثل عيب هذا النهج في أنّك تحتاج
إلى تحديد حجم الصورة، وهو غير معروف إذا كنت تستخدم صورة ليست بحجم 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 هذه مع اختبارات الوحدات للتأكُّد من أنها أقرب شكلاً إلى المواصفات. بالإضافة إلى ذلك، هناك عمليات تحقّق متوفّرة تمنع polyfill من تنفيذ أي رمز برمجي في حال تم تنفيذ srcset بشكل أصلي.
في ما يلي عرض توضيحي لتطبيق polyfill.
الخاتمة
ما مِن حلّ سحري لحلّ مشكلة الصور ذات عدد نقاط عالية لكل بوصة.
إنّ أسهل حلّ هو تجنُّب استخدام الصور تمامًا، واستخدام SVG وCSS بدلاً من ذلك. ومع ذلك، قد لا يكون ذلك واقعيًا في بعض الأحيان، خاصةً إذا كانت لديك صور عالية الجودة على موقعك الإلكتروني.
لكل من JS وCSS واستخدام الخادم نقاط قوته
وعيوبه. ومع ذلك، فإنّ النهج الأكثر تفاؤلاً هو الاستفادة من ميزات ال browser الجديدة. على الرغم من أنّ التوافق مع المتصفّحَين image-set
وsrcset
لا يزال غير مكتمل، هناك إجراءات احتياطية معقولة يمكن استخدامها في الوقت الحالي.
باختصار، إليك اقتراحاتي:
- بالنسبة إلى صور الخلفية، استخدِم image-set مع العناصر الاحتياطية المناسبة للمتصفحات التي لا تتوافق معها.
- بالنسبة إلى صور المحتوى، استخدِم مجموعة polyfill لـ srcset، أو استخدِم استخدام image-set كخيار احتياطي (راجِع أعلاه).
- في الحالات التي تكون فيها مستعدًا للتنازل عن جودة الصورة، ننصح باستخدام صور مضغوطة بدرجة كبيرة بمقدار ضعف حجمها الأصلي.