📜 ⬆️ ⬇️

Pitfalls of custom CSS properties

Stas Melnikov, the author of the course on Netology “HTML-layout”, told about nuances that can complicate working with custom CSS properties.

Custom property name syntax rules


We are used to the fact that inline CSS properties are case insensitive. Therefore, the following methods of declaring the border property will give the same result:

 button { BORDER: 2px solid #800080; } button { border: 2px solid #800080; } 

User properties, on the other hand, are case-sensitive, so the following example creates two different user properties:
')
 button { --NETOLOGY-BRAND-COLOR: #800080; --netology-brand-color: #27ae60;   border: 2px solid var(--NETOLOGY-BRAND-COLOR); color: var(--netology-brand-color); } 



Now the frame has become the color # 800080 (purple), and the text color is # 27ae60 (green).

Valid values ​​for custom properties


With a regular CSS property, you can only set the standard allowed values. According to the custom properties standard, any existing valid CSS value can be used as a value. For example, like all the following custom properties:

 .element::before { --color: rgba(0, 0, 0, 1); --hex: #000000; --value: 20px; --number: 3; --text: "Hey, what's up?"; --keyword: currentColor; } 

For example, set the frame with color # 800080 for the button:

 button { --netologyBrandColor: #800080; border-width: 2px; border-style: solid; border-color: var(--netologyBrandColor); } 



In addition to the standard values, you can set one custom property as a value for another.

 button { --netologyBrandColor: #800080; --buttonBorderColor: var(--netologyBrandColor); border-width: 2px; border-style: solid; border-color: var(--buttonBorderColor); } 

The result is nothing different from the previous one, and the button still has a frame with color # 800080.

If the custom property --netologyBrandColor has an incorrect value for the border-color property, such as 18px, the frame will turn black.

 button { --netologyBrandColor: 18px;  --buttonBorderColor: var(--netologyBrandColor); border-width: 2px; border-style: solid; border-color: var(--buttonBorderColor); } 



The fact is that before the browser applies the value of a custom property to the embedded property, it will check it for correctness. If the value is available for the embedded property, the browser will apply it. And if not, it will set the default value for the embedded property.

In our case, 18px is an incorrect value for the built-in border-color property, and therefore the browser will set the default value, that is, currentColor . This is very easy to verify by setting the color property to # 800080:

 button { --netologyBrandColor: 18px;  --buttonBorderColor: var(--netologyBrandColor); border-width: 2px; border-style: solid; border-color: var(--buttonBorderColor); color: #800080; } 



As you can see, the browser has applied the value # 800080 for the frame. In this example, I used the full syntax to set the frame. But we can use a short one, namely the border property.

 button { --netologyBrandColor: 18px;  --buttonBorderColor: var(--netologyBrandColor); border: 2px solid var(--buttonBorderColor); color: #800080; } 



Here we have another nuance. The standard has a separate section that describes the behavior of user properties in this situation. According to him, if the user property has an incorrect value for the built-in property, then this user property is not valid, so the browser will ignore the built-in property.

In our example, the built-in border property has a custom property --buttonBorderColor with an incorrect value of 18px as one of the values. According to the described algorithm, the browser simply ignored the border property, so the element disappeared from the frame.

Default value for custom properties


When we looked at an example with the var function, we used only one parameter — the name of the custom property.

 button { --netologyBrandColor: #800080; border: 2px solid var(--netologyBrandColor); color: var(--netologyBrandColor); } button:hover { --netologyBrandColor: #27ae60; } 

But besides it, the var function can take the second - the default value. To declare the default value, you need to put a comma after the name of the custom property and write the value itself.


When the browser realizes that the developer has not declared a value for a custom property, it uses the default value. For example, the value # 800080 (purple) for the user property - --netologyBrandColor .

 button { border: 2px solid var(--netologyBrandColor, #800080); color: var(--netologyBrandColor, #800080); } button:hover { --netologyBrandColor: #27ae60; } 



We see that the frame and the text are purple. But if you hover the button, they will turn green. This suggests that the browser has applied the value of # 27ae60 to the custom property, thereby replacing the default value.

But this is not all the features of the var function. In the previous example, the custom property - --netologyBrandColor used twice, respectively, so I set the default value twice.

But it can be done differently. The var function allows you to pass another var function, so you can set a different custom property as the default value. I will rewrite the previous example using the custom property --defaultButtonColor :

 button { --defaultButtonColor: #800080; border: 2px solid var(--netologyBrandColor, var(--defaultButtonColor)); color: var(--netologyBrandColor, var(--defaultButtonColor)); } button:hover { --netologyBrandColor: #27ae60; } 

Externally, the result will not change. But now to change the default value, you need to do it only in one place, and not in several, as before.

Inheriting custom properties


CSS has an inheritance mechanism that allows elements to inherit properties on parent elements. In this regard, custom properties are no different from them. For example, I'll write the code in which the custom property - --netologyBrandColor inherited from the parent body element.

 body { --netologyBrandColor: #800080; } button { border: 2px solid var(--netologyBrandColor); color: var(--netologyBrandColor); } </td></tr> 



Looking at the inspector, you can see the inscription "Inherited from body", which shows us that the custom property was taken from the body element. But if you add the custom property - --netologyBrandColor for the button element, then it will already block the property from the body element.

 body { --netologyBrandColor: #800080; } button { --netologyBrandColor: #27ae60; border: 2px solid var(--netologyBrandColor); color: var(--netologyBrandColor); } 



In the inspector, you can see that the user property - --netologyBrandColor at the button element overrides the property - --netologyBrandColor , which we specified for the body element.

Global values


The CSS Custom Properties standard introduced a special pseudo-class root , which allows you to specify custom properties that apply to the root element of the document. For example, in the HTML document for the html element.

 :root { --netologyBrandColor: #800080; } button { border: 2px solid var(--netologyBrandColor); color: var(--netologyBrandColor); } 



In the inspector, we can see that the declared custom property applies to the html element. But besides the HTML document, the root pseudo- root works in SVG documents. For example, I will declare custom properties in the style tag.

 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 28" width="50" height="50">   <style>       :root{           --iconColor: #ffcc00;           --iconStroke: #000000;           --iconStrokeWidth: 2px;       }   </style>   <path stroke="var(--iconStroke)"         stroke-width="var(--iconStrokeWidth)"         fill="var(--iconColor)"         d="M26 10.109c0 .281-.203.547-.406.75l-5.672 5.531 1.344 7.812c.016.109.016.203.016.313 0 .406-.187.781-.641.781a1.27 1.27 0 0 1-.625-.187L13 21.422l-7.016 3.687c-.203.109-.406.187-.625.187-.453 0-.656-.375-.656-.781 0-.109.016-.203.031-.313l1.344-7.812L.39 10.859c-.187-.203-.391-.469-.391-.75 0-.469.484-.656.875-.719l7.844-1.141 3.516-7.109c.141-.297.406-.641.766-.641s.625.344.766.641l3.516 7.109 7.844 1.141c.375.063.875.25.875.719z"/> </svg> 



And here we see that the root element of the SVG element has a pseudo-class root . Accordingly, this proves that the pseudo-class root applies not only to the html tag, but to any root element.

Conclusion


In this article, we met with the pitfalls of custom properties that can be confusing. And accordingly, we can begin to use them. Therefore, in the next article I will talk about practical tricks that I use in my projects.

From the Editor


Courses "Netology" on the topic:

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


All Articles