自定义CSS属性的陷阱

HTML HTML Layout课程的作者Stas Melnikov谈到了使自定义CSS属性复杂化的细微差别。

自定义属性名称语法规则


我们习惯于内联CSS属性不区分大小写的事实。 因此,以下声明border属性的方法将得到相同的结果:

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

相比之下,自定义属性区分大小写,因此以下示例创建两个不同的自定义属性:

 button { --NETOLOGY-BRAND-COLOR: #800080; --netology-brand-color: #27ae60;   border: 2px solid var(--NETOLOGY-BRAND-COLOR); color: var(--netology-brand-color); } 



现在,框架变为#800080(紫色),文本变为#27ae60(绿色)。

自定义属性的有效值


对于常规CSS属性,您只能设置标准允许的值。 根据自定义属性标准,任何现有的有效CSS值都可以用作值。 例如,与以下所有自定义属性一样:

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

例如,让我们为按钮设置颜色为#800080的框架:

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



除了标准值,您还可以将一个自定义属性设置为另一个的值。

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

结果与前一个没有什么不同,并且按钮仍然具有颜色为#800080的框架。

如果自定义属性--netologyBrandColorborder-color属性值不正确,例如18px,则框架将变为黑色。

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



事实是,在浏览器将用户属性的值应用于内置属性之前,它将检查它的正确性。 如果该值可用于inline属性,则浏览器将应用它。 如果不是,它将为内置属性设置默认值。

在我们的例子中,18px是内置的border-color属性的不正确值,因此浏览器将设置默认值,即currentColor 。 通过将color属性设置为#800080可以很容易地进行验证:

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



如您所见,浏览器为框架应用了值#800080。 在此示例中,我使用了完整的语法来设置框架。 但是我们可以使用一个简短的名称,即border属性。

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



在这里,我们正在等待另一个细微差别。 标准中有单独的部分描述了这种情况下自定义属性的行为。 据他介绍,如果用户属性的内联属性值不正确,则该用户属性无效,因此浏览器将忽略内联属性。

在我们的示例中,内置的border属性具有设置为自定义属性--buttonBorderColor的值之一,无效值为18px。 根据所描述的算法,浏览器只是忽略了border属性,因此元素丢失了边框。

自定义属性的默认值


当我们查看var函数示例时,我们仅使用了一个参数-自定义属性的名称。

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

但是除此之外, var函数可以接受第二个-默认值。 要声明默认值,您需要在自定义属性的名称后加上逗号,并写入值本身。


当浏览器意识到开发人员尚未为自定义属性声明值时,它将使用默认值。 例如,自定义属性的值#800080(紫色)是--netologyBrandColor

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



我们看到框架和文本变成紫色。 但是,如果您移动按钮,它们将变为绿色。 这表明浏览器将值#27ae60应用于用户属性,从而替换了默认值。

但这不是var函数的所有可能。 在上一个示例中,自定义属性--netologyBrandColor分别使用了两次,因此我将默认值设置了两次。

但是可以做的不同。 var函数允许您传递另一个var函数,因此可以将另一个自定义属性设置为默认值。 我将使用自定义属性--defaultButtonColor重写前面的示例:

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

从外部看,结果不会改变。 但是现在要更改默认值,您只需像以前一样在一个位置而不是多个位置执行此操作。

自定义属性的继承


CSS具有继承机制,该机制允许元素从父元素继承属性。 在这方面,定制属性与它们没有什么不同。 例如,我将编写代码,其中自定义属性--netologyBrandColor从父body元素继承的。

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



查看检查器,您会注意到题词“继承自body”,它向我们显示了custom属性是从body元素获取的。 但是,如果我们为button元素添加自定义属性--netologyBrandColor ,则它已经覆盖了body元素的属性。

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



检查器显示button元素的自定义属性--netologyBrandColor会覆盖我们为body元素指定的属性--netologyBrandColor

全球价值观


在CSS标准中,“自定义属性”引入了特殊的rootrootroot允许您指定应用于文档根元素的自定义属性。 例如,在HTML文档中的html元素。

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



在检查器中,我们可以看到已声明的custom属性已应用于html元素。 但是,除了HTML文档之外, rootroot可以在SVG文档中使用。 例如,我将在style标签中声明自定义属性。

 <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> 



在这里,我们看到根伪root已添加到SVG根元素中。 因此,这证明了根伪类不仅适用于html标签,而且适用于任何根元素。

结论


在本文中,我们遇到了可能令人困惑的自定义属性的陷阱。 因此,我们可以开始使用它们。 因此,在下一篇文章中,我将讨论在项目中使用的实用技巧。

来自编辑


有关该主题的网络学课程:

Source: https://habr.com/ru/post/zh-CN435654/


All Articles