• CSS 自定义属性(变量)


    CSS 自定义属性(变量)

    自定义属性标记设定值(比如: --main-color: black;),由 var() 函数来获取值(比如: color: var(--main-color);

    声明一个自定义属性,属性名需要以两个减号(--)开始,属性值则可以是任何有效的 CSS 值。和其他属性一样,自定义属性也是写在规则集之内的,如下:

    1. element {
    2. --main-bg-color: brown;
    3. }

    通常的最佳实践是定义在根伪类 :root 下,这样就可以在 HTML 文档的任何地方访问到它了:

    1. :root {
    2. --main-bg-color: brown;
    3. }

    如前所述,使用一个局部变量时用 var() 函数包裹以表示一个合法的属性值:

    1. element {
    2. background-color: var(--main-bg-color);
    3. }
    4. //用 var() 函数可以定义多个备用值(fallback value),当给定值未定义时将会用备用值替换
    5. //语法允许使用逗号。比如 var(--foo, red, blue) 定义了一个 red, blue 的备用值——从第一个逗号到最后的全部内容,都会被作为备用值的一部分。
    6. .three {
    7. background-color: var(--my-var, var(--my-background, pink)); /* pink if --my-var and --my-background are not defined */
    8. }
    9. .three {
    10. background-color: var(--my-var, --my-background, pink); /* Invalid: "--my-background, pink" */
    11. }

    备注: 自定义属性名是大小写敏感的,--my-color 和 --My-color 会被认为是两个不同的自定义属性。

    继承:自定义属性会继承。这意味着如果在一个给定的元素上,没有为这个自定义属性设置值,在其父元素上的值会被使用。看这一段 HTML:

    1. <style>
    2. //配套的 CSS:
    3. .two {
    4. --test: 10px;
    5. }
    6. .three {
    7. --test: 2em;
    8. }
    9. style>
    10. <div class="one">
    11. <div class="two">
    12. <div class="three">div>
    13. <div class="four">div>
    14. div>
    15. div>

    在这个情况下, var(--test) 的结果分别是:

    • 对于元素 class="two" :10px
    • 对于元素 class="three" :2em
    • 对于元素 class="four" :10px (继承自父属性)
    • 对于元素 class="one" :非法值,会变成自定义属性的默认值

     无效值

    当浏览器遇到无效的 var() 时,会使用继承值或初始值代替。

    考虑如下代码:

    HTML

    <p>This paragraph is initial black.p>
    

    CSS

    1. :root { --text-color: 16px; }
    2. p { color: blue; }
    3. p { color: var(--text-color); }

    毫不意外,浏览器将 --text-color 的值替换给了 var(--text-color),但是 16px 并不是 color 的合法属性值。代换之后,该属性不会产生任何作用。浏览器会执行如下两个步骤:

    1. 检查属性 color 是否为继承属性。是,但是 

       没有任何父元素定义了 color 属性。转到下一步。

    2. 将该值设置为它的默认初始值,比如 black。

    Result

    段落颜色并不是蓝色,因为无效代换导致了它被替换成了默认初始值的黑色。如果你直接写 color: 16px 的话,则会导致语法错误,而前面的定义则会生效(段落显示为蓝色)。

    备注: 当 CSS 属性 - 值对中存在语法错误,该行则会被忽略。然而如果自定义属性的值无效,它并不会被忽略,从而会导致该值被覆盖为默认值。

    JavaScript 中的值

    在 JavaScript 中获取或者修改 CSS 变量和操作普通 CSS 属性是一样的:

    1. // 获取一个 Dom 节点上的 CSS 变量
    2. element.style.getPropertyValue("--my-var");
    3. // 获取任意 Dom 节点上的 CSS 变量 window.getComputedStyle
    4. getComputedStyle(element).getPropertyValue("--my-var");
    5. // 修改一个 Dom 节点上的 CSS 变量
    6. element.style.setProperty("--my-var", jsVar + 4);
    7. //获取root上的css变量
    8. //:root--指的是根元素html,即document.documentElement
    9. document.documentElement.style.getPropertyValue('--my-var')
    10. getComputedStyle(document.documentElement).getPropertyValue("--my-var");

    注意:style.getPropertyValue的方式只能获取到内联样式的css变量值,要想获取任意位置的CSS变量要使用getComputedStyle。调用过setProperty后element或html会有内联style,才可以使用style.getPropertyValue获取到

    • document.documentElement.style.setProperty('--rect', '7px');方式设置CSS变量会添加到内联样式中去
    •  document.querySelector(':root') === document.documentElement

     检查支持性

    主流浏览器都已支持css变量,但顽强的 ie11仍未支持。

    1、css @supports命令(@supports也存在兼容性

    1. @supports ((--a: 0)) {
    2. /** 支持css变量字体为蓝色**/
    3. .container {
    4. --my-color: gray;
    5. background-color: var(--my-color);
    6. }
    7. }
    8. @supports (not (--a: 0)) {
    9. /* 不支持css变量字体为灰色 */
    10. .container {
    11. background-color: red;
    12. }
    13. }
    14. @supports(--css: variables) {
    15. .container{
    16. --my-color: blue;
    17. background-color: var(--my-color, 'blue');
    18. }
    19. }

    2、js

    1. const isSupported = window.CSS && window.CSS.supports && window.CSS.supports('--masterColor', 'red');
    2. if (isSupported) {
    3. /* supported */
    4. console.log('当前浏览器支持CSS变量')
    5. } else {
    6. /* not supported */
    7. console.log('当前浏览器不支持CSS变量')
    8. }

    使用案例:让一个div滑块向左匀速滑动,正好划出屏幕

    1. <head>
    2. <style>
    3. :root {
    4. --distance: -100vw;
    5. }
    6. * {
    7. margin: 0;
    8. padding: 0;
    9. }
    10. .container {
    11. position: absolute;
    12. width: 500px;
    13. height: 500px;
    14. margin: 50px;
    15. }
    16. #box {
    17. width: 20px;
    18. height: 20px;
    19. background-color: green;
    20. margin: 20px 0 0 300px;
    21. }
    22. .move {
    23. animation: moving 3s linear forwards;
    24. }
    25. @keyframes moving {
    26. 100% {
    27. transform: translate3d(var(--distance), 0, 0);
    28. }
    29. }
    30. style>
    31. head>
    32. <body>
    33. <div class="container">
    34. <button id="move-btn">movebutton>
    35. <div id="box">div>
    36. div>
    37. <script>
    38. const btn = document.getElementById("move-btn");
    39. const box = document.getElementById("box");
    40. btn.addEventListener("click", moving);
    41. function moving() {
    42. document.documentElement.style.setProperty(
    43. "--distance",
    44. "-" + (box.offsetLeft + box.offsetWidth) + "px"
    45. );
    46. box.classList.add("move");
    47. }
    48. script>
    49. body>

    注意:offsetLeft 是左顶点到最近的定位的父元素的距离,没有定位的父元素就是最初的包含快,正好移动offsetLeft那么就是box左顶点正好贴父元素边框,所以再多移动offsetWidth正好移动出去,向左移为负值。

  • 相关阅读:
    记一次 .NET 某游戏网站 CPU爆高分析
    ubuntu用Dockerfile配置ros+cuda+torch镜像及rviz可视化
    TF-IDF(Term Frequency-Inverse Document Frequency)
    输入法词库解析(七)微软用户自定义短语.dat
    Starrc input data
    VisualStudio运行程序,点击应用程序时,弹出多个个窗体问题
    springboot实现监听
    【超简单实用】Zotero 7 内置pdf背景颜色更改插推荐以及安装
    机器人自适应控制
    Spring的启动扩展点机制详解
  • 原文地址:https://blog.csdn.net/CamilleZJ/article/details/128002534