先来看一个很常见的搜索框的交互,大概逻辑如下
- 当输入框有内容才显示清除按钮
- 点击清除按钮输入框会清空
- 当输入框有内容并且处于聚焦情况下才显示搜索结果浮层
- 点击搜索条目后关闭整个搜索结果浮层
示意如下
看着逻辑好像很多的样子,其实也是可以纯 CSS 实现的,花两三分钟一起看看吧
一、输入框清除按钮的交互
首先来看原生的实现方式。
1. HTML5 新增表单元素
在 HTML5 中新增了type=search
的表单,如下
<input class="input" type="search" placeholder="请输入关键词">
天然就支持清除功能
然后只需要美化一下默认的清除按钮就可以了,chrome 中可以使用::-webkit-search-cancel-button
,ie 中可以使用::ms-clear
,这里以 chrome 为例
[type=search]::-webkit-search-cancel-button{ -webkit-appearance: none; width: 36px; height: 36px; border: 0; background: url("data:image/svg+xml,%3Csvg background-size: 16px; cursor: pointer; opacity: .4; transition: .2s; }
这样就可以了
2. firefox 下的实现
不过呢,上面这种方式在 firefox 中是无效的,firefox 中并没有清除按钮,表现和普通输入框一致(下图为firefox表现)
如果是 PC 端并且面向用户,firefox 还是不能忽略的,那如何处理呢?
可以先手动添加一个按钮
<input class="input" type="search" placeholder="请输入关键词"> <button class="clear"></button>
然后适当美化一下(相信不是什么难事),可以得到这样的效果
现在清除按钮和输入框没啥关联,如何做到有输入内容时才显示清除按钮呢?
可以这样来思考:有内容表示非空,表示必填项,提到必填项可以想到 required
属性,当有内容时,表示合法的,可以匹配:valid
选择器,这样就能区分开来了。具体实现如下
给 input加一个required
属性
<input class="input" placeholder="请输入关键词" required> <button class="clear"></button>
然后默认隐藏清除按钮,配合相邻选择器+
就可以实现啦~
.clear{ visibility: hidden; } .input:valid+.clear{ visibility: visible; }
效果如下(下图为firefox表现)
然后是清除输入框的功能,如果不借助 JS,有什么办法可以清空输入框呢?
在 HTML5 表单中,可以通过 type=reset
直接重置所有内容,所以这里需要修改一下结构,将外层 div
改为form
,然后给button
添加type=reset
属性,如下
<form class="search"> <input class="input" placeholder="请输入关键词"> <button class="clear" type="reset"></button> </form>
这样就能清空搜索框了(下图为firefox表现),当然其他浏览器也是支持的
这种方式略有遗憾的地方是清除以后输入框没能聚焦
二、搜索提示浮层自动显示
先加上搜索提示的 HTML 结构
<div class="search"> <input class="input" placeholder="请输入关键词" /> <div class="search-list"> <a class="search-item">搜索结果1</a> <a class="search-item">搜索结果2</a> <a class="search-item">搜索结果3</a> </div> </div>
搜索结果默认是隐藏的,然后在输入框有内容(:valid
),并且在聚焦情况下(:focus
)才显示,配合兄弟选择器~
可以实现如下:
.search-list{ position: absolute; visibility: hidden; } .input:focus:valid~.search-list{ visibility: visible; }
效果如下
三、搜索提示浮层上的事件
上面的效果看着好像没啥问题,点击搜索条目后整个搜索结果确实关闭了。
但其实只要是有问题的,点击关闭是由于输入框失去了焦点,如果在搜索条目上添加点击事件,有可能还没触发事件就关闭了,比如
<form class="search"> <input class="input" placeholder="请输入关键词"> <div class="search-list"> <a class="search-item" onclick="console.log(1)">搜索结果1</a> <a class="search-item">搜索结果2</a> <a class="search-item">搜索结果3</a> </div> </form>
效果如下,在点击的时候并没有触发 click 事件(控制台没有打印)
原因其实很简单,click 其实可以看成是 mousedown → mouseup,在 mousedown 后立刻失焦,还没等 mouseup 就关闭提示悬浮层了,所以事件并未触发。
为了解决这个问题,可以把 onclick换成onmousedown,但是这样显然没有从根本解决,比如很多时候搜索条目上是href
属性
<div class="search-list"> <a class="search-item" href="?id=1">搜索结果1</a> </div>
这样也无法正确的跳转。
那如何解决呢?
这里有一个非常简单的小技巧,在点击的时候强制显示不就可以了吗?点击可以用:active
来匹配,所以可以这样来实现:
.input:focus:valid~.search-list, .search-list:active{ /*点击的时候也显示*/ visibility: visible; }
这样就能正常的触发点击和跳转事件了(控制台有打印)
完整代码可以访问 CSS search (codepen.io)点击预览
兼容 firefox 的完整代码可以访问 CSS search firefox (codepen.io)点击预览
四、总结和说明
以上实现了一个搜索输入相关的交互效果,没有布局方面的技巧,核心在于选择器的合理使用,下面总结一下实现重点:
- 输入框可以使用 HTML5 新增的
type=search
属性,天然支持清除功能,可惜 firefox 不支持 - 输入框设置
requred
属性后结合:valid
选择器可以判断是否有内容 - 在 form 表单里可以通过
type=reset
的 button 重置输入的内容 - 点击失效的原因是输入框先于点击事件失焦,可以用
:active
来匹配点击相关行为 - 各种选择器结合使用可以实现更加灵活的交互效果
- 兼容性 IE 10+,几乎可以生产环境使用
使用 CSS 完成交互的好处是容错率更高,不会导致网站崩溃,性能也更好,很多时候 js 出现错误导致整个网站直接白屏,完全不可用,CSS 就不存在这样的问题啦~ 如果觉得还不错,对你有帮助的话,欢迎点赞、收藏、转发