实验全屏API

216 阅读10分钟

FullScreen API允许你让你的页面上的一个元素有一个全屏视图。通常情况下,你会在不同的图形或媒体资源中看到这个功能--例如,视频或图片--但实际上你可以让你的页面上的任何元素拥有全屏视图。

FullScreen API目前在Chrome、Firefox、Opera和Edge中得到了良好的支持。在Safari中,应该有部分支持,使用供应商的前缀,但我还没有尝试让它发挥作用。

Support for the backdrop selector from CanIUse.com

来源。CanIUse.com

如果你需要对FullScreen API的跨平台支持,现在有很多,比如fscreenscreenfull。还有一个React Hooks的实现和一个高阶组件,可以将儿童变成可全屏的区域

但本文将只关注使用指定的FullScreen API,所以你应该知道,事情只能在列出的浏览器中运行。

开始使用

要在用户的浏览器上启用全屏视图,你首先需要用Element.requestFullScreen 功能请求允许这样做。这与请求访问位置数据不同--浏览器基本上是通过判断用户是否执行了批准或拒绝全屏访问的具体操作,如点击允许按钮,来决定是否接受该请求的。

如果用户想退出全屏视图,他们可以使用他们通常用来退出全屏窗口的所有方法,也可以按转义键,前提是他们所处的环境为他们提供了转义键。

现在,让我们继续讨论一些例子。

基本的例子。一个全屏部分

FullScreen API最常用于嵌入图片和视频,但每一种都有自己的小问题需要考虑,所以我将从更简单的东西开始:一个HTML5部分,有一个按钮可以将该部分变成全屏视图。

请参阅CodePen上Bryan Rasmussen(@bryanrasmussen)的Pen
全屏部分。

我在这个例子中的按钮造型是从LogRocket CSS参考指南中重用的按钮造型。

该页面看起来有点像以下内容。

The full-screen demo visual

当你点击 "全屏"按钮时,它将切换到全屏视图,该部分的文字为 "全屏模式下可获得更多信息......"

全屏看起来是这样的(白边仍然存在,只是在屏幕的边缘)。

The promised full-screen view

这里的文字是不同的,因为我们使用了:fullscreen 伪选择器,将写着 "全屏模式下有更多信息可用...... "的H2文字切换到display:none ,将另一个写着 "这是承诺的全屏模式!"的H2文字从display:none 转到display:block

请看下面的代码片段。

.fullscreenMoreInfo {
  display: none;
}

.fullscreenEnabled:fullscreen
.fullscreenintro{
  display: none;
}

.fullscreenEnabled:fullscreen .fullscreenMoreInfo {
  display: block;
}

这里需要注意的是,:fullscreen 伪选择器必须应用在已经切换到全屏模式的元素上;在这种情况下,它是具有fullscreenEnabled 级别的部分。

FullScreen API还指定了另一个潜在的伪选择器::backdrop 选择器。
Support for the backdrop selector across browsers

这是为页面上不在:fullscreenEnabled 元素中的其他内容设计样式。现在,你可能在问自己,什么?为什么呢?

一个潜在的用途是在背景上放一个背景色,然后影响全屏显示。MDN有一个全屏视频元素的例子

另一个更重要的用途是满足背景墙的可访问性要求;然而,目前这并不可行。我们将在本文后面的 "在图像中使用全屏API "一节中讨论这个问题。

扩展基本的例子。一个全屏模态

:fullscreen 元素与对话框和模态窗口非常相似,它将内容与页面的其他部分分开,以强调它。

很自然地,对该技术进行类似模态的使用是合乎逻辑的,为了做到这一点,我将重新使用MDN上的Pure CSS Lightbox的一些代码来制作关闭按钮。

首先,我将改变一些围绕点击处理程序的逻辑,因为我想用一个按钮来打开模态,并在模态中用一个按钮来关闭它。

看一下下面的代码。

请参阅CodePen上Bryan Rasmussen(@bryanrasmussen) 的Pen
全屏模态

我们的改动主要是一些小改动,将makeFullScreen 函数添加到多个元素中(因为它关闭了:fullscreen 元素,如果有的话,我们也可以将它用于我们的模态关闭),并为事件键添加一个keydown 处理程序,像这样。

const  buttons = document.querySelectorAll(".fullscreener");
buttons.forEach( (button) => {
  button.addEventListener("click", () => {
   makeFullScreen(document.querySelector(".fullscreenEnabled"))
  });
  button.addEventListener('keydown', (e) => {
    if (e.key === "Enter") {
    makeFullScreen(fullScreenEnabledEl);
    }
  });
});

然后,我们将在模态区域添加一些结构,使我们的模态有更好的样式,包括模态打开按钮和关闭按钮的一些焦点样式。

这就是模态关闭时的样子。

Visual for the full-screen modal demo

这是模态显示时的样子。

The full-screen modal is opened, revealing additional text

为了方便使用,我们用Firefox中的VoiceOver和键盘导航对它进行了测试。显然,由于这是一个概念验证,而且是在CodePen的嵌套框架内编写的,在其他浏览器/屏幕阅读器的组合上可能存在可访问性问题。

最常见的全屏应用

正如我们之前提到的,:fullscreen 元素基本上有两种常见的用途,人们关注的是给视频或图像以全屏显示的能力。

我决定不做一个全屏视频的例子,因为要做一个赏心悦目的例子需要太多的部分,作为本文的一个小部分,我无法做到这一点。相反,我将专注于图像,因为我相信我们可以对它进行一些有趣的补充。

使用图像的FullScreen API

在这个例子中,我把一些图片摆放在一个网格中。为了让这些图像在全屏视图中值得一看,我使用了从互联网档案馆下载的小尼莫的一些例子

这里是例子的网格。

参见CodePen上Bryan Rasmussen(@bryanrasmussen)
的Pen
图片网格。

第一行的图片看起来像下面这样。

The first line of Little Nemo images

我们对我们的makeFullScreen 函数做了一个与之前类似的事情:每张图片都在一个span 里面,有一个按钮的角色,用于可访问性和类fullscreenEnabled 。我们将clickkeydown 事件处理程序添加到我们的spans,并使span 本身成为全屏。

这是因为在我们的CSS中,全屏跨度和它的子图像,允许我们以全屏的方式滚动浏览图像。

span:fullscreen {
  overflow: auto;
}

span:fullscreen img {
  object-fit: contain;
  border: 0;
}

当然,这是因为如果图像是全屏的,它将被缩小以适应你正在观看的屏幕(假设屏幕面积比图像小),而如果包裹图像的元素是全屏的,我们可以允许它溢出,然后用户可以按照他们的意愿滚动浏览图像。

出于可访问性的目的,我们没有在每个span上放一个aria-label 属性,并告诉用户他们可以点击以全屏模式查看,这可能显得过于冗长,我们在上面的段落中添加了一个通知。

然而,这并不是你在这个解决方案中可能遇到的唯一的可访问性问题。如果你使用屏幕阅读器,它如何处理页面中没有在全屏视图中显示的部分,或者换句话说,留在背景中的部分?

FullScreen API规范中,对背景墙有如下说明。

"::backdrop 伪元素可以用来创建一个背景,为顶层的元素(比如全屏显示的元素)隐藏底层文档。"

这意味着你应该可以做以下事情。

span::backdrop {
  display: none;
}

但这并不可行。

根据我使用Chrome的经验,你无法用屏幕阅读器访问背景内容。你可以进入浏览器地址栏,但你必须真的努力去做。

然而,在火狐浏览器中,当你把一个元素变成全屏时,你最终能够阅读所有不在全屏中的内容。我已经输入了一个关于这个问题的bug,但现在还不能说会有什么反应。

true目前,如果你使一个元素成为全屏,对无障碍性的解决方案可能是将:fullscreen 元素以外的所有元素都设置为aria-hidden 元素。希望Firefox能很快解决这个问题。

我没有测试过::backdrop 伪选择器的行为或:fullscreen 元素在其他浏览器上的可访问性,所以要警惕。

使用SVG的全屏图像

这开始看起来与我们上一个例子中的图像网格类似,你点击一个图像,它就以全屏模式打开。事实上,除了现在看到网格中的四个项目外,你可能会认为这是同一个例子。这是因为我使用了SVGimage 元素,将Little Nemo的jpeg嵌入到SVG中。

差别看起来就像下面这样。在最终的SVG中会有额外的代码,但这向我们展示了相同的图像。

<div role="button"
   class="fullscreenEnabled"
>
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg">
    <title>Little Nemo ThanksGiving Day Dream embedded in SVG</title>
    <image     
      href="https://assets.codepen.io/1281712/little-nemo-19051126-l.jpeg"  
    />
  </svg>
</div>

当你在玩弄嵌入SVG的图像时,你必须考虑这些图像的实际尺寸是多少(一般来说,也就是说,如果你想获得良好的视觉体验)。这是因为SVG对不适合其容器的图像的处理方式与HTML不同。

当我第一次尝试做这个的时候,它把我吓了一跳,因为我试图只是猜测图片的尺寸,而不是计算它,结果差得很远。这就在SVG的顶部产生了一堆领先的空白,因为SVG解析器试图调整图像的大小以保持长宽比。

这导致我浪费了一两个小时的时间,因为我当时的心态不对,不知道自己错在哪里--所以,现在是提醒自己先用SVG弄清楚尺寸的好时机。

我们在SVG里面嵌入的图片的尺寸是宽1738px,高2378px,所以挑选了一个长宽比相同的尺寸组合(当然要去掉小数点),我选择了宽250px,高345px。所以,为了使一切在SVG中看起来漂亮,我们可以这样做。

.fullscreenEnabled {
  width: 250px;
  height: 345px;
}

.fullscreenEnabled > svg {
  width: 100%;
  height: 100%;
}

.fullscreenEnabled image {
  width: 100%;
  height: 100%;
}

然后我们设置grid-template-columns ,使之与我们的图像宽度一致。

grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));

然后,我们最终得到的东西看起来就像下面这样。
Little Nemo images with full-screen views available
但是我们要替换所有这些值,所以也许我们应该使用CSS变量,像这样。

:root {
  --grid-item-width: 250px;
  --grid-item-height: 345px;
  --svg-width: 100%;
  --svg-height: 100%;
}

.fullscreenEnabled {
  width: var(--grid-item-width);
  height: var(--grid-item-height);
}

.fullscreenEnabled > svg {
  width: var(--svg-width);
  height: var(--svg-height);
}

.fullscreenEnabled image {
  width: var(--svg-width);
  height: var(--svg-height);
}

当然,grid-item-width 变量将被用于grid-template-columns 属性中。

然后,当我们启用全屏模式时,我们可以简单地做。

.fullscreenEnabled:fullscreen {
  --grid-item-width: 1738px;
  --grid-item-height: 2378px;
  --svg-width: var(--grid-item-width);
  --svg-height: var(--grid-item-height);
  overflow: auto;
}

这是因为我们可以在全屏模式下改变变量的值,并让它们像在其他类或虚拟选择器中一样被继承。

这可以在下面看到。

请看CodePen上Bryan Rasmussen(@bryanrasmussen)的Pen
Images Grid With SVG。

在FullScreen API的上下文中,SVG的主要好处是你可以在SVG中设置动画和其他效果(当然是在比图片更高的z-index上),当.fullscreenEnabled div实际处于全屏视图中时,这些动画和效果就会变得可见和激活。

总结

Fullscreen API非常简单,但只要有一些创意,就可以得到有趣的结果。我们已经看到了如何为各种类型的元素切换全屏,提供一个大的图像视图和一个全屏模式。很明显,这些例子可以扩展到制作全屏幻灯片或类似的效果。

然而,就可访问而言,目前实现的全屏API肯定有缺点,在使用它构建解决方案时应该考虑到这一点。

The postExperimenting with the FullScreen APIappeared first onLogRocket Blog.