上次发完 难以想象的纯 CSS 导航栏下划线跟随效果 这篇文章以后,不少朋友找我讨论,感叹 CSS 的奇妙。css
而后昨天,群里一位朋友问到了一个和这个效果比较相似的效果,问如何git
将下面这个动画的下划线效果,从左进入,右边离开修改成从上方进入,下方离开。github
描述很难理解,看看本来的效果:函数
第一眼看到这个效果,个人心里毫无波澜。觉得只是简单的一个下划线 hover 效果,通过友人提醒,才发现,这个动画效果中,下划线是从一端进入,从另一端离开的。并且,这个 hover 动画是纯 CSS 实现的。动画
先不考虑上面说的修改需求,先想想,若是就是还原上述效果,仅仅使用 CSS,该如何作呢?spa
嗯,正常而言,咱们一个 hover 效果,可能就是从哪里来,回哪里去,大部分的应该是这样的:3d
如今,难点就在于如何在 hover 离开的时候,改变更画行进的方向。code
下面咱们将一个 hover 动画分解为 3 个部分:orm
可是,对于一个 hover 效果而言,正常来讲,只有初始状态,和hover状态两种。可能咱们的代码是这样:blog
div { xxxx... } div:hover { xxxx... }
对于一个 hover transition 动画,它应该是从:
因此,必需要有一种方法,可以使得 hover 动画的进入与离开产生两种不同的效果,实现:
因此,这里的关键点就在于(划重点):
使得 hover 动画的进入与离开产生两种不同的效果 。
接下来,也就是本文的关键所在,使用 transform: scale()
以及 transform-origin
实现这个效果。
transform: scale()
实现线条运动transform: scale 你们应该都很熟悉了,通俗来讲是用于缩放,用官方的话说,就是:
CSS 函数 scale() 用于修改元素的大小。能够经过向量形式定义的缩放值来放大或缩小元素,同时能够在不一样的方向设置不一样的缩放值。
这里咱们使用 transform: scaleX(0)
与 transform: scaleX(1)
来改变线条的显示与隐藏,它的 CSS 代码简单来看,多是这样:
div { position: absolute; width: 200px; height: 60px; } div::before { content: ""; position: absolute; left: 0; bottom: 0; width: 200px; height: 2px; background: deeppink; transition: transform .5s; transform: scaleX(0); } div:hover::before { transform: scaleX(1); }
嗯?为何是要用 transform: scale()
来实现线条的动画?由于它能够配合 transform-origin
实现动画的不一样运动方向:
transform-origin
实现线条运动方向transform-origin
让咱们能够更改一个元素变形(transform)的原点,transform-origin
属性可使用一个,两个或三个值来指定,其中每一个值都表示一个偏移量。 没有明肯定义的偏移将重置为其对应的初始值。
本效果最最最重要的地方就在于这里,咱们使用 transform-origin
去改变 transform: scale()
的原点实现线条运动的方向。
transform-origin
记为状态1transform-origin
, 记为状态2因此,固然咱们 hover 的时候,会读取状态2的transform-origin
,从该原点开始放大至 scaleX(1)
,hover 离开的时候,会读取状态1的transform-origin
,从scaleX(1)
状态缩小至该原点。
嗯,CSS代码大概是这样:
div { position: absolute; width: 200px; height: 60px; } div::before { content: ""; position: absolute; left: 0; bottom: 0; width: 200px; height: 2px; background: deeppink; transition: transform .5s; transform: scaleX(0); transform-origin: 100% 0; } div:hover::before { transform: scaleX(1); transform-origin: 0 0; }
这里,咱们巧妙的经过 hover 状态施加了一层新的 transform-origin
,让动画的进入与离开产生了两种不一样的效果,两个不一样的方向。
如此一来,也就顺利实现了咱们想要的效果,撒花:
注意,这里使用了 transform-origin
去改变 transform: scale()
的原点实现线条运动的方向,而没有借助诸如 position
位移,transform: translate()
,或者 margin 等位置属性去改变线条所在的位置。
因此,有趣的是,线条其实没有产生过任何位移,这里其实也是障眼法,让它看上去,它好像在移动。
嗯,有了上述方法,也就是 transform: scale()
配合 transform-origin
,咱们能够开始随意改变更画的初始与结束状态了。把他们运用到其余效果之上,简单的几个示意效果:
还有几个点是比较有意思的,你们能够尝试尝试,思考思考:
transition-timing-function
缓动函数,可让动画更加流畅具备美感;transition
设置的是 transition: transform .5s
而不是 transition: all .5s
,体验一下两种写法所产生的不一样效果。
本方法我我的最先见于 Css菜单悬停效果。若是你有更好的方法欢迎提出共同探讨。
更多精彩 CSS 技术文章汇总在个人 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。
好了,本文到此结束,但愿对你有帮助 :)
若是还有什么疑问或者建议,能够多多交流,原创文章,文笔有限,才疏学浅,文中如有不正之处,万望告知。
个人博客即将搬运同步至腾讯云+社区,邀请你们一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=3ly2fi88twowo