使用鲜为人知的 CSS element() 函数创建小地图导航器

Avatar of Preethi
Preethi

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

W3C 的 CSS 工作组经常为我们提供出色的 CSS 功能供我们实验。 有时我们偶然发现一些非常酷的东西,让我们脸上露出笑容,但它很快就消失了,因为我们认为,“这很棒,但我该怎么用它呢?” element() 函数对我来说就是这样。 这是一个 CSS 函数,它获取页面上的元素并将其呈现为要显示在屏幕上的图像。 令人印象深刻,但有点古怪。

下面是一个简单的 示例,说明它的工作原理。 它目前仅在 Firefox 中受支持,我知道这很糟糕。 但是请坚持下去,看看它有多有用。

<div id="ele">
  <p>Hello World! how're you?<br>I'm not doing that<br>great. Got a cold &#x1F637;</p>
</div>
<div id="eleImg"></div>
#eleImg {
  background: -moz-element(#ele) no-repeat center / contain; /* vendor prefixed */
}

element() 函数(带浏览器前缀)采用元素的 id 值,将其转换为图像。 输出看起来与屏幕上给定元素的外观相同。

当我想到 element() 的输出时,我想到的是 预览 这个词。 我认为这是能够最大限度地利用它的用例类型:我们可以预览元素,然后再将其显示在页面上。 例如,幻灯片中的下一张幻灯片,隐藏的选项卡或图库中的下一张照片。 或者……一个小地图!

小地图 是长文档或页面的迷你预览,通常显示在屏幕的一侧或另一侧,用于导航到该文档上的相应点。

您可能在 Sublime Text 等代码编辑器中看到过它。

小地图在右边。

CSS element() 在制作小地图的“预览”部分方面非常有用。

下面是小地图的演示,之后我们将逐步介绍其代码。 但是,我建议您查看 完整页面演示,因为小地图对于 文档(在 屏幕上)非常有用。

如果您使用的是智能手机,请记住,根据相对论,小地图将在迷你屏幕中变得超级迷你; 而且不,这实际上不是相对论的真实说法,但您明白我的意思。

查看 Pen 使用 CSS element() 和 HTML 输入范围的小地图,由 Preethi Sam (@rpsthecoder) 在 CodePen 上制作。

A screenshot of the final result of the demo. It consists of a large block of styled paragraph text with a

如果您正在为整个页面设计小地图(例如,用于单页网站),则可以使用文档主体元素作为图像。 否则,将主要内容元素(例如我的演示中的文章)作为目标也可以。

<div id="minimap"></div>
<div id="article"> <!-- content --> </div>
#minimap {
  background: rgba(254,213,70,.1) -moz-element(#article) no-repeat center / contain;
  position: fixed; right: 10px; top: 10px; /* more style */
}

对于小地图的背景图像,我们将文章的 id 作为 element() 的参数提供,并且与大多数背景图像一样,它被设置为不重复 (no-repeat) 并适合内部 (contain) 以及显示位置的框的中心 (center)。

小地图也被固定在视窗的右上角。

准备好背景后,我们可以在它上面添加一个滑块,它将用于操作小地图滚动。 对于滑块,我选择了 input: range,即原始、简单且普通的 HTML 滑块。

<div id="minimap">
  <input id="minimap-range" type="range" max="100" value="0">
</div>
#minimap-range {
  /* Rotating the default horizontal slider to vertical */
  transform: translateY(-100%) rotate(90deg);
  transform-origin: bottom left;
  background-color: transparent;  /* more style */
}

#minimap-range::-moz-range-thumb {
  background-color: dodgerblue; 
  cursor: pointer; /* more style */
}

#minimap-range::-moz-range-track{
  background-color: transparent;
}

不是 完全 不复杂,因为它确实需要一些调整。 我将滑块竖直旋转,以匹配小地图,并对其伪元素(特别是拇指和轨道)应用了一些样式,以替换其默认样式。 再次,由于我们正在处理有限的支持,因此我们只关心 Firefox。

剩下的就是将滑块的值与页面上相应的滚动点关联,当用户更改值时,该点将被调用。 这需要一些 JavaScript,看起来像这样

onload = () => {
  const minimapRange = document.querySelector("#minimap-range");
  const minimap = document.querySelector("#minimap");
  const article = document.querySelector("#article");
  const $ = getComputedStyle.bind();
  
  // Get the minimap range width multiplied by the article height, then divide by the article width, all in pixels.
  minimapRange.style.width = minimap.style.height = 
    parseInt($(minimapRange).width) * parseInt($(article).height) / parseInt($(article).width) + "px";
  
  // When the range changes, scroll to the relative percentage of the article height    
  minimapRange.onchange = evt => 
    scrollTo(0, parseInt($(article).height) * (evt.target.value / 100));
};

美元符号 ($) 仅仅是 getComputedStyle() 的别名,这是获取元素 CSS 值的方法。

值得注意的是,小地图的宽度已在 CSS 中设置,因此我们实际上只需要计算其高度。 因此,我们正在处理小地图的高度和滑块的宽度,因为请记住,滑块实际上是向上旋转的。

以下是脚本中方程式的确定方式,从变量开始

  • x1 = 小地图的高度(以及其中滑块的宽度)
  • y1 = 小地图的宽度
  • x2 = 文章的高度
  • y2 = 文章的宽度
x1/y1 = x2/y2
x1 = y1 * x2/y2
    
height of minimap = width of minimap * height of article / width of article

并且,当滑块的值发生变化 (minimapRange.onchange) 时,就会调用 ScrollTo() 方法,将页面滚动到文章上的相应值。 💥

我们需要回退!

显然,如果我们现在使用它,element() 将有很多时候不受支持,因此我们可能希望在这些情况下隐藏小地图。

我们在 CSS 中检查功能支持

@supports (background: element(#article)) or (background: -moz-element(#article)){
  /* fallback style */
}

…或在 JavaScript 中

if(!CSS.supports('(background: element(#article)) or (background: -moz-element(#article))')){
  /* fallback code */
}

如果您不介意背景图像缺失,那么您仍然可以保留滑块并对其应用不同的样式。

还有其他一些巧妙的方法来制作在野外飘浮的小地图(并且具有更多浏览器支持)。 这是一个由 Shaw 制作的 很棒的 Pen

查看 Pen
迷你地图进度跟踪器和滚动控制
,由 Shaw (@shshaw) 制作。
CodePen 上。

还有一些工具,如 pagemapxivimap 可以提供帮助。 element() 函数目前在 W3C 的 CSS 图像值和替换内容模块级别 4 中进行了规范。 绝对值得阅读,以充分了解其背后的意图和思考。

这些浏览器支持数据来自 Caniuse,其中包含更多详细信息。 数字表示浏览器从该版本开始支持该功能。

桌面

ChromeFirefoxIEEdgeSafari
4*

移动/平板电脑

Android ChromeAndroid FirefoxAndroidiOS Safari
127*

嘘! 你试过在 演示 中选择文章文本吗? 看看小地图上发生了什么。 😉