0行JS,30行css搞定导航栏下划线跟随效果

前言

在码代码之前了,我们可以尝试思考一下上面的效果或者动手尝试一下,不借助 JS ,能否巧妙的实现上述效果?

在这之前了,有一次需求就是实现这个效果,我是用js实现的。其实用 Javascript ,也是很麻烦。所以我一直在想,有没有可能只使用 CSS 完成这个效果呢?

好的,今天我们就用CSS完成这个效果。

解析

我们定义一下简单的规则,要求如下:

1、假设 HTML 结构如下:

<ul class="cssnav">
  <li>Web秀</li>
  <li>CSS导航栏</li>
  <li>今日头条</li>
  <li>开源中国</li>
</ul>

2、li 的宽度是不固定的 3、当从左侧 li 移向右侧 li,下划线从左往右移动。同理,当从导航的右侧 li 移向左侧 li,下划线从右往左移动。

看整个效果,我们不知道如何做起的时候,我们先一步一步来,先完成前2个效果。

第一步

.cssnav {
    position: absolute;
    display: flex;
}

.cssnav li {
    position: relative;
    list-style: none;
    padding: 20px;
    font-size: 24px;
    color: #000;
    line-height: 1;
    cursor: pointer;
}

这里用到了flex布局,相信一直和我一起学习的小伙伴,应该都会了,这里不做过多的解释了,不明白的,请看:

《CSS中Flex布局的可伸缩性(Flexibility)》 《CSS3中Flex布局(弹性布局)》 《CSS3实现瀑布流布局(display: flex/column-count/display: grid)》

第二步

很多小伙伴,应该第一想法是用border-bottom来实现下面的底边效果。但是是不是忽视了整个li是不能移动的了?所以这个是行不通的,我们用:before伪类来实现底边,同时可以移动。

li::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    border-bottom: 2px solid #000;
}

这样,我们距离成功越来越近了。

下面我们考虑动画部分,hover 的时候,下划线要从一侧展开。所以,我们利用绝对定位,将 li 的伪元素的宽度设置为0,在 hover 的时候,宽度从 width: 0 -> width: 100%,CSS 如下:

li::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 0;
    height: 100%;
    border-bottom: 2px solid #000;
}

li:hover::before {
    width: 100%;
}

额,这时候的效果并不对,好像缺少了过渡效果,很僵硬。于是添加过渡效果。

li::before {
    ...
    transition: 0.2s all linear;
}

于是,就有了这个效果。细心的小伙伴是不是发现,效果还是不对了?如果看不出来的小伙伴,可以把过渡效果时间设置长一点(0.5s)。第一个 li 的方向是正确了,但是第二个 li下划线的移动方向又错误了。

~ 选择符

所以,我们需要一种方法,能够不改变当前 hover 的 li 的下划线移动方式,却能改变它下一个 li 的下划线的移动方式。

这里我们可以借助 ~ 选择符,完成最重要的部分。

对于当前 hover 的 li ,其对应伪元素的下划线的定位是 left: 100%,而对于 li:hover ~ li::before,它们的定位是 left: 0。

li:hover::before {
    width: 100%;
    left: 0;
}

li:hover ~ li::before {
    left: 0;
}

ok,效果已经全部搞定,是不是超级简单了?

如果觉得效果有点僵硬,我们可以再添加动画延迟。

li:hover::before {
    width: 100%;
    top: 0;
    left: 0;
    transition-delay: 0.1s;
    border-bottom-color: #000;
    z-index: -1;
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏脑洞前端

CSS系列漫画教程(1~10讲)

《CSS系列漫画教程》共15讲,是我2012年刚毕业步入互联网时的早期作品。时隔多年,如今互联网内容为王的分享经济迅速发展,这些作品压箱底太可惜,不如分享给大家...

7440
来自专栏每天学点Android知识

三谈属性动画——Keyframe以及ViewPropertyAnimator

经过初识属性动画——使用Animator创建动画和再谈属性动画——介绍以及自定义Interpolator插值器,对属性动画已经介绍的差不多了,还剩下最后两个概念...

9830
来自专栏每天学点Android知识

仿抖音发布按住拍呼吸效果

上面两个按钮,都是采用属性动画进行控制的,但实现细节稍有不同,左上采用的是StateListAnimator,只需要考虑跟随手指动就可以了;右下是在onTou...

9210
来自专栏每天学点Android知识

让View跟随状态动起来——StateListAnimator

StateListAnimator定义了一组动画,可以根据View drawable的状态进行不同的切换。所谓状态指的是statepressed、stateen...

15020
来自专栏每天学点Android知识

让View具有弹性效果的动画——SpringAnimation

SpringAnimation和FlingAnimation一样,是DynamicAnimation的两种类型。Spring模拟的是物理世界的弹力,弹弹弹,弹走...

10060
来自专栏叉叉敌

微信小程序-自动适配屏幕高度和宽度

微信小程序里面的height和width有几种单位,分别是 rpx px vh 和 vw。

1.2K20
来自专栏每天学点Android知识

使用动画缩放图片

我们的app经常遇到这样一种场景,就是小图到大图的转换,这时候如果有个缩放动画就会很自然。本节将介绍如何使用动画进行缩放图片,在点击头像看大图这种场景可以使用。...

8820
来自专栏编程微刊

CSS去掉input框里面的默认字体颜色

但是经过测试之后,发现浏览器记住密码之后,输入框字体颜色发生改变,变成了黑色,很影响美观。

51910
来自专栏每天学点Android知识

让View具有减速效果的动画——FlingAnimation

Google除了提供了属性动画之外,还提供了一种基于物理的动画,叫做DynamicAnimation,与物理世界更贴近,关于这块可以参考https://www....

6620
来自专栏智能计算时代

「微前端架构」微前端-Angular风格-第2部分

在前一部分中,我讨论了转向MFE解决方案的动机以及解决方案相关的一些标准。在这一部分中,我将介绍我们如何在Outbrain实现它。

11320

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励