阅读 1541

纯css实现:仿掘金账户密码登录时,小熊猫捂眼动作切换的小彩蛋

这是我参与更文挑战的第7天,活动详情查看: 更文挑战

前言

今天在浏览器登录掘金的时候,发现使用 “账密登录” 时,掘金小熊猫会随着当前鼠标焦点不同而改变,这个小彩蛋看起来很有意思的样子。如下图:

GIF 2021-6-7 16-03-24.gif

刚好最近几天看css多一些,我就想,能不能使用css来实现同样的效果呢?

想要用css实现同样的效果,要确保两点:

  • 可以监听到当前焦点
  • 监听到某焦点时改变其他元素的样式

说到监听到当前焦点,首先我们想到的是监听当前获取焦点元素的伪类 :focus选择器 ,它可以选择获得焦点的输入字段,并设置其样式。此处提个问题给各位看官:除了 :focus选择器 ,还有更适合本场景的css伪类吗?

那么当我监听到 input 获取了焦点之后,如何去改变其他元素的样式呢?很明显,css没有父级选择器,无法选择父级元素,所以要把img和input放在同级下。我采取改变兄弟元素样式的方式去改变掘金小熊猫样式的显示隐藏。

思路有了,下面就是实践了,撸起袖子说干就干,首先去把掘金小熊猫的图扒出来,这里不得不吐槽一下掘金的UI同学,三种状态的小熊猫,图片尺寸竟然是完全不同的,掘金的前端小伙伴分别给这三个图片加了三个尺寸,简直是蜜汁操作~ 有图有真相:

image.pngimage.pngimage.png

吐槽结束的我兴致满满,然后三下五除二我就把页面结构样式来构建出来了:

:focus伪类

结构:

<div class="login-form">
    <h2>账密登录</h2>
    <div class="form-item form-tel">
        <input maxlength="64" placeholder="邮箱/手机号(国际号码加区号)">
        <img src="https://sf3-scmcdn2-tos.pstatp.com/xitu_juejin_web/img/greeting.1415c1c.png" class="greeting">
        <img src="https://sf3-scmcdn2-tos.pstatp.com/xitu_juejin_web/img/normal.0447fe9.png" class="normal">
    </div>
    <div class="form-item form-password">
        <input class="form-password" type="password" maxlength="64" placeholder="请输入密码">
        <img src="https://sf3-scmcdn2-tos.pstatp.com/xitu_juejin_web/img/blindfold.58ce423.png" class="blindfold">
        <img src="https://sf3-scmcdn2-tos.pstatp.com/xitu_juejin_web/img/normal.0447fe9.png" class="normal">
    </div>
    <button class="btn-submit">登录</button>
</div>
复制代码

样式:

*{
    margin: 0;
    padding: 0;
}
body{
    background-color: #e9e9e9;
}
.login-form {
    width: 370px;
    margin: 100px auto;
    padding: 24px;
    background-color: #fff;
    position: relative;
    h2{
        color: #333;
        font-size: 18px;
        margin-bottom: 24px;
    }
    input {
        outline: none;
        padding: 10px;
        margin-bottom: 10px;
        width: 100%;
        border: 1px solid #e9e9e9;
        border-radius: 2px;
        outline: none;
        box-sizing: border-box;
        font-size: 16px;
    }
    input:focus{   
        border-color: #007fff;
    }
    img{
        width: 120;
        height: 95px;
        position: absolute;
        top: 0;
        left: 50%;
        transform: translate(-50%,-50%);
    }
    img.greeting,
    img.blindfold
    {
        display: none;
    }   
    .form-tel{
        img.greeting{
            height: 113px;
        }
        input:focus ~ img.greeting{
            display: block;
        }   
        input:focus ~ img.normal{
            display: none;
        }   
    } 
    
    .form-password{
        img.blindfold{
            width: 103px;
            height: 84px;
        }
        input:focus ~ img.blindfold{
            display: block;
        }   
        input:focus ~ img.normal{
            display: none;
        }   
    } 
    .btn-submit{
        width: 100%;
        height: 40px;
        color: #fff;
        background-color: #007fff;
        border-radius: 2px;
        outline: none;
        box-sizing: border-box;
        cursor: pointer;
        margin-top: 10px;
        border: none;
        padding: 8px 20px;
    }
}
复制代码

放到浏览器,运行一看,好家伙,失败了!

GIF 2021-6-7 16-55-42.gif

原来我不能在第一个input获取焦点的时候,去改变第二个input的兄弟元素样式。所以导致获取焦点的时候,虽然把当前input的兄弟元素图片隐藏了,但是另一个input的兄弟元素并没有隐藏,所以看起来会显示两张图片,而不是我以为的一张图片。并且上面的html代码以及css代码看起来都有大量的冗余,不利于阅读。

还记得我在前面提的问题吗?除了 :focus选择器 ,还有更适合本场景的css伪类吗?

:focus-within伪类

当然有更适合的伪类啦,那就是 :focus-within 伪类,它表示一个元素获得焦点,或该元素的后代元素获得焦点。换句话说,元素自身或者它的某个后代匹配 :focus 伪类就会触发它,类似于js中的冒泡。

有了这个伪类,我就可以把结构变得更清晰,样式代码也能更加优雅的实现。

所以我重新改写了代码:

结构:

<div class="login-form">
    <h2>账密登录</h2>
    <div class="form-item form-tel">
        <input maxlength="64" placeholder="邮箱/手机号(国际号码加区号)">
        <img src="https://sf3-scmcdn2-tos.pstatp.com/xitu_juejin_web/img/greeting.1415c1c.png" class="greeting">
    </div>
    <div class="form-item form-password">
        <input class="form-password" type="password" maxlength="64" placeholder="请输入密码">
        <img src="https://sf3-scmcdn2-tos.pstatp.com/xitu_juejin_web/img/blindfold.58ce423.png" class="blindfold">
    </div>
    <img src="https://sf3-scmcdn2-tos.pstatp.com/xitu_juejin_web/img/normal.0447fe9.png" class="normal">
    <button class="btn-submit">登录</button>
</div>
复制代码

样式:

*{
    margin: 0;
    padding: 0;
}
body{
    background-color: #e9e9e9;
}
.login-form {
    width: 370px;
    margin: 100px auto;
    padding: 24px;
    background-color: #fff;
    position: relative;
    h2{
        color: #333;
        font-size: 18px;
        margin-bottom: 24px;
    }
    input {
        outline: none;
        padding: 10px;
        margin-bottom: 10px;
        width: 100%;
        border: 1px solid #e9e9e9;
        border-radius: 2px;
        outline: none;
        box-sizing: border-box;
        font-size: 16px;
    }
    input:focus{   
        border-color: #007fff;
    }
    img{
        width: 120;
        height: 95px;
        position: absolute;
        top: 0;
        left: 50%;
        transform: translate(-50%,-50%);
    }
    .form-tel img{
        height: 113px;
    }
    .form-password img{
        width: 103px;
        height: 84px;
    }
    .form-item img{
        display: none;
    }
    .form-item:focus-within ~ img{
        display: none;
    }   
    .form-item:focus-within {   
        img {
            display: block;
        }
    }
    .btn-submit{
        width: 100%;
        height: 40px;
        color: #fff;
        background-color: #007fff;
        border-radius: 2px;
        outline: none;
        box-sizing: border-box;
        cursor: pointer;
        margin-top: 10px;
        border: none;
        padding: 8px 20px;
    }
}
复制代码

看起来结构及样式是不是好了很多?无论从阅读性还是迭代性来说,都有了巨大的提升(此处省略自吹自擂3000字)…… 那么让我们运行到浏览器来看看吧~

GIF 2021-6-7 17-06-45.gif

大功告成啦!!!

后记

掘金的小彩蛋还是挺多的,有时高端的样式往往只需要最朴素的实现方式,比如掘金网站实现这个效果的方法是js,说起来,js实现起来可能更灵活,但css实现会更有意思,没有孰是孰非,能达到实现的效果即可。

本文旨在提供css彩蛋相关的思路,如果对你有帮助,点个赞就好,如果有错误欢迎指出交流。感谢阅读~

PS: 今天是参加掘金更文挑战的第7天啦,没有存稿的我,周一依然战战兢兢的努力更文,今天的文章用了将近2小时,有进步,加油吧~

虽然没多少人看,也还是给自己引引流吧~ 更文挑战的文章目录如下:

文章分类
前端
文章标签