CSS的发展:关于Popover API的探讨

在这篇文章中,我们要看的不是一个而是两个即将出现在CSS中的令人兴奋的新东西,第一个是Popover API。虽然我认为它本身很好,但当它与锚点定位搭配使用时,我们能做的事情就非常非常酷了。在写这篇文章的时候,这两个功能都只在非稳定的浏览器中可用。

什么是Popover API?

Popover API是一个强大的工具,为开发人员提供了一个一致和灵活的方式来显示网页上的弹出式内容。无论你喜欢声明性的HTML属性还是JavaScript控制,这个API都能满足你的需求。

在网络上,在其他内容的顶部呈现内容是很常见的,如果你愿意的话,在top-layer,以引起用户对重要信息或行动的注意。你可能已经遇到了各种术语,如弹出式窗口或对话框。

HTML属性
  • popover
    • auto (default) – 这意味着当点击外部或按下esc时,弹出窗口可以被解散,同时其他弹出窗口也会为这个新的弹出窗口关闭。
    • manual – 当手动时,弹出窗口只能被手动关闭(使用JS或HTML关闭动作)。
  • popovertarget
    • [id] – 这个属性可以放在一个 button 上,让它控制一个弹出窗口,该属性的值应该是目标的 id 。
  • popovertargetaction
    • toggle (default) – 按下带有 popovertarget 的 button  将对弹出窗口执行该动作。在这种情况下,如果隐藏,弹出窗口将显示,如果显示,则隐藏。
    • hide – 设置 popovertarget 为显示无。
    • show – 设置 popovertarget 为显示块。
<button popovertarget="menu" popovertargetaction="toggle">Menu</button>

<nav id="menu" popover="auto">

<ul>

<li><a href="/items/1">Item 1</a></li>

<li><a href="/items/1">Item 2</a></li>

<li><a href="/items/1">Item 3</a></li>

</ul>

</nav>
CSS 伪元素和类
  • ::backdrop – 这是一个伪元素,它填满了弹出式窗口后面的整个屏幕,对它进行造型可以让你改变颜色,甚至增加模糊度。
  • :popover-open – 这是一个伪类,当弹出窗口元素被打开时,它会被应用到该元素上,我们可以用它来添加打开动画。
#menu {

border: 0;

margin-right: 0;

box-shadow: 0 -1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);

max-width: 100vw;

width: 200px;

height: 100%;

}

#menu ul {

list-style: none;

padding: 0;

}

#menu ul li {

padding: 1ch;

}

#menu::backdrop {

background-color: rgba(200, 200, 200, 0.5);

backdrop-filter: blur(2px);

}

#menu:popover-open {

animation: slideIn 150ms ease-in-out;

}

@keyframes slideIn {

0% {

translate: 100% 0 0;

}

100% {

translate: 0 0 0;

}

}
JavaScript控件和事件

我知道这篇文章主要是关于CSS的新的和令人兴奋的东西,但如果不谈谈JS,那就太可惜了。

控件

  • PopoverElement.hidePopover() – 更新弹出式窗口元素并将其移至隐藏状态。
  • PopoverElement.showPopover() – 更新popover元素并将其移至显示状态。
  • PopoverElement.togglePopover() – 更新popover元素并在其隐藏和显示状态之间切换。

事件

  • beforetoggle – 视觉上发生状态变化之前触发的事件。
  • toggle – 视觉上发生状态变化后触发的事件。
const popover = document.querySelector('#menu[popover]');

popover.addEventListener('beforetoggle', () => {

// I triggered first before anything visually happened.

});

popover.addEventListener('toggle', () => {

// I triggered after the toggle had happened visually.

});
Demo

这是一个简单的对话框演示,我选择在这个例子中不包含任何JavaScript,只是为了展示它可以真正的简单化。

如果你的浏览器还不支持 popover ,这里有一个后备GIF。

简单的对话框演示动画

什么是锚点定位?

锚点定位还没有在MDN上出现,所以这确实是一些实验性的东西。我将尽力解释它的作用以及如何使用它。

目前,如果你想让一个元素在另一个元素旁边呈现,最简单的方法是用JavaScript计算出目标元素的位置,然后将锚定元素设置为绝对位置,并设置顶部、右侧、底部或左侧属性。这种方法是可行的,但 “少用JavaScript就好”,所以锚可以让你把元素的位置储存在一个CSS变量中。

#anchor {

anchor-name: --test-anchor;

}

.anchored-element {

position: absolute;

right: anchor(--test-anchor left);

top: anchor(--test-anchor center);

transform: translateY(-50%);

}

你会注意到这个新的 anchor CSS函数。它接受一个CSS变量和一个位置,然后返回位置,你甚至可以在一个 calc 中使用这个值来做更复杂的位置。

Demo

这里有一个小的演示,展示了工具提示的创建,其目的是为了简单化,只展示一个简单的实现。

再说一遍,这里有一个后备的GIF,因为我相信锚点仍然是一个有点远的地方。

工具提示Gif动画

我们怎样才能把这些东西放在一起使用呢?

网络已经存在了很长时间,并且完全向后兼容,这很好,但确实导致了一些问题,比如不能定制 select 组合框组件。我相信你们中的许多人都有过这样的两难选择:是从头开始写一个新的组合框来配合特定的设计,还是找一个别人已经做出来的组合框,但失去了一些定制能力。

把 Popover 和 Anchor Position 结合起来,我想我们也许能够做出一个漂亮的组合框,我们可以按照自己喜欢的方式来构建,而不必担心可访问性和定位问题。让我们看看我们是否能做到这一点。

我们对可访问性做了什么?

有一个由W3C的可爱的人制作的网站,它为各种不同的使用情况(包括组合框)提供了所有的Aria模式。我将浏览这个网站,并查看本地选择元素的作用。

我知道Aria模式网站已经建立了一段时间,但我无法强调它有多么神奇和有用,我觉得它有点像一个最保守的秘密,但每个人都应该使用它。

Demo

所以,我们在这里,最后,演示。我把Popover API和Anchor定位结合起来,制作了一个组合框,我们可以随心所欲地设计。

我不得不使用一些JS,以确保它对键盘友好,并确保按钮中的文本更新,如果你们有什么想法,我们可以用更少的JS来做这些事情,我很想听听。

最后,希望有一天我们都能回过头来看看这个帖子,看到一切都在运作。

trg90wwomhyk8c17s1e8

小结

这就结束了,Popover API应该很快就会开始在稳定的浏览器中出现,但锚点定位可能还需要一段时间。话虽如此,但现在确实是一个令人兴奋的时代。很多以前需要黑客解决的任务现在都得到了解决,使我们能够探索更多创造性的可能性