探索 details 和 summary 元素的功能

Avatar of Robin Rendle
Robin Rendle

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费积分!

我们之前就提到过 <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> 元素不能做所有事情,但它们确实可以做很多方便的事情——我估计,这两种元素的组合可以做很多事情。我们只需要去找到它们。事实上,这里还有一些关于这个主题的精彩帖子。