深入理解CSS变量:高级技巧和最佳实践

前言

CSS 变量是一项强大的功能,它可以帮助开发人员更好地组织和管理样式表。在本文中,我们将深入探讨 CSS 变量的高级技巧和最佳实践,通过学习如何使用变量作为计算值、媒体查询和动态更改等方面,你将能够更好地利用 CSS 变量的强大功能。


一、概念

CSS 变量(也称为自定义属性)是一种在 CSS 中定义和使用的值,可以在整个样式表中重复使用。它们提供了一种灵活的方式来存储和管理样式中的值,使得样式的修改更加简单和可维护。


二、基本用法

CSS 变量的基本用法包括定义变量、使用变量和修改变量的值。

1. 定义变量

CSS 中,使用–前缀来定义变量。变量的命名可以由字母、数字、破折号和下划线组成,但必须以字母开头。变量的定义通常放在选择器的规则集内,或者在根元素(:root)中定义,以便全局使用。例如:

:root {
    
    
  --primary-color: #ff0000;
  --font-size: 16px;
}

2. 使用变量

使用变量时,需要使用 var() 函数将变量包裹起来。变量可以在任何可以使用 CSS 属性值的地方使用,例如颜色、尺寸、边距等。例如:

.element {
    
    
  color: var(--primary-color);
  font-size: var(--font-size);
}

3. 修改变量的值

变量的值可以在 CSS 中动态修改,以实现样式的变化。可以通过JavaScript或使用伪类(:hover:focus等)来修改变量的值。例如:

.element:hover {
    
    
  --primary-color: #00ff00;
}

或者使用 JavaScript 来修改变量的值:

document.documentElement.style.setProperty('--primary-color', '#00ff00');

三、命名规范

当我们在 CSS 中使用变量时,为了避免与现有的 CSS 属性冲突,我们可以使用自定义的 CSS 变量,并为它们选择适当的命名规范。以两个横线(--)开头的属性被视为 CSS 变量。

以下是一些常见的 CSS 变量命名规范:

  • 使用有意义的名称:为了增加代码的可读性和可维护性,我们应该选择具有描述性的名称来命名 CSS 变量。这样可以使其他开发人员更容易理解变量的用途和含义;
  • 使用小写字母和连字符:CSS 变量的名称应该使用小写字母,并使用连字符(-)作为单词之间的分隔符。例如,--primary-color
  • 使用命名空间:为了避免与其他变量冲突,可以使用命名空间来对变量进行分组。例如,--button-primary-color,其中 button 是命名空间;
  • 避免使用缩写和简写:尽量避免使用缩写和简写的变量名称,因为这可能会导致代码的可读性降低。选择具有描述性的名称,以便其他开发人员能够轻松理解变量的含义;
  • 使用一致的命名约定:在整个项目中保持一致的命名约定是很重要的。选择一种命名风格,并在整个项目中坚持使用它,这样可以提高代码的一致性和可读性。

总之,CSS 变量的命名规范应该注重可读性、可维护性和一致性。通过选择有意义的名称、使用小写字母和连字符、使用命名空间以及避免缩写和简写,我们可以更好地组织和管理 CSS 变量。


四、变量值类型

CSS 中,CSS 变量的值可以是各种不同的类型。不同的类型在使用上也会有细微的差别。

如果变量值是一个字符串,可以与其他字符串拼接,例如:

<!DOCTYPE html>
<html>

<style>
  :root {
      
      
    --primary-content: 'hello';
  }


  .box:after {
      
      
    content: '标题 : ' var(--primary-content)
  }
</style>

<body>
  <div class="box"></div>
</body>

</html>
  • 实现效果

在这里插入图片描述

如果变量值是数值,则不能与数值单位直接连用,例如:

在下面的代码中,我们在 box2 盒子使用 calc() 函数来执行数学计算,将变量 --primary-num 的值乘以 1 像素(1px)。这样,就可以将数值与单位进行结合,以实现正确的样式效果。通过这种方式,我们可以将数值与单位进行拼接,确保样式的正确性。而且 calc() 函数可以执行更复杂的数学计算,例如加法、减法、乘法和除法等。

<!DOCTYPE html>
<html>

<style>
  :root {
      
      
    --primary-num: 40;
  }

  .box1 {
      
      
    background: cadetblue;
    padding-top: var(--primary-num)px;
  }

  .box2 {
      
      
    background: chocolate;
    padding-top: calc(var(--primary-num) * 1px);
  }
</style>

<body>
  <div class="box1">内容1</div>
  <div class="box2">内容2</div>
</body>

</html>
  • 实现效果

在这里插入图片描述

如果变量值带有单位,就不能写成字符串,例如:

在下面的代码中,我们在 box1 盒子将带有单位的变量值定义为字符串。这是无效的,因为 CSS 属性期望的是数值单位,而不是字符串。这样的定义会导致样式无效或产生错误。因此,当变量值带有单位时,应该将其定义为数值,而不是字符串。这样可以确保变量在应用于 CSS 属性时能够正确地与单位进行结合。

<!DOCTYPE html>
<html>

<style>
  :root {
      
      
    --border-radius-box1: '20px';
    --border-radius-box2: 20px;
  }

  .box1 {
      
      
    background: chocolate;
    border-radius: var(--border-radius-box1);
  }

  .box2 {
      
      
    background: cornflowerblue;
    border-radius: var(--border-radius-box2);
  }
</style>

<body>
  <div class="box1">内容1</div>
  <div class="box2">内容2</div>
</body>

</html>
  • 实现效果

在这里插入图片描述


五、如何理解理解 :root 和 var()

:root 伪类:

  • :root 伪类选择器匹配文档树的根元素,通常是 <html> 元素;
  • :root 伪类中定义的 CSS 变量可以在整个文档中全局使用;
  • 通过在 :root 伪类中定义变量,我们可以为整个文档设置全局的 CSS 属性值;
  • 例如,我们可以使用 :root 伪类定义全局的颜色、字体大小、断点值等。

var() 函数:

  • var() 函数用于引用和使用 CSS 变量的值;
  • 它接受一个参数,即要引用的 CSS 变量的名称;
  • var() 函数可以在任何 CSS 属性的值中使用,包括字体大小、颜色、边距等;
  • 通过使用 var() 函数,我们可以根据需要在不同的元素和选择器中使用相同的 CSS 变量值,实现统一的样式管理;
  • 例如,我们可以使用 var(--primary-color) 来引用全局定义的 --primary-color 变量。

CSS 变量的基本用法就是这样。通过定义、使用和修改变量的值,可以实现样式的重用、动态变化和全局控制。这使得 CSS 开发更加灵活和可维护。下面为大家提供三个案例,涵盖了定义变量、使用变量和修改变量的值的示例的完整代码。

案例 1

在这个案例中,我们定义了两个变量 --primary-color--font-size,并将其应用于 .element 元素的颜色和字体大小。当鼠标悬停在 .element 元素上时,--primary-color 变量的值将变为绿色,--font-size 变量的值将变为 26px

<!DOCTYPE html>
<html>

<head>
  <style>
    :root {
      
      
      --primary-color: #f88604;
      --font-size: 22px;
    }

    .element {
      
      
      color: var(--primary-color);
      font-size: var(--font-size);
    }

    .element:hover {
      
      
      --primary-color: rgb(0, 104, 202);
    }
  </style>
</head>

<body>
  <div class="element">Hello, CSS Variables!</div>
</body>

</html>
  • 实现效果

在这里插入图片描述


案例 2

在这个案例中,我们使用 JavaScript 来监听窗口的大小变化,并根据窗口宽度动态修改 CSS 自定义属性的值。在 updateStyles 函数中,我们通过 window.getComputedStyle 方法获取了 --breakpoint 的值,并根据窗口宽度判断是否应用响应式样式。

<!DOCTYPE html>
<html>

<head>
  <style>
    :root {
      
      
      --breakpoint: 300px;
      --font-size: 16px;
      --primary-color: #ff0000;
    }

    .element {
      
      
      font-size: var(--font-size);
      color: var(--primary-color);
    }
  </style>
  <script>
    function updateStyles() {
      
      
      var element = document.querySelector('.element');
      var breakpoint = getComputedStyle(document.documentElement).getPropertyValue('--breakpoint');

      if (window.innerWidth <= parseInt(breakpoint)) {
      
      
        element.style.setProperty('--font-size', '14px');
        element.style.setProperty('--primary-color', '#00ff00');
      } else {
      
      
        element.style.setProperty('--font-size', '16px');
        element.style.setProperty('--primary-color', '#ff0000');
      }
    }

    window.addEventListener('resize', updateStyles);
    window.addEventListener('DOMContentLoaded', updateStyles);
  </script>
</head>

<body>
  <div class="element">Responsive Text</div>
</body>

</html>
  • 实现效果

在这里插入图片描述


案例 3

在这个案例中,我们定义了一个变量 --primary-color,并将其应用于 .element 元素的颜色。通过 JavaScript 中的 changeColor 函数,我们可以通过点击按钮来修改 --primary-color 变量的值,从而改变 .element 元素的颜色。

<!DOCTYPE html>
<html>

<head>
  <style>
    :root {
      
      
      --primary-color: orange;
    }

    .element {
      
      
      color: var(--primary-color);
    }
  </style>
  <script>
    function changeColor() {
      
      
      document.documentElement.style.setProperty('--primary-color', 'blue');
      // document.documentElement.style.setProperty('root变量', '更改的值')
    }
  </script>
</head>

<body>
  <div class="element">Click the button to change color</div>
  <button onclick="changeColor()">点击改变颜色</button>
</body>

</html>
  • 实现效果

在这里插入图片描述


案例 4

在这个案例中,通过使用 CSS 变量,我们可以动态地控制按钮的样式,实现了鼠标跟踪效果。
在代码中,我们定义了两个 CSS 变量:--x--y。这两个变量分别表示鼠标在按钮上的横坐标和纵坐标。通过 JavaScript 中的 setProperty 方法,我们可以根据鼠标移动事件的位置,实时地更新这两个变量的值。在 SCSS 部分,我们使用这两个 CSS 变量来确定鼠标跟踪效果的位置。通过将 --x--y 应用到伪元素 ::beforelefttop 属性上,我们可以让伪元素跟随鼠标的位置而移动。此外,我们还使用了 CSS 变量 --size 来控制伪元素的大小。当鼠标悬停在按钮上时,通过改变 --size 的值,我们可以实现一个渐变背景的动画效果。

<template>
  <div class="track-btn" @mousemove="handleMouseMove">
    <span>使用 CSS 变量让你的按钮更炫酷</span>
  </div>
</template>

<script>
export default {
      
      
  methods: {
      
      
    handleMouseMove(e) {
      
      
      const btnStyle = e.target.style;
      btnStyle.setProperty("--x", `${ 
        e.offsetX}px`);
      btnStyle.setProperty("--y", `${ 
        e.offsetY}px`);
    },
  },
};
</script>

<style lang="scss">
.track-btn {
      
      
  position: relative;
  width: 400px;
  height: 50px;
  background-color: rgb(102, 219, 255);
  cursor: pointer;
  line-height: 50px;
  text-align: center;
  font-weight: bold;
  font-size: 18px;
  color: #fff;
  overflow: hidden;

  span {
      
      
    position: relative;
    pointer-events: none;
  }

  &::before {
      
      
    --size: 0;
    position: absolute;
    left: var(--x);
    top: var(--y);
    width: var(--size);
    height: var(--size);
    background-image: radial-gradient(
      circle closest-side,
      rgb(0, 215, 82),
      transparent
    );
    content: "";
    transform: translate3d(-50%, -50%, 0);
    transition: width 200ms ease, height 200ms ease;
  }

  &:hover::before {
      
      
    --size: 400px;
  }
}
</style>
  • 实现效果

在这里插入图片描述


六、变量作用域

CSS 变量的作用域是定义它们的选择器的范围。在选择器内定义的变量只能在该选择器内部使用,而在全局作用域内定义的变量则可以在整个文档中使用。

1. 全局作用域

  • :root 伪类中定义的 CSS 变量具有全局作用域;
  • :root 伪类选择器匹配文档树的根元素,通常是 <html> 元素;
  • :root 伪类中定义的变量可以在整个文档中全局使用。
<!DOCTYPE html>
<html>

<head>
  <style>
    :root {
      
      
      --bg-color: rgb(88, 88, 186);
      --color: #33ca63;
    }

    div {
      
      
      background-color: var(--bg-color);
      color: var(--color);
    }

    span {
      
      
      background-color: var(--bg-color);
      color: var(--color);
    }
  </style>
</head>

<body>
  <div>
    <p>我在div内部</p>
  </div>
  <span>我在div外部</span>
</body>

</html>
  • 实现效果

在这里插入图片描述


2. 局部作用域

  • 在选择器内部或元素内部定义的 CSS 变量具有局部作用域;
  • 这些变量只能在定义它们的选择器或元素内部使用;
  • 局部作用域的变量会覆盖全局作用域中同名的变量。
<!DOCTYPE html>
<html>

<head>
  <style>
    div {
      
      
      --bg-color: rgb(88, 88, 186);
      --color: #33ca63;
    }

    p {
      
      
      background-color: var(--bg-color);
      color: var(--color);
    }

    span {
      
      
      background-color: var(--bg-color);
      color: var(--color);
    }
  </style>
</head>

<body>
  <div>
    <p>我在div内部</p>
  </div>
  <span>我在div外部</span>
</body>

</html>
  • 实现效果

在这里插入图片描述


3. vue 中设置 scoped

vue 中,当你为组件的 <style> 标签添加了 scoped 属性时,CSS 样式将会被限定在组件的作用域内。这意味着,只有在当前组件中的元素才会受到这些样式的影响,而不会泄漏到其他组件中。然而,CSS 变量在 vuescoped 样式中的行为和普通的选择器样式是不同的。当你在 <style> 标签中使用 scoped 属性时,vue 会自动为每个组件的根元素添加一个唯一的类名,以确保该组件的样式只应用到该组件内部。由于 CSS 变量是全局的,其作用域会超出组件的范围。所以在一个带有 scoped 样式的 vue 组件中,CSS 变量在其他组件中是不生效的。换句话说,你无法在一个组件中定义的 CSS 变量在其他组件中使用。

如果你希望在 vue 组件间共享 CSS 变量,有两种常见的方法:

  1. 使用 CSS 预处理器,例如 SassLess,它们可以提供变量的作用域和共享功能;
  2. CSS 变量定义在全局样式中(不使用 scoped 属性),以便在所有组件中共享。

需要注意的是,如果你选择将 CSS 变量定义在全局样式中,请确保变量的命名是唯一的,以避免可能的冲突。


七、变量优先级

CSS 变量的优先级与其他 CSS 属性的优先级相同,遵循 CSS 层叠规则。下面是 CSS 属性优先级的一般顺序(从高到低):

  • !important:使用 !important 声明的样式具有最高优先级,会覆盖其他所有样式;
  • 内联样式:直接在 HTML 元素上使用 style 属性定义的样式具有较高的优先级;
  • ID 选择器:使用 ID 选择器定义的样式具有较高的优先级;
  • 类选择器、属性选择器和伪类选择器:这些选择器定义的样式具有中等优先级;
  • 元素选择器和伪元素选择器:这些选择器定义的样式具有较低的优先级;
  • 继承样式:继承自父元素的样式具有最低优先级。

当涉及到 CSS 变量时,它们的优先级与其他选择器相同。如果在同一个元素上定义了多个相同的 CSS 变量,后面定义的变量会覆盖前面的变量。如果在不同的选择器中定义了相同的 CSS 变量,遵循选择器的优先级规则。例如,如果在内联样式中定义了一个 CSS 变量,它将具有较高的优先级,并且会覆盖其他选择器中定义的相同变量。同样,如果在 ID 选择器中定义了一个 CSS 变量,它将具有较高的优先级,并且会覆盖其他选择器中定义的相同变量。

<!DOCTYPE html>
<html>

<head>
  <style>
    :root {
      
      
      --primary-color: blue;
    }

    .container {
      
      
      --primary-color: red;
    }

    .box {
      
      
      background-color: var(--primary-color);
      width: 200px;
      height: 200px;
      margin: 20px;
    }
  </style>
</head>

<body>
  <div class="container">
    <div class="box"></div>
  </div>
</body>

</html>

在这个案例中,我们定义了一个名为 --primary-colorCSS 变量,并在 :root 伪类中设置为蓝色。然后,在 .container 类选择器中重新定义了相同的变量,并将其设置为红色。在 .box 类选择器中,我们使用 var() 函数来引用 --primary-color 变量,并将其作为背景颜色。由于 .container 类选择器具有较高的优先级,所以最终 .box 的背景颜色将是红色。

  • 实现效果

在这里插入图片描述


八、兼容性

CSS 变量在现代的浏览器中其实已经具有良好的兼容性了,但在一些旧版本的浏览器中可能存在一些限制。

浏览器 兼容性
Chrome 支持自 Chrome 49 版本及以上
Firefox 支持自 Firefox 31 版本及以上
Safari 支持自 Safari 9.1 版本及以上
Opera 支持自 Opera 36 版本及以上
Edge 支持自 Edge 15 版本及以上
Internet Explorer 不支持 CSS 变量

九、使用 CSS 变量带来的提升

  • 可重用性和易维护性

    CSS 变量允许你定义一次样式,并在整个样式表中多次重用。这样可以减少代码的重复性,提高代码的可维护性。通过修改变量的值,可以轻松地更改整个样式的外观,而无需逐个修改每个具体的样式。

  • 动态性和灵活性

    CSS 变量可以在运行时动态修改,而无需修改样式表。这使得在不同的条件下应用不同的样式变得更加容易。例如,您可以根据用户的选择或主题切换来更改变量的值,从而实现动态的样式变化。

  • 响应式设计

    CSS 变量可以与媒体查询结合使用,实现响应式设计。通过在不同的媒体查询中定义不同的变量值,可以根据设备的屏幕尺寸和特性来调整样式。这使得网页可以适应不同的屏幕大小和设备类型,提供更好的用户体验。

  • 可读性和可维护性

    CSS 变量可以使用有意义的名称来定义,使样式表更易于理解和维护。相比于硬编码的数值或颜色,使用变量可以提高代码的可读性,并使样式的意图更加清晰。

  • 全局控制

    通过在根元素上定义 CSS 变量,可以实现全局的样式控制。这意味着你可以在整个网站中使用相同的变量,从而确保一致的外观和风格。如果需要更改样式,只需修改变量的值,而无需逐个修改每个具体的样式。

猜你喜欢

转载自blog.csdn.net/Shids_/article/details/134502119
今日推荐