乐趣区

关于前端:使用CSS-background实现炫酷悬停效果

日常开发过程中,会遇到不少按钮鼠标悬停的成果,实现这类悬停成果的形式有很多,借助伪元素,CSS3 变换及过渡等都能够实现。明天的文章将应用背景色实现相似的成果,当咱们遇到一个问题时,你的脑海中的计划不止一种时,我想这必定是极好的,应用不同的办法达到同一的成果,或者某天所遇到的问题就迎刃而解了。

明天次要实现的鼠标悬停成果如下 GIF 图所示。

悬停成果一

上图所示的成果代码如下所示,只须要 4 行代码即可实现成果,是否很诧异代码为何如此精简,接下来将具体阐明是如何做到的。

.hover-1 {background: linear-gradient(#1095c1 0 0) var(--p, 0) / var(--p, 0) no-repeat;
  transition: .4s, background-position 0s;
}
.hover-1:hover {
  --p: 100%;
  color: #fff;
}

首先,咱们从一个简略的 background-size 过渡开始,如上图所示,背景色的高度是始终放弃 100%,咱们只须要扭转其宽度从 0% 到 100% 之间的切换。因为应用了 background-size 扭转宽度,所以应用 background-image: linear-gradient 设置背景色。因为只有一个色彩值,应用此 #1095c1 0 0 简写形式,不须要写两个色值。

background-image: linear-gradient(#1095c1 0 0);

应用 background-size 时,咱们能够省略高度,因为默认状况下突变是全高。咱们应用 background-size: 0 过渡到background-size: 100%

.hover-1 {background-size: 0;}
.hover-1:hover {background-size: 100%;}

进一步优化,引入一个自定义属性以防止反复 background-size--p 最后没有定义,因而将应用 0%。在悬停时,咱们定义--p100%替换初始值0%

.hover-1 {background-size: var(--p, 0%);
}
.hover-1:hover {--p: 100%;}

到此咱们的成果如下所示

接下来引入 background-position 实现反转的成果,看最开始的 GIF 图能够离开 2 步实现。

  • 鼠标悬停时背景是从右往左减少尺寸
  • 鼠标移出时背景是从左往右减小尺寸

并且在悬停时不能减少 transition 过渡动画,此属性是须要及时失效的,所以减少了background-position 0s

.hover-1 {
  background-position: left;
  transition: .4s,background-position 0s;
}
.hover-1:hover {
  --p: 100%;
  background-position: right;
}

还能够进一步优化,background-position的值应用百分比。

.hover-1 {
  background-position: 0%;
  transition: .4s,background-position 0s;
}
.hover-1:hover {
  --p: 100%;
  background-position: 100%;
}

聪慧的你可能曾经发现了,悬停时的两个值都是 100%,那么咱们能够进一步优化都应用自定义属性--p

.hover-1 {background: linear-gradient(#1095c1 0 0) no-repeat;
  transition: .4s,background-position 0s;
  background-size: var(--p, 0%);
  background-position: var(--p, 0%);
}
.hover-1:hover {--p: 100%;}

针对 background 咱们应用复合写法,进一步精简代码,应用 / 做宰割,后面是 background-position 前面是 background-size

.hover-1 {background: linear-gradient(#1095c1 0 0) var(--p, 0%) / var(--p,0%) no-repeat;
  transition: .4s, background-position 0s;
}
.hover-1:hover {--p: 100%;}

到此就残缺的实现悬停成果一且精简了代码,基于此设计,还能够略微改变代码让悬停成果达到相同的成果,批改 background-position 从 100% 到 0%,而不是下面的 0% 到 100%。为了放弃 --p自定义属性不变,咱们应用 calc() 函数解决。

  background: linear-gradient(#1095c1 0 0) calc(100% - var(--p,0%)) / var(--p,0%) no-repeat;

悬停成果二

如上图所示,相比拟成果一更为简单,整个成果是由多个动画步骤组成。最开始的背景区域在可视区域之外,从左往右挪动到笼罩到整个元素底部,而后扭转背景色到高度到 100% 笼罩到整个元素。

这里须要应用到 background-position 的百分比应用形式,不了解其应用形式的话能够看看文末的参考文章。窍门是将宽度改为 200%,但不必放心背景色超出后的溢出问题,对于元素溢出的背景色都是暗藏的,代码如下。

.hover-2 {background-image: linear-gradient(#1095c1 0 0);
  background-size: 200% .08em;
  background-position: 200% 100%;
  background-repeat: no-repeat;
  transition: background-size .3s, background-position .3s .3s;
}
.hover-2:hover {
  transition: background-size .3s .3s, background-position .3s;
  background-size: 200% 100%;
  background-position: 100% 100%;
}

而后持续开始优化代码,首先应用background 的复合写法精简,缩小额定的申明。

.hover-2 {
  background: 
    linear-gradient(#1095c1 0 0) no-repeat
    var(--p, 200%) 100% / 200% var(--p, .08em);
  transition: .3s var(--t, 0s), background-position .3s calc(.3s - var(--t, 0s));
}
.hover-2:hover {
  --p: 100%;
  --t: .3s;
}

这里减少一个自定义变量--t,在鼠标悬停时,咱们设置为.3s,最终代码如下:

transition: .3s .3s, background-position .3s 0s;

鼠标移出时,--t未定义,最终代码如下:

transition: .3s 0s, background-position .3s .3s;

到此为止,鼠标悬停时申明了两个变量,咱们还能够进一步优化,通过一个属性更新多个属性,对于如何生成这样的代码能够看文末的参考链接,最终代码批改如下:

.hover-2 {
  background: 
    linear-gradient(#1095c1 0 0) no-repeat
    calc(200% - var(--i, 0) * 100%) 100% / 200% calc(100% * var(--i, 0) + .08em);
  transition: .3s calc(var(--i, 0) * .3s), background-position .3s calc(.3s - calc(var(--i, 0) * .3s));
}
.hover-2:hover {--i: 1;}

--i最终是未定义则是 0,悬停时更新为 1,该变量就如同在 JS 中的一个开关变量,到此为止,整个成果只须要三行 css 申明实现。

悬停成果三

此成果在成果二的根底上扩大为两个突变动画成果,最后会有两个突变溢出的元素,默认都不在视线范畴内,每一个的宽度为整个元素的一半。当咱们鼠标移入的时候批改这两个溢出的元素到可见区域,第一个突变位于左下角,第二个突变位于右上角,最初减少高度笼罩到整个元素。

初始 CSS 代码如下,与成果二的代码简直雷同,惟一的区别就是具备两个不同的地位同时产生动画成果,这里同样用到了百分比的background-position

.hover-3 {
  background-image:
    linear-gradient(#1095c1 0 0),
    linear-gradient(#1095c1 0 0);
  background-repeat: no-repeat;
  background-size: 50% .08em;
  background-position:
    -100% 100%,
    200% 0;
  transition: background-size .3s, background-position .3s .3s;
}
.hover-3:hover {
  background-size: 50% 100%;
  background-position:
    0 100%,
    100% 0;  
  transition: background-size .3s .3s, background-position .3s;
}

接下来开始优化代码,background复合写法,自定义属性以及 calc()进一步整顿,这里新增了一个额定的 –c 自定义属性,因为在 background 中用到了两次。

.hover-3 {--c: no-repeat linear-gradient(#1095c1 0 0);
  background: 
    var(--c) calc(-100% + var(--p, 0%)) 100% / 50% var(--p, .08em),
    var(--c) calc(200% - var(--p, 0%)) 0    / 50% var(--p, .08em);
  transition: .3s var(--t, 0s), background-position .3s calc(.3s - var(--t, 0s));
}
.hover-3:hover {
  --p: 100%;
  --t: 0.3s;
}

接下来应用开关变量进一步优化,只有一个变量--i

.hover-3 {--c: no-repeat linear-gradient(#1095c1 0 0);
  background: 
    var(--c) calc(-100% + var(--i, 0) * 100%) 100% / 50% calc(100% * var(--i, 0) + .08em),
    var(--c) calc(200% - var(--i, 0) * 100%) 0 / 50% calc(100% * var(--i, 0) + .08em);
  transition: .3s calc(var(--i, 0) * .3s), background-position .3s calc(.3s - var(--i, 0) * .3s);
}
.hover-3:hover {--i: 1;}

悬停成果四

这个成果绝对于下面的难度较大,更多的用到了圆锥突变和更多的计算。次要能够分为以下几个步骤:

  1. 有左右两个圆锥突变在元素可视区外
  2. 鼠标移入减少两个圆锥突变的宽度,直到笼罩元素
  3. 扭转整个背景区域的地位,这也是最重要的步骤
  4. 扭转后的地位,因为两个圆锥突变是同一个色彩,所以视觉上没有任何变动
  5. 鼠标移出减小圆锥突变的宽度,则能够看到反差后的动画

两个突变都须要有默认的 0 宽度和两倍的元素高度(0% 200%),每个突变的配置如下图所示:

 background-image:
    conic-gradient(from -135deg at 100%  50%, var(--c) 90deg, #0000 0),
    conic-gradient(from -135deg at 1.2em 50%, #0000 90deg, var(--c) 0);

视觉上,每个突变的宽度都是元素的一半,然而实际上并不止,因为有锥形的空隙。所以须要在一半宽度的根底上额定减少肯定的数值,这个值能够大一点,以便笼罩到整个元素。

.hover-4:hover {background-size: calc(50% + .6em) 200%;
}

优化后的代码如下:

.hover-4 {
  --c: #1095c1;
  line-height: 1.2em;
  background:
    conic-gradient(from -135deg at 100%  50%, var(--c) 90deg, #0000 0) 
      0  var(--p, 0%) / var(--s, 0%) 200% no-repeat,
    conic-gradient(from -135deg at 1.2em 50%, #0000 90deg, var(--c) 0) 
      100% var(--p, 0%) / var(--s, 0%) 200% no-repeat;
  transition: .4s, background-position 0s;
}
.hover-4:hover {
  --p: 100%;
  --s: calc(50% + .6em);
}

总结

以上总共剖析了四种悬停成果,尽管成果不同,但次要都用到了 CSS background属性、自定义属性和calc(),不同的组合状况制作进去不同的成果,然而最初的代码都是相似,最终有了极其简洁可保护的代码。基于此,这只是冰山一角,古代 CSS 的弱小还能够产出各种神奇的成果。你是否有想法来试试呢~

看到最初如果感觉有用,点赞,关注,珍藏起来吧,说不定哪天就用上啦~

专一前端开发,分享前端相干技术干货,公众号:南城大前端(ID: nanchengfe)

参考

background-position 应用百分比值

dry-switching-with-css-variables-the-difference-of-one-declaration

using-percentage-values-with-background-position-on-a-linear-gradient

cool-hover-effects-using-background-properties

退出移动版