原文:https://webdesign.tutsplus.co...
原做:Jase Smith
翻译:Stypstivecss
当你的用户须要漂亮的图标给出额外的文字信息时,亦或是当他们在点击了按钮以后须要确认本身没点错时,又或是带图片和字幕的复活节彩蛋,提示框是用来加强用户界面的绝佳手段。如今,让咱们来作几个动画提示框,没有别的,只有HTML和CSS。html
这是咱们以后要作的:web
http://jsfiddle.net/kcschaefe...浏览器
在咱们沉浸在写代码的过程当中以前,让咱们先来看看咱们的意图是什么。主要目的是为了得到一种简单的添加提示框的方法,这样一来,咱们以后就可以经过增长一个自定义的 tooltip
属性来作到这一点。post
<span tooltip="message">visible text or icon, etc.</span>
若是你在寻找兼容508的提示框,或者须要带容器冲突侦测和/或HTML内容 vs 纯文本的智能提示框,有许多实用第三方脚本的解决方案能知足你的要求。动画
"用JavaScript来作彻底可访问的交互组件是命令式的" - Sara Soueidan, 打造一个彻底可访问的帮助提示框...比你想的要难this
这篇教程不会特意解决可访问性的需求。你了解你的用户,知道他们须要什么,因此有关这方面,也要记得考虑他们的需求。spa
不须要JavaScript.net
咱们将会使用属性选择器(而不是类名),以及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; }
当浏览器看到诸如此类的东西时:
<span foo>Check it out!</span>
浏览器会知道,它须要应用 [foo]
规则了,由于 <span>
标签有一个叫作 foo 的属性。在这个例子中,span自身会有一个半透明的黑色背景,以及白色文字。
HTML元素有着各类各样的内置属性,可是咱们也能够给出咱们本身的属性。好比 foo
,又或者是 tooltip
。默认状况下,HTML不知道这些东西是什么意思,可是有了CSS,咱们能够告诉HTML这些自定义属性是什么意思。
咱们后面会使用属性选择器,主要是出于侧重分离的目的。使用属性而不是类名,并不会让咱们在详细程度上得到更多益处,类和属性在详细程度上是相同的。 然而,经过使用属性,咱们能够把咱们的内容放在一起,由于HTML属性能够有值,而类名没有值。
在这个例子的代码中,来权衡一下类名 .tooltip
对比属性 [tooltip]
。类名是 [class] 属性的值中的一个,而tooltip属性能够存放一个值,它就是咱们要显示的文字。
<span class="tooltip another-classname">lorem ipsum</span> <span tooltip="sit dolar amet">lorem ipsum</span>
咱们的提示框会使用两种不一样的属性:
tooltip
: 这个属性存放了提示框的内容(一个纯文本字符串)
flow
: 可选;这个属性容许咱们控制如何显示提示框。咱们能够支持不少方位,可是咱们会覆盖4各经常使用方位:上,左,右,下
如今,让咱们为全部的提示框作好准备工做。步骤1-5的规则会应用到全部的提示框上,不管咱们给 flow 属性什么值。步骤6-7对于不一样的 flow
值会有所区分。
这是用在提示框的父元素上的。让咱们来给定一个定位指令,这样提示框的组成部分(即::before
和 ::after
伪元素)的绝对定位就能够以父元素作参照进行定位,而不是以整个页面或祖父元素或DOM树上方的其它外围元素做为参照进行定位。
[tooltip] { position: relative; }
是时候准备伪元素了。在这里,咱们要对 ::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; }
我不知道丁克帽是否是说得通,我只是一直这么叫它。它是一个尖尖的小三角形,经过指向它的调用者,为提示框提供对话气泡的感受。 注意到咱们在边界颜色这一块,使用了 tranparent
;因为上色要根据提示框的 flow 值来,因此以后再加上颜色。
[tooltip]::before { content: ''; z-index: 1001; border: 5px solid transparent; }
content: '';
声明中的值是一个空字符串,这并非笔误。字符串里面,咱们不想要任何东西,可是咱们须要这个属性,使得伪元素得以存在。
为了生成一个三角形,咱们定义了一个实现边框,在空的盒子(没有内容)上加了一些厚度,而不设定盒子的宽度和高度,仅仅对盒子的每一条边都给一个边框颜色。
这里是重点了。注意到 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
的话,结果在丁克帽上回获得不一致的颜色效果。
咱们的提示框是经过把鼠标移动到带提示框的元素上面,来激活的。差很少是这样。
[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; }
这一步会变得更加复杂,由于咱们会使用一些不那么常见的选择器,来帮助咱们的提示框基于 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%); }
动画是很神奇的。动画能够作到:
让用户感受舒服
让用户感觉到你的用户界面的空间感
注意到该看到的东西
让用户界面中原本非黑即白的生硬效果变得柔和
咱们的提示框属于最后那一种。若是仅仅是让一个文字泡泡出现而后忽然消失,效果是不使人满意的,咱们可让它更柔和一些。
咱们须要两个关键帧 (@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]
属性的元素) 上时,咱们须要将这些关键帧应用到提示框上。由于咱们采用了不一样的流来控制提示框的显示方式,咱们须要在样式中对它们进行定义。
[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作提示框的表面。好好享受它们,继续试验,调制出你本身的方子!