CSS变量总结

CSS变量

总结的开始首先看一个例子:
在这里插入图片描述如图是一个使用CSS3+CSS变量完成的
HTML代码如下:

<div class="navigator">
	<ul class="nav_ul">
		<li class="nav_item">
			<svg t="1580196202692" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="781" width="36" height="36"><path d="M555.541333 117.994667l312.874667 224.565333A117.333333 117.333333 0 0 1 917.333333 437.866667V800c0 64.8-52.533333 117.333333-117.333333 117.333333H640V746.666667c0-70.688-57.312-128-128-128s-128 57.312-128 128v170.666666H224c-64.8 0-117.333333-52.533333-117.333333-117.333333V437.877333a117.333333 117.333333 0 0 1 48.917333-95.317333l312.874667-224.565333a74.666667 74.666667 0 0 1 87.082666 0z" p-id="782" fill="currentColor"></path></svg>
			<span class="tip_name">Home</span>
		</li>
		<li class="nav_item">
			<svg t="1580196351612" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1159" width="36" height="36"><path d="M512 85.333333c235.637333 0 426.666667 191.029333 426.666667 426.666667S747.637333 938.666667 512 938.666667 85.333333 747.637333 85.333333 512 276.362667 85.333333 512 85.333333z m149.162667 222.901334L444.16 386.357333a96 96 0 0 0-57.802667 57.813334l-78.122666 216.992a42.666667 42.666667 0 0 0 54.602666 54.602666l217.002667-78.122666a96 96 0 0 0 57.802667-57.813334l78.122666-216.992a42.666667 42.666667 0 0 0-54.602666-54.602666zM512 565.333333a53.333333 53.333333 0 1 0 0-106.666666 53.333333 53.333333 0 0 0 0 106.666666z" p-id="1160" fill="currentColor"></path></svg>
			<span class="tip_name">Explore</span>
		</li>
		<li class="nav_item">
			<svg t="1580196428669" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2609" width="30" height="30"><path d="M335.008 916.629333c-35.914667 22.314667-82.88 10.773333-104.693333-25.557333a77.333333 77.333333 0 0 1-8.96-57.429333l46.485333-198.24a13.141333 13.141333 0 0 0-4.021333-12.864l-152.16-132.586667c-31.605333-27.52-35.253333-75.648-8.234667-107.733333a75.68 75.68 0 0 1 51.733333-26.752L354.848 339.2c4.352-0.362667 8.245333-3.232 10.026667-7.594667l76.938666-188.170666c16.032-39.2 60.618667-57.92 99.52-41.461334a76.309333 76.309333 0 0 1 40.832 41.461334l76.938667 188.16c1.781333 4.373333 5.674667 7.253333 10.026667 7.605333l199.712 16.277333c41.877333 3.413333 72.885333 40.458667 69.568 82.517334a76.938667 76.938667 0 0 1-26.08 51.978666l-152.16 132.586667c-3.541333 3.082667-5.141333 8.074667-4.021334 12.853333l46.485334 198.24c9.621333 41.013333-15.36 82.336-56.138667 92.224a75.285333 75.285333 0 0 1-57.525333-9.237333l-170.976-106.24a11.296 11.296 0 0 0-12.010667 0l-170.986667 106.24z" p-id="2610" fill="currentColor"></path></svg>
			<span class="tip_name">Collection</span>
		</li>
		<li class="nav_item">
			<svg t="1580196480651" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2891" width="30" height="30"><path d="M512 85.333333c235.637333 0 426.666667 191.029333 426.666667 426.666667S747.637333 938.666667 512 938.666667 85.333333 747.637333 85.333333 512 276.362667 85.333333 512 85.333333z m0 586.666667a32 32 0 1 0 0 64 32 32 0 0 0 0-64z m-2.517333-373.333333c-48.416 0-92.746667 24.16-118.613334 63.413333a137.088 137.088 0 0 0-15.978666 33.237333 32 32 0 0 0 60.906666 19.690667c2.016-6.24 4.885333-12.202667 8.522667-17.717333C458.4 375.914667 482.709333 362.666667 509.482667 362.666667 552.277333 362.666667 586.666667 396.266667 586.666667 437.333333s-34.4 74.666667-77.194667 74.666667a32 32 0 0 0-32 32v64a32 32 0 0 0 64 0v-35.584C603.946667 558.197333 650.666667 503.232 650.666667 437.333333c0-76.757333-63.381333-138.666667-141.194667-138.666666z" p-id="2892" fill="currentColor"></path></svg>
			<span class="tip_name">Help</span>
		</li>
	</ul>
</div>

CSS代码如下:

body{
	height: 100vh;
	background-color: #eceffc;
	display: flex;
	align-items: center;
	justify-content: center;
}


.nav_ul {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  list-style-type: none;

}
.navigator {
  --nav-width: 600px;
  --nav-item-width: calc(var(--nav-width) / 4 );
  --nav-overlay-width: calc(var(--nav-item-width));
  --active-index: 0;
  position: relative;
  width: var(--nav-width);
  height: 150px;
  background: white;
  border: 1em solid white;
  border-radius: 5% 5% 15% 15% / 15% 15% 50% 50%;
  overflow: hidden;
}

.nav_item {
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 2;
  flex-direction: column;
  width: var(--nav-item-width);
  height: 100%;
  color: #0288d1;
  cursor: pointer;
  transition: 0.5s ease;
}

.navigator::after{
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  width: var(--nav-overlay-width);
  height: 100%;
  background: #b3e5fc;
  transition: 0.2s ease;
  transform: translateX(0px);
  
  box-sizing: border-box;
  /*! margin-left: 30px; */
  transform: translateX(calc(var(--nav-item-width) * var(--active-index)));
  border-radius: 20px;
}

.nav_item span{
  opacity: 0;
  transition: 0.6s ease;
}

.active span{
  opacity: 1;
}

JS代码如下:

window.onload = function(){
  nav = document.querySelector(".navigator")
  navItems = document.querySelectorAll("li.nav_item")
  navItems.forEach(function(navItem,activeIndex){
    navItem.addEventListener("click",function(){
      console.log("click")
      navItems.forEach(function(item){
        return item.classList.remove("active")
      })
      navItem.classList.add("active")
      nav.style.setProperty("--active-index",activeIndex)

    })
  })		
}

这里主要CSS动画为:

transition: 0.2s ease;
transform: translateX(0px);

形成蓝色块的代码为:

.navigator::after{
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  width: var(--nav-overlay-width);
  height: 100%;
  background: #b3e5fc;
  transition: 0.2s ease;
  transform: translateX(0px);
  
  box-sizing: border-box;
  /*! margin-left: 30px; */
  transform: translateX(calc(var(--nav-item-width) * var(--active-index)));
  border-radius: 20px;
}

这里就是通过在四个tab的父元素设置一个after伪类来形成的,有一定的宽度,初始是靠在左侧的
那么如何运动的呢?这里就要提到CSS变量。移动原理相关的CSS代码如下:

transform: translateX(calc(var(--nav-item-width) * var(--active-index)));

translateX可以使块进行水平移动,如果能让translateX里边的参数能在点击触发以后都移动一定的距离,这不就动起来了!这里移动的原理就是使用CSS函数中的calc方法和var方法。以下是详细一点的分析。

  • 字典之中有个单词是calculate,就是计算的意思。从这里可以看出calc是用来计算
  • var同样,就是取自variable,也就是变量的意思。那他作为一个方法,意思很明显了,就是用来取变量的也就是参数所代表的值。如下:

var(–nav-item-width)

这里就是取--nav-item-width的值了。他是什么呢?
再往上找就可以看到他的定义:

–nav-item-width: calc(var(–nav-width) / 4 );

这里可以看到--nav-item-width同样包含了一层的计算,这里表明:变量的值是可以嵌套var函数的。到了这里,也可以发现变量前边都是有两杠的这就是CSS变量定义的格式。那么为什么的不用其他呢?因为 $variable已经被SASS用了@variable被Less用了

继续上述的例子。从找到的式子可以看到其中还包含了一层运算,其中还有以一个变量--nav-width。那就再找到–nav-width.

–nav-width: 600px;

这里就找到一个准确的值,变量的简单定义就是直接定义一个值。那既然var是获取变量的值,现在知道了这个变量的值。那么就可以知道这种结论:var函数会返回原本定义的值

var(–nav-width) == 600px

那么上述的例子就可以这么转化:

–nav-item-width: calc(var(–nav-width) / 4 ) => --nav-item-width: calc(600px / 4 )

var的使用得到了上述的结果。可以看到括号中还有一个600px / 4
看上去就是一个除法的运算。这个时候就是calc发挥作用的时候,就像他的名字一样,对变量进行了计算并将结果返回。于是得到如下的等价结果:

–nav-item-width: calc(600px / 4 ) => --nav-item-width: calc(150px ) => --nav-item-width: 150px

这里就成功将--nav-item-width设置成了150px。所以,总结以上:

  • 自定义变量中前边是有两条杠的
  • 变量可以直接赋值,也同样支持嵌套
  • var可用来获取变量的值并将值进行返回
  • calc可以用来进行算数运算,并将结果返回
    注意事项: calc函数进行运算,其中运算符号两侧是需要有空格的,不然是无效的

例子补充

1. var可以返回变量指向的值,可以用来字符串拼接

//HTML
  <body>
      <div class="test"></div>
  </body>
  
//CSS
.test{

	width: 100px;
	height: 100px;
	border: 1px solid grey;
}
.test::after{
	--test-str: "hello";
	content: var(--test-str)+"world";
}

是按JS的方式进行拼接么?明显是不行的
正确的应该是这样:

.test::after{
	--test-str: "hello";
	content: var(--test-str)"world";
}

在这里插入图片描述
2. 那除了字符串还能进行其他值的拼接么?

// HTML

  <body>
    <div class="test"></div>
  </body>
  
// CSS
.test{
	--test-width: 100;
	width: var(--test-width)px;
	height: 100px;
	border: 1px solid grey;
}

在这里插入图片描述

从结果上看也是不可以的

这里在补充一点:

.test{
	width: "100px";
	height: 100px;
	border: 1px solid grey;
}

在这里插入图片描述从结果上看,这样的形式也是不可以的。也就是说,通过var函数进行字符串拼接而来的数值设置给属性也是无效的。
那么如何在只拥有数值的情况下进行赋值呢。这里可以通过calc方法进行赋值。
如下:

.test{
	--test-width: 100;
	width: calc(var(--test-width) * 1px);
	height: 100px;
	border: 1px solid grey;
}

3. 既然用到var去设置变量的值,那么要是失效了会怎样呢?有 默认值吗?

// HTML
  <body>
    <div class="test"></div>
  </body>
  
// CSS
.test{
	--test-width: 100;
	width: var(--test-width,100px);
	height: 100px;
	border: 1px solid grey;
}

结果:

在这里插入图片描述不是说有默认值么?事实上该值**只有在变量缺失的时候作为返回值的。**这个值称为 回调值

.test{
	/* --test-width: 100; */
	width: var(--test-width,100px);
	height: 100px;
	border: 1px solid grey;
}

结果:

补充:

3.1 如果设置了多个回调值会怎样呢?如下

// 形式一
.test{
	/* --test-width: 100; */
	width: var(--test-width,100,200px);
	height: 100px;
	border: 1px solid grey;
}

// 形式二
.test{
	/* --test-width: 100; */
	width: var(--test-width,100px,200px);
	height: 100px;
	border: 1px solid grey;
}

二者的结果都是:
在这里插入图片描述这里的原因就是var函数中分为两个参数,第一个参数就是我们正常设置的,第二个参数就是回调的,二者之间是通过逗号隔开的。也就是说逗号以后的整个语句就是一个回调函数。

3.2 var回调值是逗号以后的值,但是也是支持嵌套的。如下:

.test{
	/* --test-width: 100; */
	width: var(--test-width,var(--test,100px));
	height: 100px;
	border: 1px solid grey;
}

同样也是在参数缺省的时候才发挥作用。

4 为什么在设置里变量的基础上使用回调值会失败呢?这里就说明一下。css变量的灵活是它的优点,因为在任何地方,你都可以通过var函数进行调用,这么做的好处是什么呢?例如要给产品做个换肤的功能,使用css变量就可以将这些跟皮肤相关的变量就可以统一设置在一个地方,换肤的时候就可以直接修改相应的值,而不是一个个查找(在仅仅使用css实现的情况下)。
但是使用var也同样是他的一个缺点,因为你只要定义了这个变量,但是浏览器是不知道你在哪里会调用他的,所以只要你定义了,它就会认为你有效,这里的一个坏处就是忽略了上下文。什么意思呢?这里首先看一个对比情况

// HTML
  <body>
    <div class="container">
      <div class="test"></div>
    </div>
  </body>
  
// CSS
情况一
.test{
	width: 20px;
	width: 100px;
	height: 100px;
	border: 1px solid grey;
}

情况二
.test{
	--width: 100px;
	width: 100px;
	width: var(--width);
	height: 100px;
	border: 1px solid grey;
}

情况一结果:
在这里插入图片描述情况二结果:
在这里插入图片描述这里貌似都没有毛病,但是这里都是在值都是有效的情况下的。再来看看两种情况。

// HTML
  <body>
    <div class="container">
      <div class="test"></div>
    </div>
  </body>
  
// CSS
情况一
.test{
	width: 100px;
	width: red;
	height: 100px;
	border: 1px solid grey;
}

情况二
.test{
	--width: red;
	width: 100px;
	width: var(--width);
	height: 100px;
	border: 1px solid grey;
}

情况一结果:

在这里插入图片描述可以看到情况一是正常设置两个width属性,在发现第二个width失效了以后,立即将其设置为无效,从上一个例子中,可以知道当第二个值有效的情况下是设置第二个值的。再来看看情况二的结果:
!在这里插入图片描述

.test{
	--width: red;
	width: 100px;
	width: var(--width);
	height: 100px;
	border: 1px solid grey;
}

情况二的结果就有点出人意料了,使用了var函数将相同的值设置在同样额位置,但是上文的width却出现了无效的结果。这里就会产生一个无效的计算时间,因为css变量是处处有效,在这里更是忽略了上文的width导致一些“浪费”和出人意料的结果。

5. 那么对4中的无效情况又如何处理呢?
这里对于第二种情况,在test类中,width属性都失效了。但是可以从父元素中进行继承和使用默认的样式或者内联样式中取到

.container{
	width: 100px;
}

.test{
	--width: red;
	width: 100px;
	width: var(--width);
	height: 100px;
	border: 1px solid grey;
}

结果:

6. 以上都是介绍css中使用css变量的,那么如何而是用js进行操作css变量呢?
DOMsetProperty getPropertyValue

// 设置
var data = document.querySelector('div.test')
data.style.setProperty('--width','100px')

结果:
在这里插入图片描述
从上图中可以看到成功设置上了相应的数值,并且是设置到了内联样式中


这里也是确实有效果的。
从上述中可以看到,结果是设置在内联样式中的,那么可以直接设置么?

var obj = document.querySelector('div.test')
obj.style['--width'] = '100px'

结果:
在这里插入图片描述
在这里插入图片描述
甚至连影子也是找不到。
或许会想到为什么不用obj.style.--width呢,明显不行的,因为不符合变量要求。

那么还有其他办法么?是有的。

第一种: setAttribute

         var obj = document.querySelector('div.test')
         obj.setAttribute('style','--width:100px')

第二种:addRule

        var style = document.querySelector('style')
        var sheet = style.sheet
        sheet.addRule('div.test','--width:100px')

第三种: insertRule

        var style = document.querySelector('style')
        var sheet = style.sheet
        sheet.insertRule('div.test {--width:100px}',0)

上述经过测试都是可行的。在这里补充一点第二和第三种方法是通过在内联样式表中进行插入样式,所以html文件中必须创建style标签。

再看获取: getPropertyValue

// 设置
var data = document.querySelector('div.test')
data.style.getPropertyValue('--width')

结果:

出现获取不到的情况,getPropertyValue获取不到值是什么原因呢?
setProperty中可以看出一点眉目,设置是设置在内联样式中的,那么获取是不是也是获取内联样式中的呢?
这里尝试一下:

<div class="test" style="--width:100px"></div>

结果:
在这里插入图片描述所以getPropertyValue仅仅是获取内联样式中的属性
那么如何进行获取内联样式表中的css变量呢?代码如下:

         var obj = document.querySelector('div.test')
         var cssStyles = window.getComputedStyle(obj,null)
         var width = cssStyles.getPropertyValue('--width')

通过上述代码可以获取在火狐浏览器和谷歌浏览器

以上方法都是获取在样式中的自定义变量的值

通过jquery去获取:通过jquery属性的值,首先会想到,既然是内联的样式,那么可不可以通过css方法进行获取呢。尝试一下。

// HTML
	     <div class="container">
	       <div class="test" style="--width:100px"></div>
	     </div>
          var $obj = $('div.test')
		  $obj.css('--width')

在这里插入图片描述从结果可以看出,即使在设置了内联样式中的--width也是不可行的。从上述的DOM中可以得到一些启发就是可以操作属性对象去获取相应的值。这里就用到attr方法。

         <div class="test" style="--width:100px"></div>
          var $obj = $('div.test')
          $obj.attr('style').split(':')[1]

因为获取的style是一个字符串,所以对字符串进行分割。就可以得到--width的值了。

初次以外还有一个方法:就是使用跟attr很相似的prop方法:

          var $obj = $('div.test')
          $obj.prop('style')

结果:
在这里插入图片描述
从图中可以看到并没有获得先gattr那样返回的字符串,而是返回了一个DOM兑对象。那么就可以使用DOMgetPropertyValue进行获取他的值。详细参考上述。

第三种方法就是: 转换成DOM,然后对DOM进行操作。

通过jquery去设置:
1. 从上述中使用css方法进行获取是不可能的了,所以设置也是不可行的

2. 通过attr方法设置

          var $obj = $('div.test')
          $obj.attr('style',"--width:100px")

3. 通过prop方法设置:

          var $obj = $('div.test')
          $obj.prop('style',"--width:100px")

参考:
CSS 变量教程 - 阮一峰的网络日志

CSS Custom Properties for Cascading Variables Module Level 1
(需要翻墙)

Using CSS custom properties (variables)

js获取css属性值

js设置css样式的几种方式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值