كيف جعلنا أصدقاء SCSS مع متغيرات CSS باستخدام سمة UI Kit


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


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



المشكلة


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


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


كانت الحجة بسيطة: لقد استغرق تصميم طقم UI 200 ساعة من تصميم UX وأكثر من 500 ساعة من التطوير. هذا هو الوقت اللازم لإنشاء نظام من الخطوط والألوان وحوالي 10 مكونات أساسية. وفقًا لذلك ، إذا كنت تكتب مكتبة منفصلة لكل منتج ، فستقضي الشركة N * 500 ساعة من وقت التطوير. لقد اعتقدنا أن تحسين مجموعة أدوات واجهة المستخدم الخاصة بنا سيكون أرخص ، بالإضافة إلى أن هذه الخطوة لن تتكرر لكل منتج.


تم قبول حججنا ، ووافقت المجالات ذات الصلة على الانتظار ، وانطلقنا للبحث عن حل تقني.


مصدر البيانات


أدواتنا: الزاوي ، SCSS.


نحن ندعم المتصفحات الحديثة فقط ، مع بعض القيود ، IE11. مما يجعل الحياة أسهل.


تم تشبع جميع مكونات مجموعة أدوات واجهة المستخدم الخاصة بنا بأساليب شائعة قمنا UI kit.var.scss في UI kit.var.scss باعتبارها ثوابت UI kit.var.scss :


 @mixin fontSizeXl { @include fontSize(18px, 26px); } $colorSkillListening: #9679e0; $colorSkillListeningText: #7754d1; $colorSkillListeningBackground: mix($colorSkillListening, #ffffff, 16%); $colorSkillListeningBackgroundHover: mix($colorSkillListening, #ffffff, 8%); 

مهمة


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

دعنا نذهب!


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


المواد الزاوي


لا نرغب في كتابة الدراجات ، لذلك انتقلنا أولاً إلى Angular Material. في المكونات ، يتم نقل الأنماط الديناميكية إلى ملف منفصل {component}-theme.scss . ترتبط هذه الأنماط بالمحدد العام للمكون.


الايجابياتسلبيات
لا حاجة لإضافة تقنيات جديدة للمشروعبحاجة إلى إجراء تغييرات على كل مكون
أكبر قدر من العمل
تضطر إلى التضحية نمط التغليف

متغيرات CSS


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


الايجابياتسلبيات
تمتلك النطاقيجب أن تضيف polyfill ل IE
تقنية المتصفح الأصلي (باستثناء IE)لن نتمكن من استخدام وظائف SCSS
يفتح إمكانية استخدام فرس CSS في مهام أخرى

يبني العرف


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


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

قرار


لمدة أسبوع درسنا كل خيار ، وناقشنا ، وأرجأنا القرار ، ودرسنا مرة أخرى.


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


فهم المغلق ضد SCSS


بعد أن جربنا ذلك ، أدركنا أن المشكلة الرئيسية هي عدم وجود دعم لـ # hex في CSS: في rgba(#ffffff, 0.4) نكتب rgba(#ffffff, 0.4) ، وفي CSS نفس الشيء يتطلب مجموعة مختلفة من المعلمات - rgba(255, 255, 255, 0.4) . كل شيء يناسبنا مع # hex ، ونحن في الحقيقة ، لا نريد تغيير هذا. لقد وجدنا حلولاً ، سأقول بترتيب القبول.


تفتيح وتغميق


جاء مصممنا بلوحة تتألف من عدد صغير من الألوان الأساسية ، تتوسع نظرًا لوظائف SCSS المظلمة darken :


 // $color –   base: $color, background: mix($color, #ffffff, 16%), backgroundHover: mix($color, #ffffff, 8%), hover: lighten($color, 5), focused: darken($color, 5), ...more transformations... 

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


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


 @function getMainColors($color, $colorText) { $colors: ( text: $colorText, base: $color, background: mix($color, #ffffff, 16%), backgroundHover: mix($color, #ffffff, 8%), lightenLess: lighten($color, 5), darkenLess: darken($color, 5), lightenMore: lighten($color, 20), ); @return $colors; } 

النظام الأساسي يستخدمه عند تهيئة الألوان:


 //platform $colorValues: ( brand: getMainColors(#5d9cec, #4287df), positive: getMainColors(#8cc152, #55a900), accent: getMainColors(#ff3d6f, #ff255d), wrong: getMainColors(#ff6666, #fe4f44), ) 

RGBA


في مجموعة واجهة المستخدم الخاصة بنا ، نستخدم وظيفة rgba . مع ذلك ، نقوم بضبط شفافية الألوان الأساسية. ولكن إذا كان rgba يعمل مع # hex في SCSS ، فلن يتمكن CSS من ذلك. اضطررت إلى كتابة دالة تقوم بتحليل قيمة # hex إلى r / g / b:


 // returns `r, g, b` from `#hex` for `rgba(var(--smth))` usage @function rgbValuesFromHex($hex) { @return red($hex), green($hex), blue($hex); } 

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


 // adds `fieldRgb: r, g, b` fields to map for each `field: #hex` for `rgba(var(--smth-rgb))` usage @function withRgbValues($map) { $rgbValues: (); @each $name, $value in $map { $formattedValue: (); @if type-of($value) == 'map' { $rgbValues: map-merge($rgbValues, (#{$name}: withRgbValues($value))); } @else { //   , rgb    Rgb   $rgbValues: map-merge($rgbValues, (#{$name}Rgb: rgbValuesFromHex($value))); } } @return map-merge($map, $rgbValues); } 

نتيجة لذلك ، فإن تهيئة اللوحة مع قيم RGB التي تم إنشاؤها تبدو كما يلي:


 $colorValues: withRgbValues( ( text: ( base: #242d34, secondary: #50575c, label: #73797d, placeholder: #969b9e, inversed: #ffffff, inversedSecondary: #dadada, ), brand: getMainColors(#5d9cec, #4287df), positive: getMainColors(#8cc152, #55a900), accent: getMainColors(#ff3d6f, #ff255d), wrong: getMainColors(#ff6666, #fe4f44), //...etc 

الإخراج هو خريطة ألوان SCSS ، والتي يمكن بعد ذلك تحويلها إلى طريقة تحولها إلى متغيرات CSS. من أجل الحصول على القيمة من سمة RGB ، كتبنا دالة:


 @function getUiKitRgbVar($path...) { $path: set-nth($path, -1, #{nth($path, -1)}Rgb); //       @return getFromMap($uiKitBaseVars, $path...); } //  border-color: rgba(getUiKitRgbVar(color, brand, base), $opacity64); 

تحويل SCSS const إلى VSS CSS


تتمثل الخطوة الأولى في إنشاء بنية متطابقة (على غرار SCSS) تخزن أسماء متغيرات CSS:


 $colorCssVars: withRgbCssVars( ( text: ( base: getColorCssVar(text, base), secondary: getColorCssVar(text, secondary), label: getColorCssVar(text, label), placeholder: getColorCssVar(text, placeholder), inversed: getColorCssVar(text, inversed), //   

getColorCssVar - طريقة تضيف البادئات إلى أسماء المتغيرات. أضف بادئة --sky لتجنب الاصطدامات مع المكتبات الخارجية. وأيضًا إضافة بادئة مكتبة - UI kit إلى --sky لتجنب التعارضات مع المكتبات الداخلية. اتضح - --sky- UI kit :


 @function getColorCssVar($parts...) { @return getUiKitCssVar(color, $parts...); } @function getUiKitCssVar($parts...) { $uiKitCssVarPrefix: '--sky- UI kit'; $cssVar: $uiKitCssVarPrefix; @each $part in $parts { $cssVar: $cssVar + '-' + $part; } @return $cssVar; } 

على سبيل المثال ، بالنسبة إلى getColorCssVar(text, base) نحصل على --sky- UI kit-color-text-base في الإخراج.


اللمسة الأخيرة عبارة عن مزيج متكرر يعمل على تهيئة القيم من بنية SCSS إلى المتغيرات بأسماء من بنية CSS Var:


 //       :root { @include uiKitThemeCssVars($uiKitDefaultTheme); //uiKitDefaultTheme – SCSS       } @mixin uiKitThemeCssVars($theme) { $cssVarsList: createVarsList($theme, $uiKitBaseCssVars); //18+,    Map  List, $uiKitBaseCssVars   css  @each $cssVar, $value in $cssVarsList { #{$cssVar}: $value; } } 

مثال على استخدام سمة على النظام الأساسي:


 .popup { font-family: getUiKitVar(font, family); background-color: getUiKitVar(color, background, base); ... } 

ما هي النتيجة


تمكنا من استخدام متغيرات CSS ، مع الحفاظ على القدرة على استخدام وظائف SCSS. خلق القدرة على تخصيص مظهر المكونات. لقد كتبنا عدة طرق متكررة لأتمتة تمديد الموضوع. حسنًا والأهم من ذلك - أنفق 30 ساعة من التطوير بدلاً من 500 *.


الربح!

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


All Articles