日常开发过程中,会遇到不少按钮鼠标悬停的成果,实现这类悬停成果的形式有很多,借助伪元素,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