
اسمي فلاديمير ، وأطور واجهة الهاتف المحمول لـ Yandex Mail. تمتاز تطبيقاتنا بمظهر مظلم لفترة من الوقت ، لكنها كانت غير مكتملة: لم تكن سوى الواجهة ورسائل البريد الإلكتروني المظلمة مظلمة. ظلت الرسائل ذات التنسيق المخصص خفيفة وبرزت أمام الواجهة المظلمة ، مما أضر بعيون مستخدمينا في الليل.
سأخبرك اليوم كيف أصلحنا هذه المشكلة. سوف تتعلم عن طريقتين بسيطتين لم تنفعان بالنسبة إلينا والطريقة التي نجحت في حلها - إعادة تلوين الصفحة القابلة للتكيف. سوف أشارك أيضًا بعض الأفكار حول تكييف الصور مع مظهر مظلم. لكي نكون منصفين ، فإن الصفحات الداكنة مع CSS المخصصة هي مهمة غريبة إلى حد ما ، لكنني أعتقد أن بعضًا منكم قد يجد تجربتنا مفيدة.
طرق بسيطة
قبل أن نستقر على أسلوبنا السحري لثني الألوان ، جربنا خيارين أساسيين حقًا: إما تطبيق التصميم الداكن الإضافي أو مرشح CSS على العناصر. لم ينجح أي من الخيارين لنا ، ولكن قد يكون أكثر ملاءمة في الحالات الأخرى (بسيط بسيط ، أليس كذلك؟).
تجاوز الأساليب
هذا خيار بسيط للغاية ، والذي يمتد منطقيا CSS الظلام موضوع التطبيق. يمكنك فقط وضع أنماط داكنة إضافية على حاوية بريد إلكتروني (أو بشكل عام ، على حاوية للمحتوى الذي ينشئه المستخدم لتغميقه):
.message--dark { background-color: black; color: white; }
ومع ذلك ، فإن أي أنماط على العناصر الموجودة داخل البريد الإلكتروني ستتجاوز نمط الجذر الخاص بنا. و لا !important
لا يساعد هنا. يمكن اتخاذ خطوة إلى الأمام عن طريق منع الميراث:
.message--dark * { background-color: black !important; color: white !important; border-color: #333 !important; }
في هذه الحالة ، لا يمكنك الاستغناء عنها !important
، لأن المحدد نفسه ليس محددًا للغاية. يحدث هذا أيضًا لتجاوز معظم الأنماط المضمّنة (تلك المضمّنة !important
لا يزال من !important
العثور على طريقها ، وليس هناك الكثير مما يمكنك فعله حيال ذلك).
أسلوبنا يرسم بشغف كل شيء بنفس اللون ، وبالتالي إدخال مشكلة أخرى. هناك فرصة أراد المصمم أن يقول شيئًا بالطريقة التي رتبوا بها الألوان (كما تعلمون ، الأولويات ، الإقران ، كل تلك الأشياء الخاصة بالمصمم) ، وقد أخذنا فكرتهم وطردناها من النافذة. ليس شيء جميل القيام به.

إذا كنت لا تحترم المصممين بقدر ما أحترم وقررت اتباع هذه الطريقة ، فلا تنس التعامل مع الأشياء غير الواضحة:
box-shadow
. ومع ذلك ، لن تكون قادرًا على تجاوز اللون فقط. إما أن تتخلص من الظل تمامًا أو أن تصنع السلام مع النور.- ألوان العناصر الدلالية ، مثل الروابط أو المدخلات.
- مضمنة SVG. استخدم
fill
بدلاً من background
، والحد بدلاً من color
، لكن لا يمكنك أن تكون متأكدًا أبدًا ، فقد يكون الأمر عكس ذلك.
من وجهة نظر تقنية ، هذه طريقة صلبة: فهي تأخذ ثلاثة أسطر من التعليمات البرمجية (موافق ، ثلاثون لإصدار جاهز للإنتاج مع مراعاة جميع الحالات المتطورة) ، وهي متوافقة مع جميع المتصفحات في العالم ، يعمل على الصفحات الديناميكية خارج الصندوق ، والطريقة التي يتم بها إرفاق CSS بالوثيقة لا صلة لها بالموضوع. هناك أيضًا مكافأة رائعة: يمكنك بسهولة تعديل الألوان في النمط لمطابقة الألوان الرئيسية للتطبيق (على سبيل المثال ، قم #bbbbb8
الخلفية #bbbbb8
بدلاً من الأسود).
بالمناسبة ، هكذا اعتدنا على تغميق رسائل البريد الإلكتروني من قبل. إذا كان للبريد الإلكتروني أي أنماط خاصة به ، فسنستسلم ونضعها في حالة جيدة.
باستخدام مرشح CSS
هذه طريقة ذكية وأنيقة. يمكنك تغميق الصفحة باستخدام مرشح CSS:
.message--dark { filter: invert(100) hue-rotate(180deg); }
تصبح الصور زاحفة ، لكن يمكننا إصلاح ما يلي بسهولة:
.message-dark img { filter: invert(100) hue-rotate(180deg); }

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

- صفحات الظلام تصبح مشرقة.
- لا يمكنك التحكم في الألوان النهائية. ما المرشح الذي تقدمه إلى الخلفية بحيث يطابق علامتك التجارية
#bbbbb8
؟ هذا هو رأس الخدش الحقيقي. - انعكاس مزدوج يجعل الصور تلاشى.
- يكون الأداء بطيئًا ، خاصةً على الأجهزة المحمولة - منطقيًا ، فبدلاً من مجرد عرض الصفحة ، يقوم المستعرض بتشغيل تحويل فورييه على كل سحب.
تعمل هذه الطريقة مع رسائل البريد الإلكتروني ذات النص ذي الألوان المحايدة ، لكنني لم أقابل أي شخص مطلقًا في صندوق الوارد الكامل لهذا المحتوى. من ناحية أخرى ، تعتبر المرشحات هي الطريقة الوحيدة لتغميق العناصر دون الوصول إلى محتوياتها - الإطارات أو مكونات الويب أو الصور.
موضوع الظلام التكيفي
والآن حان الوقت للسحر! استنادًا إلى عيوب النهجين الأولين ، وضعنا قائمة مرجعية بما ينبغي أن نهتم به:
- اجعل الخلفية مظلمة وضوء النص والحدود في مكان ما بينهما.
- كشف الصفحات المظلمة والحفاظ على ألوانها.
- الحفاظ على التوازن الأصلي للسطوع والتباين.
- إعطاء السيطرة على الألوان الناتجة.
- اترك الأشكال دون تغيير.
لذلك ، تحتاج إلى تغيير ألوان الأنماط لجعل الخلفية مظلمة. لماذا لا تفعل ذلك فقط ، حرفيا؟ استخدم جميع الأنماط ، واستخلص القواعد المتعلقة color
( color
، background
، border
، box-shadow
، وخصائصها الفرعية) ، واستبدلها بإصداراتها "المظلمة": قم بتغميق الخلفية والحدود (لكن ليس بقدر الخلفية) ، تفتيح النص ، الخ
هذه الطريقة لها ميزة رائعة ستدفئ قلب أي مطور. يمكنك تكوين قواعد تحويل اللون لكل خاصية - نعم ، باستخدام الكود! مع قليل من الخيال ، يمكنك ملائمة الألوان مع أي سمة خارجية ، وتنفيذ أي تصحيح للألوان ترغب فيه (على سبيل المثال ، القيام بمظهر فاتح بدلاً من مظلم ، أو سمة بأي لون تريده) ، وحتى إضافة القليل من السياق - على سبيل المثال ، تعامل مع الحدود الواسعة والضيقة بشكل مختلف.
العيوب هي ما تتوقعه من نهج "كل ما في اللعبة". نقوم بتشغيل البرامج النصية ، تغليف نمط الفوضى ، وتحليل CSS مع regex. ومع ذلك ، فإن هذا الأخير ليس مهينًا كما هو الحال مع HTML ، لأن قواعد CSS هي قواعد منتظمة (على الأقل في المستوى الذي نتعامل معه).
ها هي خطتنا المظلمة:
- قم بتطبيع خصائص النمط القديم (
bgcolor
وغيرها) ونقلها إلى style="..."
. - العثور على جميع الأنماط المضمنة.
- ابحث عن كل القواعد المتعلقة بالألوان في كل نمط (
background-color
box-shadow
وغيرها). - أخذ الألوان من الخصائص المتعلقة بالألوان ومطابقتها مع المحول الصحيح (تغميق الخلفية ، تفتيح النص).
- استدعاء المحول.
- ضع الخصائص المحولة مرة أخرى في CSS.
رمز المجمع - التطبيع ، تحديد أنماط ، تحليل - هو تافهة جدا. دعونا نرى كيف يعمل المحول السحري بالضبط.
تحويلات HSL
إن تغميق اللون ليس بسيطًا كما يبدو ، خاصةً إذا كنت ترغب في الحفاظ على التدرج اللوني (على سبيل المثال ، يمكنك تحويل اللون الأزرق إلى اللون الأزرق الداكن وليس اللون البرتقالي). يمكنك القيام بذلك في RGB العادي ، لكنه يمثل مشكلة. إذا كنت تعمل في تصميم حسابي ، فأنت تعلم أنه في RGB ، حتى التدرجات مكسورة. وفي الوقت نفسه ، يعد العمل باستخدام الألوان في HSL تجربة حقيقية: بدلاً من الأحمر والأخضر والأزرق ، والتي ليس لديك أي فكرة عما يمكنك فعله ، لديك القنوات الثلاث التالية:
- هوى - الشيء الذي نتطلع إلى الحفاظ عليه.
- التشبع ، وهو أمر غير مهم للغاية بالنسبة لنا الآن.
- خفة ، ونحن سوف تتغير.
يمكنك التفكير في الأمر باعتباره اسطوانة. نحن بحاجة إلى قلب هذه الاسطوانة رأسًا على عقب. يقوم تصحيح الألوان بشيء من هذا القبيل: (h, s, l) => [h, s, 1-l]
.
الألوان التي هي بالفعل موافق
أحيانًا ما نكون محظوظين والتصميم المخصص للبريد الإلكتروني (أو جزء منه) مظلمة بالفعل. هذا يعني أننا لسنا بحاجة إلى تغيير أي شيء - ربما قام المصمم بعمل أفضل في اختيار الألوان أكثر مما كان يحلم به الخوارزمية. في HSL ، تحتاج فقط إلى التفكير في L - Lightness. إذا كانت قيمتها أعلى أو أقل (بالنسبة للنص والخلفية ، على التوالي) من العتبة (التي يمكنك تعيينها) ، فما عليك سوى تركها بمفردها.
السيرك الديناميكي
على الرغم من أننا لم نكن بحاجة إلى أي من هذا (شكرًا جزيلاً ، المطهر ، لقد أنقذت يومي هنا) ، سأدرج الميزات الإضافية التي يحتاجها السمة التكيفية لتغميق الصفحات بأكملها وليس فقط رسائل البريد الإلكتروني الثابتة من التسعينيات. تحذير عادل: هذه المهمة ليست للجميع.
أنماط مضمنة ديناميكية
تغيير الأنماط المضمّنة هو أبسط الحالات التي تفسد صفحاتنا الداكنة. إنه أمر شائع ، ولكن يوجد إصلاح بسيط: إضافة MutationObserver
وإصلاح الأنماط المضمنة بمجرد حدوث التغييرات.
الأنماط الخارجية
العمل مع الأنماط المشار إليها بواسطة عنصر <link>
من داخل الصفحة يمكن أن يكون مؤلمًا بسبب عدم التزامن @import
. و CORS لا تجعل الأمور أفضل. يبدو أن هذه المشكلة يمكن حلها بشكل أنيق تمامًا من خلال عامل الويب (الذي يقوم بتوكيل جميع *.css
).
الأساليب الديناميكية
لجعل الأمور أسوأ ، يمكن أن تضيف البرامج النصية عناصر <style>
و <link>
أو تزيلها أو تعيد ترتيبها كما تشاء ، بل وتغيير القواعد في <style>
. هنا ستحتاج أيضًا إلى استخدام MutationObserver
، ولكن كل تغيير سيتطلب معالجة أكثر.
متغيرات CSS
تصبح الأمور حقيقية عندما تدخل متغيرات CSS. لا يمكنك تغميق المتغيرات: حتى إذا كنت تعتقد أن أحد المتغيرات يحتوي على لون بناءً على تنسيقه (على الرغم من أنني أنصح بهذا) ، لا تزال لا تعرف دوره - الخلفية أو النص أو الحدود أو الكل في آن واحد؟ علاوة على ذلك ، يتم توارث قيم متغيرات CSS ، لذلك تحتاج إلى تتبع ليس فقط الأنماط ، ولكن العناصر التي يتم تطبيقها عليها ، وهذا يتصاعد بسرعة خارج نطاق السيطرة.
بمجرد وصول متغيرات CSS إلى الاتجاه السائد ، فإننا في ورطة. من ناحية أخرى ، سيتم دعم color()
بحلول ذلك الوقت ، مما يسمح لنا باستبدال جميع تحويلات JS لدينا color(var(--bg) lightness(-50%))
.
ملخص

في حالتنا ، عندما لا يترك المطهر سوى أنماط مضمّنة ، يعمل اللون الداكن التكيفي على مستوى CSS كأنه سحر: فهو يعطي تغميق عالي الجودة ، ولا يعطل البنية الأصلية ، وهو بسيط وسريع نسبيًا. قد لا يكون تمديدها لمعالجة الصفحات الديناميكية أمرًا يستحق العناء. لحسن الحظ ، إذا كنت تعمل مع محتوى تم إنشاؤه بواسطة المستخدم ولم تقم بتطوير مستعرض ، فمن المحتمل أن يعمل المطهر الخاص بك بنفس الطريقة.
في الممارسة العملية ، يجب إقران الوضع التكيفي بتجاوزات النمط ، نظرًا لأن العناصر القياسية مثل <input>
أو <a>
غالباً ما تستخدم أنماط الإضاءة الافتراضية.
كيفية تغميق الصور
سواد الصورة هي قضية منفصلة تزعجني شخصياً. إنه أمر صعب ، ويعطيني ذريعة لاستخدام أخيرًا عبارة "التحليل الطيفي". هناك العديد من المشاكل النموذجية مع الصور ذات المظهر المظلم.
بعض الصور مشرقة جدا. هذه تعطينا نفس مشكلة رسائل البريد الإلكتروني المشرقة التي بدأنا بها سعينا. غالبًا ما تنشأ هذه المشكلة في الصور العادية ، ولكنها ليست مقصورة على هذه الصور. نظرًا لأن كتابة النشرة الإخبارية CSS ليست ممتعة كثيرًا ، فإن بعض اللاعبين يحبون تخطي الزوايا عن طريق إدراج تخطيط معقد كصورة ، مما يمنع التغميق. عندما أرى ذلك ، يئن بلدي الكمال الداخلي من الإحباط. يجب أن تكون هذه الصور باهتة ، ولكن غير مقلوبة ، إلا إذا كنت تريد تخويف المستخدمين لديك.

ثم هناك صور مظلمة مع شفافية حقيقية. هذه مشكلة نموذجية في الشعارات - فهي مصممة مع وضع خلفية خفيفة في الاعتبار ، وعندما نستبدلها بخلفية داكنة ، يختفي الشعار فيها. هذه الصور تحتاج إلى قلب.

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

ومن المثير للاهتمام أن بعض الصور لا تحمل أي معنى على الإطلاق. عادة ما يتم تتبع هذه البكسلات أو "أصحاب التنسيقات" في تخطيطات bizzare بشكل خاص. يمكنك جعلها بأمان غير مرئية (على سبيل المثال ، مع opacity: 0
).

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

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