14
头图

先来看一个很常见的搜索框的交互,大概逻辑如下

  1. 当输入框有内容才显示清除按钮
  2. 点击清除按钮输入框会清空
  3. 当输入框有内容并且处于聚焦情况下才显示搜索结果浮层
  4. 点击搜索条目后关闭整个搜索结果浮层

示意如下

Kapture 2021-10-30 at 16.00.02

看着逻辑好像很多的样子,其实也是可以纯 CSS 实现的,花两三分钟一起看看吧

一、输入框清除按钮的交互

首先来看原生的实现方式。

1. HTML5 新增表单元素

在 HTML5 中新增了type=search的表单,如下

<input class="input" type="search" placeholder="请输入关键词">

天然就支持清除功能

Kapture 2021-10-30 at 14.26.30

然后只需要美化一下默认的清除按钮就可以了,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 xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E %3Cpath d='M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z'%3E%3C/path%3E %3C/svg%3E") center no-repeat;
    background-size: 16px;
    cursor: pointer;
    opacity: .4;
    transition: .2s;
}

这样就可以了

Kapture 2021-10-30 at 15.27.02

2. firefox 下的实现

不过呢,上面这种方式在 firefox 中是无效的,firefox 中并没有清除按钮,表现和普通输入框一致(下图为firefox表现)

Kapture 2021-10-30 at 15.30.16

如果是 PC 端并且面向用户,firefox 还是不能忽略的,那如何处理呢?

可以先手动添加一个按钮

<input class="input" type="search" placeholder="请输入关键词">
<button class="clear"></button>

然后适当美化一下(相信不是什么难事),可以得到这样的效果

image-20211029172242444

现在清除按钮和输入框没啥关联,如何做到有输入内容时才显示清除按钮呢?

可以这样来思考:有内容表示非空,表示必填项,提到必填项可以想到 required 属性,当有内容时,表示合法的,可以匹配:valid选择器,这样就能区分开来了。具体实现如下

input加一个required属性

<input class="input" placeholder="请输入关键词" required>
<button class="clear"></button>

然后默认隐藏清除按钮,配合相邻选择器+就可以实现啦~

.clear{
    visibility: hidden;
}
.input:valid+.clear{
    visibility: visible;
}

效果如下(下图为firefox表现)

Kapture 2021-10-29 at 17.43.54

然后是清除输入框的功能,如果不借助 JS,有什么办法可以清空输入框呢?

在 HTML5 表单中,可以通过 type=reset直接重置所有内容,所以这里需要修改一下结构,将外层 div改为form,然后给button添加type=reset属性,如下

<form class="search">
    <input class="input" placeholder="请输入关键词">
      <button class="clear" type="reset"></button>
</form>

这样就能清空搜索框了(下图为firefox表现),当然其他浏览器也是支持的

Kapture 2021-10-29 at 19.03.37

这种方式略有遗憾的地方是清除以后输入框没能聚焦

二、搜索提示浮层自动显示

先加上搜索提示的 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;
}

效果如下

Kapture 2021-10-30 at 16.00.02

三、搜索提示浮层上的事件

上面的效果看着好像没啥问题,点击搜索条目后整个搜索结果确实关闭了。

但其实只要是有问题的,点击关闭是由于输入框失去了焦点,如果在搜索条目上添加点击事件,有可能还没触发事件就关闭了,比如

<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 事件(控制台没有打印)

Kapture 2021-10-29 at 19.28.24

原因其实很简单,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;
}

这样就能正常的触发点击和跳转事件了(控制台有打印)

Kapture 2021-10-29 at 19.44.01

完整代码可以访问 CSS search (codepen.io)

兼容 firefox 的完整代码可以访问 CSS search firefox (codepen.io)

四、总结和说明

以上实现了一个搜索输入相关的交互效果,没有布局方面的技巧,核心在于选择器的合理使用,下面总结一下实现重点:

  1. 输入框可以使用 HTML5 新增的 type=search属性,天然支持清除功能,可惜 firefox 不支持
  2. 输入框设置 requred 属性后结合 :valid 选择器可以判断是否有内容
  3. form 表单里可以通过 type=resetbutton 重置输入的内容
  4. 点击失效的原因是输入框先于点击事件失焦,可以用 :active来匹配点击相关行为
  5. 各种选择器结合使用可以实现更加灵活的交互效果
  6. 兼容性 IE 10+,几乎可以生产环境使用

使用 CSS 完成交互的好处是容错率更高,不会导致网站崩溃,性能也更好,很多时候 js 出现错误导致整个网站直接白屏,完全不可用,CSS 就不存在这样的问题啦~ 如果觉得还不错,对你有帮助的话,欢迎点赞、收藏、转发❤❤❤


XboxYan
18.1k 声望14.1k 粉丝