حان الوقت لبدء استخدام خصائص CSS المخصصة

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

نستخدم معالجات أولية لتخزين الألوان وتفضيلات الخطوط وتفاصيل التخطيط - في الغالب كل شيء نستخدمه في CSS.

مقدمة مفصلة للعناصر المخصصة

ربما تكون قد سمعت عن مكونات الويب وكيف أنها ستغير تطوير الويب إلى الأبد. أكثر التقنيات تحويلية هي Custom Elements ، وهي طريقة لتعريف العناصر الخاصة بك بسلوكها وخصائصها. اقرأ المقدمة →

لكن متغيرات المعالج المسبق لها بعض القيود:

  • لا يمكنك تغييرها ديناميكيًا.
  • إنهم ليسوا على دراية بهيكلية DOM.
  • لا يمكن قراءتها أو تغييرها من JavaScript.

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

الخصائص المخصصة تفتح آفاقًا جديدة لتطوير الويب.

المزيد بعد القفز! أكمل القراءة أدناه ↓

بناء الجملة للإعلان عن واستخدام الخصائص المخصصة

المشكلة المعتادة عندما تبدأ بمعالج أو إطار عمل جديد هي أنه عليك تعلم بناء جملة جديد.

يتطلب كل معالج مسبق طريقة مختلفة للتصريح عن المتغيرات. عادة ، يبدأ برمز محجوز - على سبيل المثال ، $ in Sass و @ in LESS.

سارت خصائص CSS المخصصة بنفس الطريقة واستخدمت -​- لتقديم إعلان. ولكن الشيء الجيد هنا هو أنه يمكنك تعلم بناء الجملة هذا مرة واحدة وإعادة استخدامه عبر المتصفحات!

قد تسأل ، "لماذا لا تعيد استخدام بناء جملة موجود؟"

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

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

لذلك ، للإعلان عن متغير بدلاً من خاصية CSS المعتادة مثل color أو padding ، ما عليك سوى توفير خاصية مسماة مخصصة تبدأ بـ -​- :

 .box{ --box-color: #4d4e53; --box-padding: 0 10px; }

قد تكون قيمة الخاصية أي قيمة CSS صالحة: لون ، سلسلة ، قيمة تخطيط ، حتى تعبير.

فيما يلي أمثلة على الخصائص المخصصة الصالحة:

 :root{ --main-color: #4d4e53; --main-bg: rgb(255, 255, 255); --logo-border-color: rebeccapurple; --header-height: 68px; --content-padding: 10px 20px; --base-line-height: 1.428571429; --transition-duration: .35s; --external-link: "external link"; --margin-top: calc(2vh + 20px); /* Valid CSS custom properties can be reused later in, say, JavaScript. */ --foo: if(x > 5) this.width = 10; }

في حال لم تكن متأكدًا مما :root ، في HTML ، فهو مماثل لـ html ولكن مع دقة أعلى.

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

لاستخدام متغير ، عليك استخدام دالة var() CSS وتقديم اسم الخاصية بداخلها:

 .box{ --box-color:#4d4e53; --box-padding: 0 10px; padding: var(--box-padding); } .box div{ color: var(--box-color); }

حالات الإعلان والاستخدام

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

 .box{ --box-color:#4d4e53; --box-padding: 0 10px; /* 10px is used because --box-margin is not defined. */ margin: var(--box-margin, 10px); }

كما قد تتوقع ، يمكنك إعادة استخدام متغيرات أخرى للإعلان عن متغيرات جديدة:

 .box{ /* The --main-padding variable is used if --box-padding is not defined. */ padding: var(--box-padding, var(--main-padding)); --box-text: 'This is my box'; /* Equal to --box-highlight-text:'This is my box with highlight'; */ --box-highlight-text: var(--box-text)' with highlight'; }

العمليات: + ، - ، * ، /

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

 :root{ --indent-size: 10px; --indent-xl: calc(2*var(--indent-size)); --indent-l: calc(var(--indent-size) + 2px); --indent-s: calc(var(--indent-size) - 2px); --indent-xs: calc(var(--indent-size)/2); }

تنتظرك مشكلة إذا حاولت استخدام قيمة أقل من وحدة. مرة أخرى ، calc() هو صديقك ، لأنه بدونه ، لن يعمل:

 :root{ --spacer: 10; } .box{ padding: var(--spacer)px 0; /* DOESN'T work */ padding: calc(var(--spacer)*1px) 0; /* WORKS */ }

النطاق والميراث

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

نحن نعلم أنه باستخدام متغيرات JavaScript ( var ) ، على سبيل المثال ، يقتصر النطاق على الوظائف.

لدينا موقف مماثل مع let و const ، لكنهما متغيرات محلية في نطاق الكتلة.

closure في JavaScript هو وظيفة لها حق الوصول إلى متغيرات الوظيفة الخارجية (التضمين) - سلسلة النطاق. يحتوي الإغلاق على ثلاث سلاسل نطاقات ، ولديه إمكانية الوصول إلى ما يلي:

  • نطاقه الخاص (أي المتغيرات المحددة بين أقواسها) ،
  • متغيرات الوظيفة الخارجية ،
  • المتغيرات العالمية.

(عرض النسخة الكبيرة)

القصة مع المعالجين متشابهة. دعنا نستخدم Sass كمثال لأنه ربما يكون المعالج المسبق الأكثر شعبية اليوم.

مع Sass ، لدينا نوعان من المتغيرات: المحلية والعالمية.

يمكن الإعلان عن المتغير الشامل خارج أي محدد أو بناء (على سبيل المثال ، كمزيج). خلاف ذلك ، سيكون المتغير محليًا.

يمكن لأي كتل متداخلة من التعليمات البرمجية الوصول إلى المتغيرات المضمنة (كما في JavaScript).

(عرض النسخة الكبيرة)

هذا يعني أن نطاقات المتغير في Sass تعتمد بشكل كامل على بنية الكود.

ومع ذلك ، فإن خصائص CSS المخصصة يتم توارثها افتراضيًا ، ومثل خصائص CSS الأخرى ، فإنها تتتالي.

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

دعنا نستخدم معرفتنا اللغوية ونكيف مثال Sass مع HTML و CSS. سننشئ عرضًا توضيحيًا باستخدام خصائص CSS المخصصة الأصلية. أولاً ، HTML:

 global <div class="enclosing"> enclosing <div class="closure"> closure </div> </div>

وهنا CSS:

 :root { --globalVar: 10px; } .enclosing { --enclosingVar: 20px; } .enclosing .closure { --closureVar: 30px; font-size: calc(var(--closureVar) + var(--enclosingVar) + var(--globalVar)); /* 60px for now */ } 

راجع Pen css-custom-properties-time-to-start-using 1 بواسطة Serg Hospodarets (malyw) على CodePen.

راجع Pen css-custom-properties-time-to-start-using 1 بواسطة Serg Hospodarets (malyw) على CodePen.

يتم تطبيق التغييرات التي تم إجراؤها على الخصائص المخصصة على الفور على كافة المثيلات

حتى الآن ، لم نر كيف يختلف هذا عن متغيرات Sass. ومع ذلك ، دعونا نعيد تعيين المتغير بعد استخدامه:

في حالة Sass ، ليس لهذا أي تأثير:

 .closure { $closureVar: 30px; // local variable font-size: $closureVar +$enclosingVar+ $globalVar; // 60px, $closureVar: 30px is used $closureVar: 50px; // local variable } 

راجع Pen css-custom-properties-time-to-start-using 3 بواسطة Serg Hospodarets (malyw) على CodePen.

راجع Pen css-custom-properties-time-to-start-using 3 بواسطة Serg Hospodarets (malyw) على CodePen.

لكن في CSS ، يتم تغيير القيمة المحسوبة ، لأن قيمة font-size يُعاد حسابها من قيمة تغيير –closureVar :

 .enclosing .closure { --closureVar: 30px; font-size: calc(var(--closureVar) + var(--enclosingVar) + var(--globalVar)); /* 80px for now, --closureVar: 50px is used */ --closureVar: 50px; } 

راجع Pen css-custom-properties-time-to-start-using 2 بواسطة Serg Hospodarets (malyw) على CodePen.

راجع Pen css-custom-properties-time-to-start-using 2 بواسطة Serg Hospodarets (malyw) على CodePen.

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

المعالجات الأولية ليست على دراية بهيكل DOM

لنفترض أننا أردنا استخدام font-size الافتراضي للكتلة ، باستثناء مكان highlighted الفئة المميزة.

هنا HTML:

 <div class="default"> default </div> <div class="default highlighted"> default highlighted </div>

لنفعل ذلك باستخدام خصائص CSS المخصصة:

 .highlighted { --highlighted-size: 30px; } .default { --default-size: 10px; /* Use default-size, except when highlighted-size is provided. */ font-size: var(--highlighted-size, var(--default-size)); }

نظرًا لأن عنصر HTML الثاني الذي يحتوي highlighted الفئة default يحمل الفئة المميزة ، فسيتم تطبيق الخصائص من الفئة المميزة highlighted هذا العنصر.

في هذه الحالة ، فهذا يعني أن –highlighted-size: 30px; سيتم تطبيقه ، والذي بدوره سيجعل خاصية font-size يتم تعيينها تستخدم –highlighted-size .

كل شيء مباشر ويعمل:

راجع Pen css-custom-properties-time-to-start-using 4 بواسطة Serg Hospodarets (malyw) على CodePen.

راجع Pen css-custom-properties-time-to-start-using 4 بواسطة Serg Hospodarets (malyw) على CodePen.

الآن ، دعنا نحاول تحقيق نفس الشيء باستخدام Sass:

 .highlighted { $highlighted-size: 30px; } .default { $default-size: 10px; /* Use default-size, except when highlighted-size is provided. */ @if variable-exists(highlighted-size) { font-size: $highlighted-size; } @else { font-size: $default-size; } }

تظهر النتيجة أن الحجم الافتراضي يتم تطبيقه على كليهما:

راجع Pen css-custom-properties-time-to-start-using 5 بواسطة Serg Hospodarets (malyw) على CodePen.

راجع Pen css-custom-properties-time-to-start-using 5 بواسطة Serg Hospodarets (malyw) على CodePen.

يحدث هذا لأن جميع حسابات Sass ومعالجتها تحدث في وقت التجميع ، وبالطبع لا يعرف أي شيء عن بنية DOM ، حيث يعتمد بشكل كامل على بنية الكود.

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

الخلاصة الثانية هي أن خصائص CSS المخصصة تدرك بنية DOM وديناميكية .

الكلمات الرئيسية على مستوى CSS all الممتلكات

تخضع خصائص CSS المخصصة لنفس القواعد مثل خصائص CSS المخصصة المعتادة. هذا يعني أنه يمكنك تعيين أي من الكلمات الأساسية الشائعة لـ CSS لها:

  • inherit
    تطبق الكلمة الأساسية CSS هذه قيمة أصل العنصر.
  • initial
    يتم تطبيق القيمة الأولية على النحو المحدد في مواصفات CSS (قيمة فارغة ، أو لا شيء في بعض حالات خصائص CSS المخصصة).
  • unset
    يطبق هذا القيمة الموروثة إذا كانت الخاصية موروثة بشكل طبيعي (كما في حالة الخصائص المخصصة) أو القيمة الأولية إذا لم يتم توريث الخاصية بشكل طبيعي.
  • revert
    يؤدي هذا إلى إعادة تعيين الخاصية إلى القيمة الافتراضية المحددة بواسطة ورقة أنماط وكيل المستخدم (قيمة فارغة في حالة خصائص CSS المخصصة).

هنا مثال:

 .common-values{ --border: inherit; --bgcolor: initial; --padding: unset; --animation: revert; }

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

ولكن هناك الآن طريقة أخرى: لاستخدام خاصية all CSS. هذا الاختصار يعيد تعيين جميع خصائص CSS.

جنبًا إلى جنب مع كلمات CSS الأساسية ، يمكننا القيام بما يلي:

 .my-wonderful-clean-component{ all: initial; }

هذا يعيد تعيين جميع الأنماط لمكوننا.

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

لذلك ، في المستقبل ، قد يتم إجراء إعادة تعيين كاملة على النحو التالي:

 .my-wonderful-clean-component{ --: initial; /* reset all CSS custom properties */ all: initial; /* reset all other CSS styles */ }

حالات استخدام خصائص CSS المخصصة

هناك العديد من الاستخدامات للخصائص المخصصة. سأعرض أكثرهم إثارة للاهتمام.

محاكاة قواعد CSS غير الموجودة

اسم متغيرات CSS هذه هو "خصائص مخصصة" ، فلماذا لا نستخدمها لمحاكاة الخصائص غير الموجودة؟

هناك الكثير منها: translateX/Y/Z ، background-repeat-x/y (لا تزال غير متوافقة مع المستعرضات) ، box-shadow-color .

دعنا نحاول جعل آخر واحد يعمل. في مثالنا ، دعنا نغير لون box-shadow عند التحويم. نريد فقط اتباع قاعدة DRY (لا تكرر نفسك) ، لذلك بدلاً من تكرار قيمة box-shadow بالكامل في قسم :hover ، سنقوم فقط بتغيير لونه. خصائص مخصصة للإنقاذ:

 .test { --box-shadow-color: yellow; box-shadow: 0 0 30px var(--box-shadow-color); } .test:hover { --box-shadow-color: orange; /* Instead of: box-shadow: 0 0 30px orange; */ } 

راجع خاصية Pen Emulating "box-shadow-color" CSS باستخدام خصائص CSS المخصصة بواسطة Serg Hospodarets (malyw) على CodePen.

راجع خاصية Pen Emulating "box-shadow-color" CSS باستخدام خصائص CSS المخصصة بواسطة Serg Hospodarets (malyw) على CodePen.

ثيمات اللون

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

هذا هو رمز مكون الزر الخاص بنا:

 .btn { background-image: linear-gradient(to bottom, #3498db, #2980b9); text-shadow: 1px 1px 3px #777; box-shadow: 0px 1px 3px #777; border-radius: 28px; color: #ffffff; padding: 10px 20px 10px 20px; }

لنفترض أننا نريد قلب سمة اللون.

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

 .btn { --shadow-color: #777; --gradient-from-color: #3498db; --gradient-to-color: #2980b9; --color: #ffffff; background-image: linear-gradient( to bottom, var(--gradient-from-color), var(--gradient-to-color) ); text-shadow: 1px 1px 3px var(--shadow-color); box-shadow: 0px 1px 3px var(--shadow-color); border-radius: 28px; color: var(--color); padding: 10px 20px 10px 20px; }

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

 body.inverted .btn{ --shadow-color: #888888; --gradient-from-color: #CB6724; --gradient-to-color: #D67F46; --color: #000000; }

يوجد أدناه عرض توضيحي يمكنك من خلاله النقر فوق الزر لإضافة فصل دراسي عالمي وإزالته:

راجع Pen css-custom-properties-time-to-start-using 9 بواسطة Serg Hospodarets (malyw) على CodePen.

راجع Pen css-custom-properties-time-to-start-using 9 بواسطة Serg Hospodarets (malyw) على CodePen.

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

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

استخدام الخصائص المخصصة مع JavaScript

في السابق ، لإرسال البيانات من CSS إلى JavaScript ، غالبًا ما كان علينا اللجوء إلى الحيل ، وكتابة قيم CSS عبر JSON العادي في إخراج CSS ثم قراءتها من JavaScript.

الآن ، يمكننا التفاعل بسهولة مع متغيرات CSS من JavaScript ، والقراءة والكتابة لهم باستخدام .getPropertyValue() و .setProperty() ، والتي تستخدم لخصائص CSS المعتادة:

 /** * Gives a CSS custom property value applied at the element * element {Element} * varName {String} without '--' * * For example: * readCssVar(document.querySelector('.box'), 'color'); */ function readCssVar(element, varName){ const elementStyles = getComputedStyle(element); return elementStyles.getPropertyValue(`--${varName}`).trim(); } /** * Writes a CSS custom property value at the element * element {Element} * varName {String} without '--' * * For example: * readCssVar(document.querySelector('.box'), 'color', 'white'); */ function writeCssVar(element, varName, value){ return element.style.setProperty(`--${varName}`, value); }

لنفترض أن لدينا قائمة بقيم استعلام الوسائط:

 .breakpoints-data { --phone: 480px; --tablet: 800px; }

نظرًا لأننا نريد إعادة استخدامها فقط في JavaScript - على سبيل المثال ، في Window.matchMedia () - يمكننا الحصول عليها بسهولة من CSS:

 const breakpointsData = document.querySelector('.breakpoints-data'); // GET const phoneBreakpoint = getComputedStyle(breakpointsData) .getPropertyValue('--phone');

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

ليس من الصعب جدا. نحتاج فقط إلى إضافة خلفية بسيطة ، ثم وضع خمسة أوجه مكعب مع القيم ذات الصلة لخاصية transform : translateZ() ، translateY() ، rotateX() and rotateY() .

لتوفير المنظور الصحيح ، أضفت ما يلي إلى غلاف الصفحة:

 #world{ --translateZ:0; --rotateX:65; --rotateY:0; transform-style:preserve-3d; transform: translateZ(calc(var(--translateZ) * 1px)) rotateX(calc(var(--rotateX) * 1deg)) rotateY(calc(var(--rotateY) * 1deg)); }

الشيء الوحيد المفقود هو التفاعل. يجب أن يغير العرض التوضيحي زوايا العرض X و Y (– –rotateX و – –rotateY ) عندما يتحرك الماوس ويجب أن يقوم بالتكبير والتصغير عند تمرير الماوس ( –translateZ ).

ها هي JavaScript التي تقوم بالخدعة:

 // Events onMouseMove(e) { this.worldXAngle = (.5 - (e.clientY / window.innerHeight)) * 180; this.worldYAngle = -(.5 - (e.clientX / window.innerWidth)) * 180; this.updateView(); }; onMouseWheel(e) { /*…*/ this.worldZ += delta * 5; this.updateView(); }; // JavaScript -> CSS updateView() { this.worldEl.style.setProperty('--translateZ', this.worldZ); this.worldEl.style.setProperty('--rotateX', this.worldXAngle); this.worldEl.style.setProperty('--rotateY', this.worldYAngle); };

الآن ، عندما يحرك المستخدم الماوس ، يغير العرض التوضيحي العرض. يمكنك التحقق من ذلك عن طريق تحريك الماوس واستخدام عجلة الماوس للتكبير والتصغير:

راجع Pen css-custom-properties-time-to-start-using 10 بواسطة Serg Hospodarets (malyw) على CodePen.

راجع Pen css-custom-properties-time-to-start-using 10 بواسطة Serg Hospodarets (malyw) على CodePen.

بشكل أساسي ، لقد قمنا للتو بتغيير قيم خصائص CSS المخصصة. كل شيء آخر (التدوير والتكبير والتصغير) يتم بواسطة CSS.

نصيحة: من أسهل الطرق لتصحيح أخطاء قيمة خاصية مخصصة لـ CSS هي إظهار محتوياتها في محتوى CSS الذي تم إنشاؤه (والذي يعمل في حالات بسيطة ، مثل السلاسل) ، بحيث يعرض المتصفح تلقائيًا القيمة المطبقة الحالية:

 body:after { content: '--screen-category : 'var(--screen-category); }

يمكنك التحقق من ذلك في عرض CSS العادي (بدون HTML أو JavaScript). (قم بتغيير حجم النافذة لرؤية المتصفح يعكس قيمة خاصية CSS المخصصة التي تم تغييرها تلقائيًا.)

دعم المتصفح

خصائص CSS المخصصة مدعومة في جميع المتصفحات الرئيسية:

(عرض النسخة الكبيرة)

هذا يعني أنه يمكنك البدء في استخدامها محليًا.

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

بالطبع ، نحتاج إلى أن نكون قادرين على اكتشاف الدعم في كل من CSS و JavaScript من أجل توفير احتياطيات أو تحسينات.

هذا سهل للغاية. بالنسبة إلى CSS ، يمكنك استخدام شرط @supports مع استعلام ميزة وهمية:

 @supports ( (--a: 0)) { /* supported */ } @supports ( not (--a: 0)) { /* not supported */ }

في JavaScript ، يمكنك استخدام نفس الخاصية المخصصة الوهمية مع الأسلوب الثابت CSS.supports() :

 const isSupported = window.CSS && window.CSS.supports && window.CSS.supports('--a', 0); if (isSupported) { /* supported */ } else { /* not supported */ }

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

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

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

 <!-- HTML --> <link href="without-css-custom-properties.css" rel="stylesheet" type="text/css" media="all" />
 // JavaScript if(isSupported){ removeCss('without-css-custom-properties.css'); loadCss('css-custom-properties.css'); // + conditionally apply some application enhancements // using the custom properties }

هذا مجرد مثال. كما سترى أدناه ، هناك خيارات أفضل.

كيف تبدأ في استخدامها

وفقًا لمسح حديث ، لا تزال Sass هي المعالج الأول المفضل لمجتمع التنمية.

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

لدينا بعض الخيارات.

1. تحقق يدويًا من رمز الدعم

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

 $color: red; :root { --color: red; } .box { @supports ( (--a: 0)) { color: var(--color); } @supports ( not (--a: 0)) { color: $color; } }

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

2. استخدم مكونًا إضافيًا يعالج CSS الناتج تلقائيًا

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

مثال على ذلك postcss-custom-properties.

يقدم هذا البرنامج المساعد العديد من المزايا: فهو يجعل بناء الجملة يعمل ؛ متوافق مع جميع البنية التحتية لـ PostCSS ؛ ولا يتطلب الكثير من التكوين.

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

3. css-vars Mixin

لقد بدأت في استخدام خصائص CSS المخصصة في معظم مشاريعي وجربت العديد من الاستراتيجيات:

  • قم بالتبديل من Sass إلى PostCSS باستخدام cssnext.
  • قم بالتبديل من متغيرات Sass إلى خصائص CSS المخصصة الخالصة.
  • استخدم متغيرات CSS في Sass لاكتشاف ما إذا كانت مدعومة أم لا.

نتيجة لتلك التجربة ، بدأت في البحث عن حل يلبي معياري:

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

نتيجة لذلك ، قمت بإنشاء css-vars ، مزيج Sass الذي يمكنك العثور عليه على Github. باستخدامه ، يمكنك نوعًا من البدء في استخدام بناء جملة خصائص CSS المخصصة.

باستخدام css-vars Mixin

للإعلان عن المتغير (المتغيرات) ، استخدم الاختلاط كما يلي:

 $white-color: #fff; $base-font-size: 10px; @include css-vars(( --main-color: #000, --main-bg: $white-color, --main-font-size: 1.5*$base-font-size, --padding-top: calc(2vh + 20px) ));

لاستخدام هذه المتغيرات ، استخدم الدالة var() :

 body { color: var(--main-color); background: var(--main-bg, #f00); font-size: var(--main-font-size); padding: var(--padding-top) 0 10px; }

يمنحك هذا طريقة للتحكم في جميع مخرجات CSS من مكان واحد (من Sass) والبدء في التعرف على بناء الجملة. بالإضافة إلى ذلك ، يمكنك إعادة استخدام متغيرات Sass والمنطق باستخدام mixin.

عندما تعمل جميع المتصفحات التي تريد دعمها مع متغيرات CSS ، فكل ما عليك فعله هو إضافة هذا:

 $css-vars-use-native: true;

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

إذا كنت تريد تشغيل معلومات تصحيح الأخطاء المفيدة ، فأضف ما يلي:

 $css-vars-debug-log: true;

سيعطيك هذا:

  • سجل عندما لم يتم تعيين متغير ولكن تم استخدامه ؛
  • سجل عند إعادة تعيين متغير ؛
  • المعلومات عندما لا يتم تعريف متغير ولكن يتم تمرير القيمة الافتراضية التي يتم استخدامها بدلاً من ذلك.

خاتمة

أنت الآن تعرف المزيد عن خصائص CSS المخصصة ، بما في ذلك تركيبها ومزاياها وأمثلة الاستخدام الجيد وكيفية التفاعل معها من JavaScript.

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

هذا هو الوقت المناسب لبدء استخدام خصائص CSS المخصصة والاستعداد لدعمها الأصلي في المتصفحات.