كيفية إنشاء موضوع مظلم وليس ضرر. تجربة فريق ياندكس


اسمي فلاديمير ، أنا منخرط في واجهة متنقلة في Yandex.Mail. في تطبيقنا ، كان هناك بالفعل موضوع غامق ، لكن ليس كافيًا: لقد استطعنا إعادة رسم الواجهة والرسائل البسيطة. لكن الحروف المنسقة ظلت خفيفة وتتناقض مع واجهة مظلمة ، مما قد يجعل عيناي متعبة في الليل.


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


طرق بسيطة


قبل أن نصل إلى "repainter" السحري ، جربنا خيارين بسيطين مثل الفلين: إضافة نمط مظلم إضافي أو مرشح 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 سيتم الزحف إليها على أي حال ، لا يوجد شيء يجب القيام به).


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



إذا كنت تحترم المصممين أقل مما أحترم ، وما زلت تقرر استخدام هذه الطريقة ، فلا تنسَ إنهاء التافهات غير الواضحة:


  • box-shadow - فقط اللون لا يمكن إعادة تعريفه ؛ يجب عليك إزالة جميع الظلال أو التعايش مع الضوء.
  • ألوان العناصر الدلالية - الروابط ، عناصر الإدخال.
  • على SVG - بدلاً من background ، يحتاجون إلى ضبط fill ، وبدلاً من حد color ، لكن هذا ليس دقيقًا ، حسب نوع SVG - يمكن أن يكون والعكس صحيح.

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


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


مرشح المغلق


خيار ذكي جدا وأنيق. يمكنك إعادة رسم الصفحة باستخدام مرشح CSS:


 .message--dark { filter: invert(100) hue-rotate(180deg); /* hue-rotate    */ } 

بعد ذلك ، ستصبح الصور زاحفة ، لكن لا يهم - سنعيد رسمها مرة أخرى:


 .message-dark img { filter: invert(100) hue-rotate(180deg); } 


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


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



  1. صفحات مظلمة تفتيح.
  2. لا يمكن التحكم في الألوان الناتجة - ما هو المرشح الذي سيتم تطبيقه لضبط الخلفية على شركتك #bbbbb8 ؟ اللغز.
  3. بعد اثنين من إعادة طلاء ، الصور تتلاشى.
  4. كل شيء يبطئ (خاصة على الهواتف) - إنه أمر منطقي ، والآن بدلاً من عرض بسيط يحتاج المتصفح إلى تشغيل معالجة الصور على كل شاشة.

ستكون هذه الطريقة مناسبة للأحرف التي تتكون من نص بألوان محايدة ، ولكن من هم هؤلاء الجماليات الذين يحصلون على صندوق الوارد الكامل لهذا المحتوى الغريب؟ لكن المرشحات يمكنها إعادة طلاء العناصر التي لا يمكن الوصول إلى محتوياتها - الإطارات ، مكونات الويب ، الصور.


موضوع استجابة


لقد حان الوقت للسحر! من بين أوجه القصور في النهجين الأولين ، نجمع قائمة مرجعية:


  1. اجعل الخلفية مظلمة ، ضوء النص ، الحدود المتوسطة.
  2. تحديد الصفحات المظلمة بالفعل وعدم إعادة رسمها.
  3. حافظ على النسبة الأصلية للسطوع والتباين.
  4. إعطاء القدرة على تخصيص الألوان.
  5. اترك النغمات كما كانت في البداية.

نحتاج إلى تغيير ألوان الأنماط بحيث تكون الخلفية مظلمة. ولماذا لا تفعل ذلك حرفيا؟ نحن فقط نأخذ كل الأنماط ونبحث عن القواعد المرتبطة بالألوان ( color ، background ، border ، box-shadow ، خصائصها الفرعية) ، ونستبدلها بـ "مظلمة" - تغميق الخلفية ، تفتيح النص ، تغميق الحدود أقل من الخلفية ، إلخ.


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


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


خطة إعادة الطلاء هي كما يلي:


  1. نقوم بتطبيع الخصائص القديمة للأسلوب ( bgcolor والأصدقاء) ، ونحولها إلى style="..." .
  2. البحث عن جميع الأنماط المضمنة.
  3. في كل نمط ، نجد كل قواعد اللون ( background-color ، color ، box-shadow ، إلخ).
  4. من كل قواعد الألوان ، نحصل على الألوان ، نجد المحول المطلوب (أغمق للخلفية ، مصور للنص).
  5. نحن نسمي المحول.
  6. إعادة القواعد المحولة إلى CSS.

الربط (التطبيع ، البحث عن الأسلوب ، التحليل) بسيط للغاية. سنكتشف كيف يعمل محولنا السحري بالضبط.


تحويلات HSL


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


  • هيو هي مجرد نغمة نريد الاحتفاظ بها.
  • Saturaion - التشبع ، وهو أمر غير مهم للغاية بالنسبة لنا الآن.
  • الخفة - السطوع الذي سوف نغيره.

يتم تمثيل مثل هذه المساحة بشكل مريح في شكل اسطوانة. ومهمتنا هي قلب هذه الاسطوانة رأسًا على عقب. وظائف الدرجات اللونية تفعل شيئًا مثل (h, s, l) => [h, s, 1 - l] .


الألوان التي كل شيء جيد


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


السيرك الديناميكي


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


أنماط مضمنة ديناميكية


أبسط الحالات التي تقطع الصفحة المظلمة لدينا هي تغيير الأنماط المضمنة. العملية متكررة ، ولكن الإصلاح بسيط: قم بإضافة MutationObserver وإصلاح الأنماط المضمّنة بسرعة عند التغيير.


الأنماط الخارجية


العمل باستخدام أنماط من <link> من داخل الصفحة أمر مؤلم إلى حد ما بسبب عدم التزامن و @import ، ولا يعد CORS أكثر متعة. يبدو أن هذه المشكلة يمكن حلها بشكل أنيق تمامًا من خلال عامل الويب (الوكيل لـ *.css ).


الأساليب الديناميكية


أخيرًا ، مع تجميع جميع مشكلاتنا ، نذكر أن البرنامج النصي يمكنه عمومًا إضافة وحذف وإعادة ترتيب (خصوصية! Cascade!) <style> و <link> ، وحتى تغيير القواعد في <style> . يتم حل كل شيء بواسطة نفس MutationObserver لعناصر النمط ، ولكن لكل تغيير هناك معالجة أكثر.


متغيرات CSS


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


إذا وصلت متغيرات CSS إلى التيار الرئيسي ، فلدينا مشكلة. من ناحية أخرى ، بحلول ذلك الوقت ، سيكون color() قد بدأ بالفعل ، والذي سيكون من الممكن عدم تغيير الألوان في JS ، ولكن ببساطة استبدل الألوان color(var(--bg) lightness(-50%)) .


ملخص



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


في الممارسة العملية ، يجب استخدام الوضع التكيفي إلى جانب إعادة تعريف الأنماط: عادة ما لا يتم تطبيق الأنماط بشكل صريح على العناصر القياسية مثل <input> أو <a> ، ولكنها خفيفة بشكل افتراضي.


كيفية تغميق الصور


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


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



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



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



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



الاستدلال الاستقراء


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


نحن نعتبر البيكسلات الداكنة والخفيفة والشفافة في الصورة ، وليس كلها ، ولكن بشكل انتقائي - تحسين واضح. نحدد السطوع الكلي للصورة (الضوء ، الظلام ، المتوسط) ووجود الشفافية. عكس الصور المظلمة بشفافية ، ضوء بدون شفافية - كتم الصوت ، لا تلمس الباقي.


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


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



يؤدي


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


إذا احتجت في أي وقت إلى إعادة رسم HTML المخصص إلى سمة مظلمة ، ضع في الاعتبار ثلاث طرق:


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

حتى لو لم تفعل هذا أبداً ، أتمنى أن تكون قد استمتعت!


روابط مفيدة :


  1. إذا كنت مهتمًا بمناقشة هذا الموضوع بشكل حيوي وفي سياق التطوير لنظام Android ، فإننا ندعوك لزيارة مكتب ياندكس بطرسبرغ في 18 أبريل.


  2. لقد تحدثنا مؤخرًا عن حل مشكلة أخرى لمستخدمي البريد - مشكلات البريد.


Source: https://habr.com/ru/post/ar446780/


All Articles