顶部菜单栏中放置搜索框是一个常见的场景,但如果搜索功能使用的不那么频繁,同时菜单栏中内容本来就比较拥挤,再放一个完整的搜索框在那就显得不那么美观。

因此,也有一个挺常见的做法是,只放一个搜索图标,需要时再显示整个搜索框,如下图所示:


实现思路

起始状态时搜索框没有显示,鼠标移入后从右侧滑入,因此不能使用搜索框自身的 hidden 或透明度属性,需要使用父元素的 overflow: hidden 将其隐藏,并把输入框移动到父元素的显示范围以外,需要时再移动回来。

css 中有 transition 和 animation 两种方式来实现动画效果,由于这里只有搜索框位置移动、图标透明度改变两个简单效果,用 transition 就足够了。

这两个动画本身实现很简单,但有一些小细节:

两个动画不是同时进行,而是有先后,需要使用 transition-delay 实现两个效果的序列

显示、隐藏两个过程好像完全一样,但仔细看会发现动画的顺序有不同:显示时图标先消失、搜索框后移入;隐藏时搜索框先移出、图标后出现。因此需要单独设置。

代码实现

完整的样式表附在文末,不想看具体思路的可以跳过本节直接去复制。

基础样式

先普普通通的写一下基础样式,这里用的图标是 material design icon。

<div class="search">

  <input class="bar" placeholder="请输入内容" />

  <span class="material-icons icon">search</span>

</div>

.icon {

  width: 24px;

  height: 24px;

}

.bar {

  height: 26px;

  width: 200px;

  padding: 1px 9px;

  border: #fff 1px solid;

  border-radius: 3px;

  background-color: transparent;

  color: #fff;

}

::placeholder {

  color: #ccc;  /* 修改input中placeholder的颜色*/

}

.search {

  height: 30px;

  display: flex;

  align-items: center;

}

隐藏搜索框

移动搜索框位置的方法有很多,比如可以使用 absolute 或者 relative 定位。

如果将搜索框设为 absolute 定位(position: absolute),搜索框会从输入流中抽出,通俗的说就是父元素在渲染时会当它不存在,这样父元素的宽度、搜索图标的位置都需要额外指定。

相比之下,relative 定位(position: relative)只是简单地移动元素的位置,对其他元素没有任何影响,在此处使用更加简单一些。

还有一种更直接的方法:transform 属性。通过这个属性,可以实现对元素的平移、旋转、缩放等变形操作,同时对其他元素不产生影响。

在这里使用的 translateX() 属性就是将元素沿X轴(横向)平移指定距离。单从平移来说,各方面效果和使用 relative 定位没有明显区别。

PS: transition, transform, translate 这几个词不会只有我一直分不清吧555

.search {

  overflow: hidden;

}

.bar {

  transform: translateX(224px);

  /* 

    上一句也可以替换为下面两句,效果相同

    position: relative;

    left: 224px;

  */

}

动画序列

动画通过 transition 属性实现。transition 是 transition-property,transition-duration,transition-timing-function 和 transition-delay 四个属性的简写(类比border: red 1px solid;),四个属性分别指定了过渡动画的属性、持续时间、时间曲线、延迟时间。

属性即要应用过渡动画的属性

时间曲线是动画的速度变化,比如开始慢、中间快、结束慢,可以比匀速运动更好看更平滑。

延迟时间即达到触发条件后延迟一段时间再触发动画,可以用来实现多个动画有先后顺序地执行。

transition 属性本质上是小学电脑课学过的 flash 补间动画,指定一个属性的起止两个状态,自动补全中间的过渡动画。

元素本来的属性是起始状态,鼠标移上后的动画,自然元素的 :hover 伪类属性是终止状态。

.icon {

  opacity: 1;

  transition: opacity 0.3s ease; /* delay 属性默认值为0 */

}

.search:hover .icon {

  opacity: 0;

}

.bar {

  transform: translateX(224px);

  transition: transform 0.3s ease-in-out 0.3s;

}

.search:hover .bar {

  transform: translateX(24px);

}

逆向序列

这样能够基本实现想要的动画效果了,但是在隐藏搜索框的时候也是图标先出现,搜索框后滑出,不够美观。

解决方案也很简单,为 hover 伪类单独设置不同的 delay 属性即可。

有一点需要注意一下,hover 伪类中的 delay 属性对应的是鼠标移上时的延迟,元素本身属性中的 delay 对应的是鼠标移出时恢复动画的延迟。

可能和第一反应不太一样(不过仔细想想倒也挺合理的),别写反了。

.icon {

  transition: opacity 0.3s ease 0.3s;

}

.search:hover .icon {

  transition-delay: 0s;

}

.bar {

  transition: transform 0.3s ease-in-out 0s;

}

.search:hover .bar {

  transition-delay: 0.3s;

}

触发区域

其实但就想要的动画效果,以上几步就足够了。但是这样还有一个小问题:动画是通过父元素 .search 的 hover 状态触发的,因此如果鼠标移入搜索图标左侧本来应该是搜索框的位置(但是现在什么也没有,被隐藏了),还是会触发显示搜索框动画。

这其实也不是不能接受。

如果想只在鼠标悬停在图标时才触发动画,只要将触发条件改成 .icon 的悬停状态即可。

不过由于 css 中只有后继元素选择器而没有前驱元素选择器(因为 DOM 渲染 CSS 的原则是不能出现回溯),需要调整一下 html 中图标和搜索框的顺序。

<div class="search">

  <span class="material-icons icon">search</span>

  <input class="bar" placeholder="请输入内容" />

</div>

然后修改相应的样式和选择器即可。

.icon:hover {

  opacity: 0;

  transition-delay: 0s;

}

.icon:hover + .bar {  /* + 紧邻兄弟选择器 */

  transform: translateX(24px);

  transition-delay: 0.3s;

}

.search {

  display: flex;

  flex-direction: row-reverse;  /* 让搜索框还在图标左边 */

}

附录:完整样式表

<div class="search">

  <span class="material-icons icon">search</span>

  <input class="bar" placeholder="请输入内容" />

</div>

.icon {

  width: 24px;

  height: 24px;

  opacity: 1;

  transition: opacity 0.3s ease 0.3s;

}

.icon:hover {

  opacity: 0;

  transition-delay: 0s;

}

.bar {

  height: 26px;

  width: 180px;

  padding: 1px 9px;

  border: #fff 1px solid;

  border-radius: 3px;

  background-color: transparent;

  color: #fff;

  transform: translateX(224px);

  transition: transform 0.3s ease-in-out 0s;

}

.icon:hover + .bar {

  transform: translateX(24px);

  transition-delay: 0.3s;

}

::placeholder {

  color: #ccc;

}

.search {

  height: 30px;

  display: flex;

  flex-direction: row-reverse;

  align-items: center;

  overflow: hidden;

}

本文完~


点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

热门产品

历史上的今天:03月29日

热门专题

卓越综合高中|卓越综合高中
卓越综合高中
安徽开放大学|安徽开放大学报名,安徽开放大学报考,安徽开放大学,什么是安徽开放大学,安徽开放大学学历,安徽开放大学学费,安徽开放大学报名条件,安徽开放大学报名时间,安徽开放大学学历,安徽开放大学专业
安徽开放大学
开放大学|开放大学报名,开放大学报考,开放大学,什么是开放大学,开放大学学历,开放大学学费,开放大学报名条件,开放大学报名时间,开放大学学历,开放大学专业
开放大学
金诺幼儿园(春城路金诺幼儿园)|昆明官渡区幼儿园,幼儿园报名,官渡区幼儿园,春城路幼儿园,幼儿园招生,学前班,昆明幼儿园,金诺幼儿园,环城南路幼儿园,石井路幼儿园
金诺幼儿园(春城路金诺幼儿园)
大理科技管理学校|大理科技管理学校,大理科技,大理科技中等职业技术学校,大理科技管理中等职业技术学校,大理科技学校
大理科技管理学校
昆明网站建设|昆明网站建设,昆明网站开发,昆明网站建设公司,昆明网站建设价格,昆明网站设计,昆明网站制作,网页设计,高端网站建设,高端网站设计
昆明网站建设
云南网站建设|云南网站制作,网站建设,云南网站开发,云南网站设计,云南网页设计,云南网站建设公司,云南网站建设
云南网站建设
中源管业|中源管业,中源管业公司,中源管业有限公司,中源管业电话,中源管业地址,中源管业电力管,中源管业mpp电力管,中源管业cpvc电力管,中源管业pe穿线管
中源管业

微信小程序

微信扫一扫体验

立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部