HTML 幻灯片无需框架,仅需 CSS
我是reveal.js的忠实粉丝,几乎每次演讲都会用到它。它是一个功能齐全的演示框架,拥有许多实用的功能,例如演讲者备注、全屏模式、代码语法高亮等等。
但有时,我只需要在本地聚会或办公室演示时,在屏幕上显示一些信息。作为一名 Web 开发人员,我更习惯使用 CSS 来控制和调整布局,而不是使用点击式的界面。
我偶然发现了Ondřej Žára的一个纯 CSS 幻灯片实现,于是深入研究了他的代码库,想看看能用哪些代码制作我自己的精简版 HTML 幻灯片。作为一个纯 CSS 实现,它功能相当齐全,无论如何你都应该尝试一下。
伪:target
类
我想要的是一种幻灯片之间良好过渡的方式,我注意到 Ondřej 使用了:target
伪类。它是一个选择器,用于匹配一个元素,该元素的 ID 与当前 URL 的片段(用#
符号表示)匹配。
例如,如果您的网站有一个 ID 为 的元素dinosaur
,您可以使用 URL 从地址栏导航到该元素https://www.example.com/index.html#dinosaur
。如果这是当前 URL,则以下 CSS 规则将应用于该#dinosaur
元素:
#dinosaur:target {
background-color: green;
}

有了这些,我们就可以开始恶作剧了。
标记结构
HTML 结构可以相当简单。
<main>
<section id="slide1"></section>
<section id="slide2"></section>
<section id="slide3"></section>
<section id="slide4"></section>
<section id="slide5"></section>
</main>
每张幻灯片都可以是占据视口整个高度的部分。使用视口单位,我们可以相对轻松地实现这一点。顾名思义,视口单位是相对于视口大小的 CSS 单位。
我们有vw
、和。为了制作 HTML 幻灯片,这里相关的单位是或视口高度。通过为每个部分设置 的高度,无论您如何调整浏览器大小,它们都将始终是视口的高度vh
。vmax
vmin
vh
100vh
每张幻灯片都有一个可以定位的唯一 ID,这将成为幻灯片控制的机制。

那么,这一切中的伪类在哪里呢:target
?等等,我们马上就要谈到它了。我们之前所做的是让浏览器跳转到每个部分的顶部,你仍然可以上下滚动,让你的演示文稿看起来更像一个网页,而不是幻灯片。
如果这就是你想要的效果,那就太好了。说实话,今天的工作就完成了。但是,假设我们不想激活滚动条。我们只想让活动幻灯片显示在视口中,仅此而已。这时:target
伪类就派上用场了。
堆叠幻灯片
但在深入讨论之前,让我们先想象一下幻灯片的表现方式。
我们将对各个部分进行样式设置,以便通过将它们堆叠在一起,一次只能看到一张幻灯片,然后利用 URL 片段来指示哪张幻灯片应该处于活动状态。
那么,沿着 z-index 堆叠,对吧?现在我们有不止一个方法来实现类似的效果。让我们来介绍一下久经考验的 Position 和 Z-index 技术。该属性仅适用于定位框,即具有除默认值 之外的任何值的z-index
框。position
static
现在新增了4个值position
,分别是relative
、absolute
和。Elad Shechter撰写了一篇关于其工作原理的精彩深入的文章,不妨一读。fixed
sticky
sticky
根据规范:
根元素构成根堆叠上下文。其他堆叠上下文由任何具有除 'auto' 之外的 'z-index' 计算值的定位元素(包括相对定位元素)生成。
因此,一旦你将位置属性应用于框,就可以使用该z-index
属性来调整其堆叠级别。设置position: absolute
框的位置会将其从正常流中移除,并使其相对于其包含块显式偏移。
绝对定位元素的内容不会流到其他框周围,如果它们具有更高的堆栈级别,它们只会覆盖其下方的所有内容。

要将它们全部叠加,请在每张幻灯片上应用position: absolute
和。有些人可能会想,在绝对定位元素上使用 和将所有偏移值设置为有什么区别?(例如)幸好其他人也问过同样的问题。width: 100%
width: 100%
0
top: 0; right: 0; bottom: 0; left: 0
Keith J. Grant对这两种方法之间的差异进行了分析,并发现如果width: 100%
在元素周围使用额外的边距,它将移出其定位的祖先。
但是因为我想让我的幻灯片填满视口,所以我根本不使用边距,所以我宁愿做一行而不是 4 行。🤷
接下来的事情是使用我们可靠的选择器调整活动幻灯片的 z 索引,使其高于所有其他非活动幻灯片:target
。
section {
height: 100vh;
width: 100%;
position: absolute;
z-index: 0;
}
section:target {
z-index: 1;
}
有些人以不同的方式处理 z-index,使用 10 或 100 的面额,但老实说,在两个元素之间,无论整数值是 1 还是 1000,哪个元素的整数值较大就获胜。

添加一些动画
为了给这项工作增添一些专业性(我在开玩笑吧?),我认为一些幻灯片过渡效果是必要的。CSS 也提供了一套很棒的动画选项。你可以使用 CSS 的 transforms 来实现旋转、缩放、滑入和滑出等效果。
如果你看过 Ondřej 的幻灯片,你会发现他使用了旋转效果,所以让我们来试试看。旋转效果有三种位置状态:进入视口前、在视口中处于活动状态以及离开视口。
默认值为transform-origin
,50% 50%
表示元素将围绕其中心旋转。要使某个角像图中那样旋转,请将值设置为0 0
。所有幻灯片在视口外开始时都会顺时针旋转 90 度,而离开视口的幻灯片将逆时针向上向外旋转 90 度。
我们可以利用同级选择器来定位活动幻灯片之后的幻灯片,并添加一些过渡值以使动画看起来更流畅:
section {
height: 100vh;
width: 100%;
position: absolute;
z-index: 0;
transform: rotate(90deg);
transform-origin: 0 0;
transition: transform 1s, opacity 0.8s;
}
section:target {
transform: rotate(0deg);
z-index: 1;
}
section:target ~ section {
opacity: 0;
transform: rotate(-90deg);
}
当幻灯片旋转出视口时,它会以某种方式触发滚动条。我还没弄清楚具体原因,但我知道解决方案是overflow: hidden
在body
元素中添加一个。我应该再研究一下,因为我使用翻译时不会发生这种情况。
总结
还有一点需要注意,幻灯片首次加载时,不会触发任何 URL 片段,这意味着所有幻灯片都不会处于活动状态。要解决这个问题,请为第一张幻灯片添加一个链接,该链接将在首次加载时显示,并确保它也是一个定位元素。

如果旋转不适合你的风格,可以尝试其他 CSS 变换来实现更多幻灯片过渡效果。但如果你的幻灯片需求比较简单,不妨试试这个方法。你甚至可以把它放到一些免费的静态网站托管平台上,随时随地访问。😎
要了解其实际实现,请查看介绍 Talk.CSS 的幻灯片
鏂囩珷鏉ユ簮锛�https://dev.to/huijing/html-slides-without-frameworks-just-css-323g