资讯专栏INFORMATION COLUMN

如何使用CSS创建巧妙的动画提示框

vpants / 3351人阅读

摘要:我们巧妙的提示框打算使用属性选择器也就是方括号表示法。相对性这是用在提示框的父元素上的。向上向下提示框要用到关键帧,而向左向右提示框使用关键帧。注意,在这些关键帧中,我们只定义了提示框所需的终止状态。

原文:https://webdesign.tutsplus.co...
原作:Jase Smith
翻译:Stypstive

当你的用户需要漂亮的图标给出额外的文字信息时,亦或是当他们在点击了按钮之后需要确认自己没点错时,又或是带图片和字幕的复活节彩蛋,提示框是用来增强用户界面的绝佳手段。现在,让我们来做几个动画提示框,没有别的,只有HTML和CSS。

样例

这是我们之后要做的:

http://jsfiddle.net/kcschaefe...

在我们沉浸在写代码的过程中之前,让我们先来看看我们的意图是什么。主要目的是为了获得一种简单的添加提示框的方法,这样一来,我们之后就能够通过增加一个自定义的 tooltip 属性来做到这一点。

    visible text or icon, etc.
关于可访问性和功能的记注

如果你在寻找兼容508的提示框,或者需要带容器冲突侦测和/或HTML内容 vs 纯文本的智能提示框,有许多实用第三方脚本的解决方案能满足你的要求。

"用JavaScript来做完全可访问的交互组件是命令式的" - Sara Soueidan, 打造一个完全可访问的帮助提示框...比你想的要难

这篇教程不会特地解决可访问性的需求。你了解你的用户,知道他们需要什么,所以有关这方面,也要记得考虑他们的需求。

让我们设定几个预期

不需要JavaScript

我们将会使用属性选择器(而不是类名),以及CSS内建的模式匹配

加到现有的DOM元素(你的标签中不需要新的元素)

代码例子中是没有前缀的(如有需要,为你的目标浏览器加上供应商前缀)

假设通过 mouseover/hover 来触发提示框

仅仅是纯文本提示框(HTML,图片等等都不支持)

当唤起提示框时,有巧妙的动画

好了,老司机要开车了!

哦,等等。我们还要先处理一个问题,是关于"不需要额外标签"的。毕竟,这很巧妙。 我们的提示框真的不需要额外的DOM元素,因为它们完全是基于伪元素的(::before::after),我们可以通过CSS来控制。

如果你已经在其它样式集中使用了一个元素的伪元素,又希望在这个元素是加一个提示框,那么你可能需要稍稍做一些重构。

没什么比得上来一场提示框盛会了!

等等。小坏蛋!还有一个警告:CSS定位。为了提示框正常运作,它们的父元素(我们把提示框添加在它后面)需要是

position: relative,或者

position: absolute,或

position: fixed

基本上,什么都行,只要不是 position: static — 这是浏览器赋给几乎所有元素的默认定位模式。提示框是绝对定位的,所以它们需要知道它们的绝对值在什么边界内是有意义的。 默认的定位指令 static 不会声明它的边界,也不会给我们的提示框以上下文来进行相对定位。所以提示框会使用之后,最近的,有声明边界的父元素。

你还需要根据你如何使用提示框来决定哪个定位指令最为合适。这篇教程假设父元素是 postion: relative 如果你的UI依靠一个绝对定位的元素,那么在那个元素上部署一个提示框,也会需要一些重构(额外的标签)。

让我们开始吧。

属性选择器:快速回顾

大多数CSS规则印象中都是用类名写的,比如 .this-thing ,但是CSS有几个类型的选择器。我们巧妙的提示框打算使用属性选择器——也就是方括号表示法。

    [foo] {
    background: rgba(0, 0, 0, 0.8);
    color: #fff;
}

当浏览器看到诸如此类的东西时:

Check it out!

浏览器会知道,它需要应用 [foo] 规则了,因为 标签有一个叫做 foo 的属性。在这个例子中,span自身会有一个半透明的黑色背景,以及白色文字。

HTML元素有着各种各样的内置属性,但是我们也可以给出我们自己的属性。比如 foo ,又或者是 tooltip 。默认情况下,HTML不知道这些东西是什么意思,但是有了CSS,我们可以告诉HTML这些自定义属性是什么意思。

为什么用属性选择器?

我们后面会使用属性选择器,主要是出于侧重分离的目的。使用属性而不是类名,并不会让我们在详细程度上获得更多益处,类和属性在详细程度上是相同的。 然而,通过使用属性,我们可以把我们的内容放在一块儿,因为HTML属性可以有值,而类名没有值。

在这个例子的代码中,来权衡一下类名 .tooltip 对比属性 [tooltip] 。类名是 [class] 属性的值中的一个,而tooltip属性可以存放一个值,它就是我们要显示的文字。

lorem ipsum
 
lorem ipsum
现在让我们来看看提示框炼金术

我们的提示框会使用两种不同的属性:

tooltip: 这个属性存放了提示框的内容(一个纯文本字符串)

flow: 可选;这个属性允许我们控制如何显示提示框。我们可以支持很多方位,但是我们会覆盖4各常用方位:上,左,右,下

现在,让我们为所有的提示框做好准备工作。步骤1-5的规则会应用到所有的提示框上,无论我们给 flow 属性什么值。步骤6-7对于不同的 flow 值会有所区分。

1) 相对性

这是用在提示框的父元素上的。让我们来给定一个定位指令,这样提示框的组成部分(即::before::after 伪元素)的绝对定位就可以以父元素做参照进行定位,而不是以整个页面或祖父元素或DOM树上方的其它外围元素作为参照进行定位。

[tooltip] {
  position: relative;
}
2) 伪元素准备时间

是时候准备伪元素了。在这里,我们要对 ::before::after 设置常用属性。content 属性是真正让伪元素工作的属性,不过我们稍后再讨论它。

[tooltip]::before,
[tooltip]::after {
    line-height: 1;
    user-select: none;
    pointer-events: none;
    position: absolute;
    display: none;
    opacity: 0;
 
    /* opinions */
    text-transform: none; 
    font-size: .9em;
}
3) 丁克帽

我不知道丁克帽是不是说得通,我只是一直这么叫它。它是一个尖尖的小三角形,通过指向它的调用者,为提示框提供对话气泡的感觉。 注意到我们在边界颜色这一块,使用了 tranparent ;由于上色要根据提示框的 flow 值来,所以之后再加上颜色。

[tooltip]::before {
    content: "";
    z-index: 1001;
    border: 5px solid transparent;
}

content: "";声明中的值是一个空字符串,这并不是笔误。字符串里面,我们不想要任何东西,但是我们需要这个属性,使得伪元素得以存在。

为了生成一个三角形,我们定义了一个实现边框,在空的盒子(没有内容)上加了一些厚度,而不设定盒子的宽度和高度,仅仅对盒子的每一条边都给一个边框颜色。

4) 气泡!

这里是重点了。注意到 content: attr(tooltip) 这一部分是说:“这个伪类应该使用 tooltip 属性的值作为这个伪类的内容。”这也是为什么使用属性而不是类名会这么赞的原因。

[tooltip]::after {
    content: attr(tooltip); /* magic! */
    z-index: 1000;
     
    /* most of the rest of this is opinion */
    font-family: Helvetica, sans-serif;
    text-align: center;
     
    /* 
    Let the content set the size of the tooltips 
    but this will also keep them from being obnoxious
    */
    min-width: 3em;
    max-width: 21em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
     
    /* visible design of the tooltip bubbles */
    padding: 1ch 1.5ch;
    border-radius: .3ch;
    box-shadow: 0 1em 2em -.5em rgba(0, 0, 0, 0.35);
    background: #333;
    color: #fff;
}

注意看丁克帽和气泡的 z-index 值。这些值可以是任意的。但是要记住,z-index 值是相对的。 解释:一个z-index值为1001的元素,在一个z-index为3的元素内部。仅仅意味着,z-index: 3 容器内部,1001元素是最顶层的元素。

气泡的z-index应该至少比丁克帽的z-index低一档。如果它和丁克的一样高,或更高的话,如果你提示框使用了 box-shadow 的话,结果在丁克帽上回得到不一致的颜色效果。

5)交互动作

我们的提示框是通过把鼠标移动到带提示框的元素上面,来激活的。差不多是这样。

[tooltip]:hover::before,
[tooltip]:hover::after {
    display: block;
}

如果你回顾在第2不中的样式部分,你会看到我们对提示框的组成部分,使用了 opacity: 0; 以及 display: none; 。我们这么做是为了当提示框显示和隐藏时,可以使用CSS动画效果。

display属性是不能做成动画的,但是opacity属性可以!我们留到最后来处理动画的问题。如果你对动画提示框没兴趣,只要把第2步中的 opacity: 0; 删掉,无视第7步即可。

最后一件要应用到所有提示框上的是,如果提示框没有内容,能有一个方法来抑制提示框。如果你使用某种动态系统(Vue.js, Angular, 或者 React, PHP等等)来生成提示框的话,我们就不需要笨笨的空白气泡了!

/* don"t show empty tooltips */
[tooltip=""]::before,
[tooltip=""]::after {
    display: none !important;
}
6) 流控制

这一步会变得更加复杂,因为我们会使用一些不那么常见的选择器,来帮助我们的提示框基于 flow 值(或没有flow属性)来确定位置。

“奇怪的东西出现在了 Circle-K 的门口” — Ted Theodore Logan

在我们写样式之前,让我们看看将要用到一些选择器模式。

[tooltip]:not([flow])::before,
[tooltip][flow^="up"]::before {
    /* ...
    properties: values
    ... */
}

这是在告诉浏览器:“对于所有带有 tooltip 属性来说,其中没有 flow 属性的元素,或者有flow元素,但它的值是以"up"开头的:将这些样式套用到这类元素的::before伪元素上。”

我们在这里使用了一个模式,这样一来,这些东西可以扩展到其它流上,而步需要重复这么多的CSS。这个模式 flow^="up" 使用了 ^= (开头)匹配符。 如果你想增加其它流控制的话,通过这个模式,也可以将样式应用在 up-right 和 up-left 方向上(代码中)。我们在这里不会讨论这些流控制,不过你可以在CodePen上,我原来的提示框演示中看到如何使用它们。

以下是教程中所讲到的4个流所对应的CSS代码块。

/* ONLY the ::before */
[tooltip]:not([flow])::before,
[tooltip][flow^="up"]::before {
    bottom: 100%;
    border-bottom-width: 0;
    border-top-color: #333;
}
 
/* ONLY the ::after */
[tooltip]:not([flow])::after,
[tooltip][flow^="up"]::after {
    bottom: calc(100% + 5px);
}
 
/* Both ::before & ::after */
[tooltip]:not([flow])::before,
[tooltip]:not([flow])::after,
[tooltip][flow^="up"]::before,
[tooltip][flow^="up"]::after {
    left: 50%;
    transform: translate(-50%, -.5em);
}
[tooltip][flow^="down"]::before {
    top: 100%;
    border-top-width: 0;
    border-bottom-color: #333;
}
 
[tooltip][flow^="down"]::after {
    top: calc(100% + 5px);
}
 
[tooltip][flow^="down"]::before,
[tooltip][flow^="down"]::after {
    left: 50%;
    transform: translate(-50%, .5em);
}
[tooltip][flow^="left"]::before {
    top: 50%;
    border-right-width: 0;
    border-left-color: #333;
    left: calc(0em - 5px);
    transform: translate(-.5em, -50%);
}
 
[tooltip][flow^="left"]::after {
    top: 50%;
    right: calc(100% + 5px);
    transform: translate(-.5em, -50%);
}
[tooltip][flow^="right"]::before {
    top: 50%;
    border-left-width: 0;
    border-right-color: #333;
    right: calc(0em - 5px);
    transform: translate(.5em, -50%);
}
 
[tooltip][flow^="right"]::after {
    top: 50%;
    left: calc(100% + 5px);
    transform: translate(.5em, -50%);
}
7) 让一切都动起来

动画是很神奇的。动画可以做到:

让用户感觉舒服

让用户感受到你的用户界面的空间感

注意到该看到的东西

让用户界面中本来非黑即白的生硬效果变得柔和

我们的提示框属于最后那一种。如果仅仅是让一个文字泡泡出现然后突然消失,效果是不令人满意的,我们可以让它更柔和一些。

关键帧 (@keyframes)

我们需要两个关键帧 (@keyframe) 动画。向上/向下提示框要用到tooltips-vert关键帧,而向左/向右提示框使用tooltips-horz关键帧。 注意,在这些关键帧中,我们只定义了提示框所需的终止状态。我们并不需要知道它们从何处来 (提示框本身就有状态信息)。我们只想控制它们要到哪儿去。

@keyframes tooltips-vert {
  to {
    opacity: .9;
    transform: translate(-50%, 0);
  }
}
 
@keyframes tooltips-horz {
  to {
    opacity: .9;
    transform: translate(0, -50%);
  }
}

现在,当一个用户的鼠标移到触发元素 (具有[tooltip]属性的元素) 上时,我们需要将这些关键帧应用到提示框上。因为我们采用了不同的流来控制提示框的显示方式,我们需要在样式中对它们进行定义。

使用:hover将控制传递给动画
[tooltip]:not([flow]):hover::before,
[tooltip]:not([flow]):hover::after,
[tooltip][flow^="up"]:hover::before,
[tooltip][flow^="up"]:hover::after,
[tooltip][flow^="down"]:hover::before,
[tooltip][flow^="down"]:hover::after {
    animation: 
        tooltips-vert 
        300ms 
        ease-out
        forwards;
}
 
[tooltip][flow^="left"]:hover::before,
[tooltip][flow^="left"]:hover::after,
[tooltip][flow^="right"]:hover::before,
[tooltip][flow^="right"]:hover::after {
    animation: 
        tooltips-horz 
        300ms 
        ease-out 
        forwards;
}

我们不能对display属性进行动画,但是可以通过操作opacity属性,在提示框上加上淡入效果。我们也可以动画transform属性,它可以给提示框加上微妙的动作,触发的元素就像飞入某点的一样。

主要forward关键词在动画的声明中,这告诉动画当完成时不重置,而是继续停留在结束。

结论

棒极了!我们在这个教程里已经覆盖了很多,一堆提示框效果。

http://jsfiddle.net/kcschaefe...

我们仅仅摸索了用css做提示框的表面。好好享受它们,继续试验,调制出你自己的方子!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/50934.html

相关文章

  • 如何使用CSS创建巧妙动画提示

    摘要:我们巧妙的提示框打算使用属性选择器也就是方括号表示法。相对性这是用在提示框的父元素上的。向上向下提示框要用到关键帧,而向左向右提示框使用关键帧。注意,在这些关键帧中,我们只定义了提示框所需的终止状态。 原文:https://webdesign.tutsplus.co...原作:Jase Smith翻译:Stypstive 当你的用户需要漂亮的图标给出额外的文字信息时,亦或是当他们在点击...

    wmui 评论0 收藏0
  • 【译】编写更好CSS必备40个工具

    摘要:一个叫的人用纯重绘并模拟了种不同的移动设备包括可以给你的网站添加不相关的独立组件的一个库。每一个组件都是针对移动设备定制的,并且它有很多你在传统的框架中看不到的功能。如果你用开发移动优先的网站,并想要网站正常运行在低版本的上,可以考虑。 众所周知,CSS是非常棒的,它使网站看起来很漂亮,可以为网站添加动画,并让呈现和内容分离。去了解CSS的一切是非常难做到的,它只会变得更加困难,因为我...

    moven_j 评论0 收藏0
  • task0002(四)- 练习:数据处理、轮播及交互

    摘要:获取下一个元素节点,存在的话,取消现有选中状态,设置下一个元素节点为选择中,调用运动框架实现动画,添加定时器,调用该函数,实现自动播放。移出时,开启定时器,继续轮播。轮播间隔时间单位为毫秒,默认为,在内部,以下部分进行修改或添加。 转载自我的个人博客 欢迎大家批评指正 包括5部分: 小练习1-处理用户输入 小练习2-日期对象的使用 小练习3:轮播图 小练习4:输入提示框 小练习...

    cnTomato 评论0 收藏0
  • task0002(四)- 练习:数据处理、轮播及交互

    摘要:获取下一个元素节点,存在的话,取消现有选中状态,设置下一个元素节点为选择中,调用运动框架实现动画,添加定时器,调用该函数,实现自动播放。移出时,开启定时器,继续轮播。轮播间隔时间单位为毫秒,默认为,在内部,以下部分进行修改或添加。 转载自我的个人博客 欢迎大家批评指正 包括5部分: 小练习1-处理用户输入 小练习2-日期对象的使用 小练习3:轮播图 小练习4:输入提示框 小练习...

    赵春朋 评论0 收藏0
  • 67 个拯救前端开发者工具、库和资源

    摘要:库一个用来在中创建炫酷的浮动粒子的库一个用来在中创建物体和空间的库快速实现全屏滚动特性打字机效果滚动到某个元素位置时触发一个功能语法高亮使用创建漂亮的图表能够明显加速网站加载时间,鼠标时预加载资源另一个图表库一个基于动画和平移的雪碧图库实现 Javascript 库 Particles.js  一个用来在 web 中创建炫酷的浮动粒子的库 Three.js  一个用来在 web 中创...

    XiNGRZ 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<