在日常的开发过程中,你会遇到很多按钮鼠标悬停效果。有很多方法可以实现这种悬停效果。借助伪元素,可以实现CSS3变换和过渡等。今天的文章将使用背景颜色来实现类似的效果。当我们遇到一个问题,你脑子里有不止一个解决方案的时候,我觉得一定是极好的。用不同的方法达到同样的效果,或者遇到的问题总有一天会迎刃而解。今天主要实现的鼠标悬停效果如下图GIF所示。悬停效果1上图效果代码如下,只需要4行代码就可以实现效果。您是否惊讶为什么代码如此精简?接下来,我们将详细解释如何做。.hover-1{background:linear-gradient(#1095c100)var(--p,0)/var(--p,0)不重复;transition:.4s,background-position0s;}.hover-1:hover{--p:100%;color:#fff;}首先,我们从一个简单的background-sizetransition开始,如上图所示,背景颜色的高度始终保持在100%,我们只需要将Togglesitswidth从0%变为100%。因为background-size是用来改变宽度的,所以background-image:linear-gradient是用来设置背景色的。因为只有一个颜色值,所以使用#1095c100这种简写方法不需要写两个颜色值。背景图像:线性渐变(#1095c100);使用background-size时,我们可以省略高度,因为默认情况下渐变是全高。我们使用background-size:0过渡到background-size:100%。.hover-1{background-size:0;}.hover-1:hover{background-size:100%;}进一步优化,引入自定义属性避免重复background-size,--p一开始没有定义,所以将使用0%。在悬停时,我们定义--p为100%以替换初始值0%.hover-1{background-size:var(--p,0%);}.hover-1:hover{--p:100%;}至此,我们的效果如下。接下来引入background-position,实现反向效果。第一张GIF图片可以分两步完成。当鼠标悬停时,背景从右到左变大。鼠标移出时,背景从左到右变小,悬停时无法添加过渡动画。该属性需要及时生效,所以添加了background-position0s。.hover-1{背景位置:左;过渡:.4s,背景位置0s;}.hover-1:hover{--p:100%;background-position:right;}可以进一步优化,background-position的值使用百分比。.hover-1{背景位置:0%;过渡:.4s,背景位置0s;}.hover-1:hover{--p:100%;background-position:100%;}聪明的你可能已经发现悬停时的两个值都是100%,那么我们可以进一步优化两者使用自定义属性--p。.hover-1{背景:线性渐变(#1095c100)不重复;过渡:.4s,背景位置0s;背景大小:var(--p,0%);background-position:var(--p,0%);}.hover-1:hover{--p:100%;}对于背景,我们使用复合写法进一步简化代码,使用/来划分,前面是背景位置,后面是背景大小。.hover-1{background:linear-gradient(#1095c100)var(--p,0%)/var(--p,0%)不重复;transition:.4s,background-position0s;}.hover-1:hover{--p:100%;}这样就完成了悬停效果,简化了代码。基于这种设计,还可以稍微改动一下代码,让hover效果达到相反的效果。将背景位置从100%修改为0%,而不是像上面那样从0%修改为100%。为了保持--p自定义属性不变,我们使用calc()函数来处理。背景:线性梯度(#1095c100)calc(100%-var(--p,0%))/var(--p,0%)不重复;比较效果一个比较复杂,整个效果由多个动画步骤组成。初始背景区域在可见区域之外,从左向右移动覆盖整个元素的底部,然后将背景颜色更改为100%的高度覆盖整个元素。这里需要用到background-position的百分比使用方式。如果不明白怎么用,可以看文末的参考文章。技巧是把宽度改成200%,不过不用担心背景色超出后溢出的问题,元素溢出的背景色是隐藏的,代码如下。.hover-2{背景图像:线性渐变(#1095c100);背景大小:200%.08em;背景位置:200%100%;背景重复:不重复;过渡:背景大小.3s,背景位置.3s.3s;}.hover-2:hover{过渡:背景大小.3s.3s,背景位置.3s;背景大小:200%100%;background-position:100%100%;}然后继续优化代码,首先使用background的复合写法来简化和减少额外的声明。.hover-2{background:linear-gradient(#1095c100)no-repeatvar(--p,200%)100%/200%var(--p,.08em);过渡:.3svar(--t,0s),background-position.3scalc(.3s-var(--t,0s));}.hover-2:hover{--p:100%;--t:.3s;}这里添加一个自定义变量--t,当鼠标悬停时,我们设置为.3s,最终代码如下:transition:.3s.3s,background-position.3s0s;当鼠标移出时,--t未定义,最后代码如下:transition:.3s0s,background-position.3s.3s;到目前为止,当鼠标悬停时,声明了两个变量。我们可以通过一个属性进一步优化和更新多个属性。如何生成这样的代码可以在文末的参考链接中找到。最终代码修改如下:.hover-2{background:linear-gradient(#1095c100)no-repeatcalc(200%-var(--i,0)*100%)100%/200%calc(100%*var(--i,0)+.08em);过渡:.3scalc(var(--i,0)*.3s),背景位置.3scalc(.3s-calc(var(--i,0)*.3s));}.hover-2:hover{--i:1;}--i最后是undefined,那么就是0,悬停时更新为1,这个变量就像JS中的switch变量。至此,整个效果只需要三行css声明即可完成。悬停效果三该效果在效果二的基础上扩展为两种渐变动画效果。一开始会有两个渐变溢出元素,默认不在视野范围内,每个元素的宽度都是整个元素的一半。将这两个溢出元素修改为鼠标移入可见区域。第一个渐变位于左下角,第二个渐变位于右上角,最后增加高度覆盖整个元素。初始CSS代码如下,和效果2的代码几乎一样,唯一不同的是动画效果同时出现的位置有两个不同,这里也使用了百分比background-position..hover-3{背景图像:线性渐变(#1095c100),线性渐变(#1095c100);背景重复:不重复;背景大小:50%.08em;背景位置:-100%100%,200%0;过渡:背景大小.3s,背景位置.3s.3s;}.hover-3:hover{背景大小:50%100%;背景位置:0100%,100%0;transition:background-size.3s.3s,background-position.3s;}接下来开始优化代码,后台复合写法,自定义属性和calc()进一步整理,这里多了一个--c自定义属性,因为它在后台使用了两次。.hover-3{--c:无重复线性渐变(#1095c100);背景:var(--c)calc(-100%+var(--p,0%))100%/50%var(--p,.08em),var(--c)calc(200%-var(--p,0%))0/50%var(--p,.08em);过渡:.3svar(--t,0s),背景位置.3scalc(.3s-var(--t,0s));}.hover-3:hover{--p:100%;--t:0.3s;}接下来使用switch变量进一步优化,只有一个变量--i.hover-3{--c:no-repeatlinear-gradient(#1095c100);背景:var(--c)calc(-100%+var(--i,0)*100%)100%/50%calc(100%*var(--i,0)+.08em),var(--c)计算(200%-var(--i,0)*100%)0/50%计算(100%*var(--i,0)+.08em);过渡:.3scalc(var(--i,0)*.3s),背景位置.3scalc(.3s-var(--i,0)*.3s);}.hover-3:hover{--i:1;}hover效果四这个效果相对于上面的难度更大,使用了更多的锥形渐变和更多的计算量。主要可以分为以下几个步骤:有左右两个锥体梯度。将鼠标移到元素可见区域外,增加两个锥形渐变的宽度,直到覆盖元素改变整个背景区域的位置。这也是改版后最重要的一步。位置,因为两个锥形渐变颜色相同,所以视觉上没有变化高度(0%200%),每个渐变的配置如下图所示:background-image:conic-gradient(from-135degat100%50%,var(--c)90deg,#00000),conic-gradient(from-135degat1.2em50%,#000090deg,var(--c)0);从视觉上看,每个渐变的宽度都是元素的一半,但实际上它并没有停止,因为有一个渐变的间隙。所以需要在一半宽度的基础上加上一定的值,这个值可以大一些,覆盖整个元素。.hover-4:hover{background-size:calc(50%+.6em)200%;}优化后的代码如下:.hover-4{--c:#1095c1;行高:1.2em;背景:圆锥梯度(从-135deg到100%50%,var(--c)90deg,#00000)0var(--p,0%)/var(--s,0%)200%no-重复,圆锥梯度(从-135degat1.2em50%,#000090deg,var(--c)0)100%var(--p,0%)/var(--s,0%)200%不重复;transition:.4s,background-position0s;}.hover-4:hover{--p:100%;--s:calc(50%+.6em);}总结虽然效果不一样,主要是用到CSS背景属性,自定义属性和calc()。不同的组合产生不同的效果,但是最终的代码都是相似的,最终得到了一个极其简洁和可维护的代码。基于此,这只是冰山一角,现代CSS的强大功能还可以产生各种神奇的效果。有没有想法试试看~如果最后觉得有用,点赞,关注,收藏,说不定哪天会用到呢~专注前端开发,分享前端相关技术干货,公众号:南城大学前端(ID:nanchengfe)参考背景-positionusingpercentagevaluesdry-switching-with-css-variables-the-difference-of-one-declarationusing-percentage-values-with-background-position-on-a-linear-gradientcool-hover-effects-using-background-properties
