我们之前就提到过 <details>
和 <summary>
元素有多棒。它们非常适合快速 制作手风琴,这些手风琴可供触摸、鼠标和键盘输入访问
<details>
和 <summary>
甚至可以用于 播放/暂停 gif!单击此图像右上角的暂停按钮以查看其工作原理
很酷,是吧?但这些元素还能做什么?很长一段时间以来,我只考虑过将 details
作为制作手风琴的一种方式。但前几天我开始思考了一下,我首先意识到也许我们可以用它们制作更好的脚注。
以下是我们今天通常使用纯 HTML 制作脚注的方式
单击段落中的链接会将您推送到页面的底部,那里是脚注的描述。我们通过链接到元素的 ID 来回实现这一点。但是!像 BigFoot 这样的 jQuery 插件可以让你将脚注放在行内。
以下是在 BigFoot 脚本和 jQuery 应用于它的情况下,相同示例的代码
很酷吧?BigFoot 采用我们可访问的标记,删除所有这些链接内容,并将其直接作为一个小按钮和工具提示项放在行内。
但是,如果我们能使用 <details>
和 <summary>
来替换我们脚注的这个 jQuery 和普通的 HTML 呢?好吧,很遗憾,我们做不到。如果你试图将这两个元素中的任何一个放在 <p>
标签内,浏览器会将这些元素渲染到 <p>
元素的外部
糟糕!这很烦人,但我多少理解为什么它会这样工作。如果我们能够替换所有这些链接的复杂性和上下跳动页面的糟糕体验,那就太好了。但我们做不到。
那么,如果我们不能这样做,我们还能用 <details>
和 <summary>
来做什么?这让我思考... 工具提示怎么样?当然可以!我们可以绝对做到。假设我们有一些像这样扩展显示日期的标记
非常标准,我们之前见过。但现在让我们开始进行样式设置,这才是有趣的部分。首先,我们需要处理 <details>
元素
details {
border-radius: 3px;
cursor: pointer;
display: inline-block;
position: relative;
transition: 0.15s background linear;
}
details:hover,
details:focus {
background: #d4d1ec;
}
这使我们能够将信息绝对定位在 details 元素内,但也使工具提示在单击时感觉更像一个按钮,带有背景。接下来,我们可以通过以下操作来撤消 summary
元素的默认箭头
summary {
background: url("https://assets.codepen.io/14179/Info.svg") 11px 11.5px no-repeat;
list-style: none;
padding: 10px;
padding-left: 33px;
}
最后,我们需要绝对定位 details 元素内的段落。并制作一个小三角形,指向工具提示的其余部分
details p {
cursor: auto;
background: #eee;
padding: 15px;
width: 250px;
position: absolute;
left: 0;
top: 35px;
border-radius: 4px;
right: 0;
}
// Tiny triangle that points up
details p:before {
content: "";
border-bottom: 12px solid #eee;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
height: 0;
left: 10px;
position: absolute;
top: -10px;
width: 0;
}
这将导致类似以下内容。请确保单击工具提示以查看其下方出现的描述
我们可以在这里做的一件不错的事情是,在工具提示打开时添加动画,以便稍加完善
details[open] p {
animation: animateDown 0.2s linear forwards;
}
@keyframes animateDown {
0% {
opacity: 0;
transform: translatey(-15px);
}
100% {
opacity: 1;
transform: translatey(0);
}
}
就是这样!如果你单击工具提示,它会弹开;如果你按 Tab 键并单击空格键,它也会打开。
但我们可以更进一步。我们可能不想要的是,这些工具提示到处乱开。如果我们大量使用工具提示,那么这可能会变得非常笨拙且分散注意力。我们需要做的是,当我们在工具提示之外单击时关闭它。我们可以使用一些简单的 JavaScript 来实现这一点
const tooltip = document.querySelector(".tooltip");
document.addEventListener("click", function (e) {
var insideTooltip = tooltip.contains(e.target);
if (!insideTooltip) {
tooltip.removeAttribute("open");
}
});
现在,当您单击工具提示之外时,它会关闭。太棒了!
<details>
和 <summary>
元素不能做所有事情,但它们确实可以做很多方便的事情——我估计,这两种元素的组合可以做很多事情。我们只需要去找到它们。事实上,这里还有一些关于这个主题的精彩帖子。
在
<summary>
上设置list-style: none;
不会在 Chrome 中删除默认矩形(至少在 Chrome 87 中是这样)。为了实现它,您应该使用非标准的
::-webkit-details-marker
伪元素原则上,
<details>
标签可以在我们需要真/假状态时使用,就像“复选框”黑客一样,但我们可能不应该这样做!我最近用它来播放/暂停动画——只是为了好玩
我还用它来制作“切换提示”
https://codepen.io/stoumann/full/abZXxPx
正如你在文章中间接提到的,
[open]
状态只能使用animation
来设置动画,不能使用transition
,因此details[open] p
在使用transition
时不会执行任何操作。我想知道你或这里其他人是否知道原因?!
在 Android Chrome 中,工具提示示例中仍然显示一个小三角形。
很喜欢工具提示的想法!我一直使用 details 来制作下拉菜单,它们很相似。我还使用了一个小小的 CSS 技巧(无 JS!)来在单击菜单外部时关闭它们。我认为我是从检查 GitHub 上的菜单中学到的?它使用 summary 上的生成内容来创建一个全窗口单击目标
您还需要根据菜单的内容调整 z-index。
虽然我喜欢单击时工具提示的视觉表示,但添加额外单击需求而不是仅仅在悬停时显示信息,这不是一个坏主意吗?
将鼠标悬停在“3 天前”文本上(至少对我来说)是一个强烈的指示,表明用户请求该特定数据,为什么不直接显示它呢?
注意:我承认这种特定的机制可以用于在其他情况下显示更详细的内容,所以我并不是贬低这个想法本身。我只是认为在这里它是一个相当糟糕的用例:-)
对于工具提示示例,在 Chrome 和 Safari 中,动画只在您第一次打开时播放。之后,它会恢复到只是弹出和消失。它似乎在 Firefox 中工作正常。
有没有什么动画设置可以解决这个问题?