Unlimited Wordpress themes, plugins, graphics & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Web Design
  2. Patterns
Webdesign

用CSS和一点JavaScript写一个垂直时间线

by
Difficulty:IntermediateLength:MediumLanguages:

Chinese (Simplified) (中文(简体)) translation by Songfeng Li(李松峰) (you can also view the original English article)

在本教程中,我们将从零开始学习如何构建响应式垂直时间线。 首先,创建基本的标记结构,然后应用CSS伪元素魔法。 接着,使用JavaScript添加向下滚动页面时的过渡效果。

先来看看最终完成后的时间线效果(通过CodePen来看更大的版本

1. HTML标记

标记很简单,就是一个无序列表,然后每个列表项包含一个div元素。 因为时间线上要显示事件,所以为每个列表项添加time元素以显示时间。

此外,把整个列表都放到一个section元素里,给它一个类叫timeline

此时的页面布局如下所示:

2. 添加CSS样式

先添加一些颜色(下面CSS代码的上半部分),再为列表项应用结构化的CSS规则。 同时,也为这些项目的::after伪元素添加样式:

为了清楚起见,这里删除了列表项里的内容,结果如下:

3. 时间线元素样式

现在为列表项中的div元素(我们叫它“时间线元素”)添加样式。 同样,也给这些元素的::before伪元素添加样式。

一会儿我们会看到,并不是所有“时间线元素”的样式都完全一样。 这就需要用到:nth-child(odd):nth-child(even)这两个伪类了,通过它们可以实现样式差异化。

以下是相应的CSS规则:

然后是奇数个元素的样式:

最后是偶数个元素的样式:

有了这些样式(以及补充好内容的HTML),时间线的效果就有了雏形:

奇数(odd)和偶数(even)“时间线元素”在样式上的差别主要是定位。 前者为left:45px;,后者为left:-439px;。 不理解这些值是怎么来的?好,下面是计算过程:

每个“时间线元素”的宽度+留白-每个列表项的宽度=400px+45px-6px=439px

其次,是各自伪元素上生成的箭头。 “奇数”伪元素生成左箭头,“偶数”伪元素生成右箭头。

4. 交互

时间线的基本结构完成了,下面看看新的需求:

  • 默认情况下,时间线元素应该隐藏;
  • 它们应该在父元素进入视口时出现。

第一个需求简单。 第二个还挺复杂的。 因为需要检测目标元素是否完全进入了当前视口,如果是则显示其子元素。 要实现这个功能,不需要使用任何JavaScript库(比如WOW.jsScrollReveal.js)。 甚至都不需要我们自己写太复杂的代码。 哈哈,StackOvewrflow上对这个功能有一个非常热门的讨论。 我们先用上面建议的方式测试某个元素是否完全进入了当前视口。

这是我们使用的一个简单的函数:

进入视口时添加类

接下来为当前视口中可见的列表项添加in-view类。

注意:测试它们在以下情况下是否可见很重要。

  • 页面加载时
  • 向下滚动时

有必要的话,还可以再测试更多的情况(比如浏览器窗口缩放时)。

我们这里使用的代码如下:

添加完JavaScript,再刷新页面,应该看到如下结果:

隐藏或显示

先回顾一下我们的需求。 记住,默认情况下,所有DIV都应该隐藏。 为此我们visibilityopacity这两个CSS属性。 另外,我们使用translated3d()把它们从原始位置移开200px。 只要它们的父元素可见,就显示它们并删除预先设置的位移。 这样,就可以实现漂亮的滑入特效。

最后还要做一件事,就是当li元素在视口中时,要修改其::before伪元素的背景颜色。

以下就是实现以上需要的所有样式:

下面的示意图展示了时间线的初始状态。 能看到时间线元素,是为了显示它们的初始位置而为它们应用了一点不透明度。

The default appearance of the timeline before the animations

而以下是时间线的最终状态:

The final appearance of the timeline after the animations

5. 响应式

终于快完成了。 最后一件事就是实现响应式的时间线。

首先,在所谓的“中等屏幕”(>600px且≤900px)上,我们只做少许改动。 特别是要修改DIV的宽度。

以下是要修改的规则:

此时的时间线效果如下:

而在小屏幕(≤600px)上,所有时间线元素看起来都一样,无论是奇数个还是偶数个。 同样,需要覆盖一些CSS规则:

在更小一些的屏幕上,时间线应该是这样的:

注意:在小屏幕上,我们使用了vw单位指定时间线的宽度。 使用这个单位并没有什么特别的原因。 使用百分比或像素也是一样的。

浏览器支持

以上示例可以在大多数较新的浏览器和设备中运行。 但是在iOS设备上,时间线元素始终会保持可见,而不是在它们的父元素进入视口时才出现。

根据我的测试,我发现在那些设备上window.innerHeight和document.documentElement.clientHeight返回的并非实际的视口高度。 它们返回的值要大很多。 由于存在这种不一致的问题,所有列表项都会在页面加载后获得in-view类。

虽然这不算是个大问题(通常我们都希望在大屏幕上看到动画),但假如你知道这个问题,或者以前也碰到过,请在评论中留言吧。

小结

本教程教大家写了一个响应式的垂直时间线。 涉及的知识点不少,我们来回顾一下:

  • 使用简单的无序列表和CSS伪元素,我们实现了时间线的主框架。 但也有一个不足,就是CSS伪元素并非百分之百地可用,要注意。
  • 我们利用了StackOverflow上的一段代码来检测列表项是否进入了视口。 然后,我们又写了CSS实现它们子元素的进入动画。 当然,这里也可以利用JavaScript库。

希望大家能从这篇教程中学到新东西,并利用这个时间线实现一些有意思的效果。 如果大家有什么问题,欢迎留言。

Envato qr branded
关注我们的公众号
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.