一.场景
需要实现时间轴列表,左边一串小圆点,右边是列表内容,需要小圆点位置与列表项对应,最终效果如下:
二.实现方案
有几个细节:
小圆点要与列表项对齐
首项、末项的时间线不能超出小圆点
列表项之间要有间隔
前两条是对自适应的要求,最后一条是对布局的限制
传统方案是通过列表容器生成一条足够长的竖线,然后列表项自带小圆点,再把小圆点对齐到竖线上。竖线的长度没有办法精确控制(不通过js计算的话),无法满足第二条,那么可以换个方式,让列表项自带同高度的竖线,拼接成完整的时间线
P.S.不用担心拼接出来的竖线会被看出来,一定是完美无缝的,否则浏览器不科学(两个相邻的块级元素之间不能有无法解释的缝隙吧,那么它们的border-left
一定能够完美连接起来)
三.具体实现
首先确定结构,因为列表项间隔的限制,列表项需要多套一层:
.listItem>.listItemContent>.listItemContent-date+.listItemContent-content
因为用margin
实现间隔的话竖线长度不对,接不起来,所以多套一层listItem
,把margin
换成padding
。由listItem
携带竖线和小圆点:
/* 列表项间隔padding-top */
.listItem {
position: relative;
padding-left: 40px;
padding-top: 4px;
}
/* 列表项自带竖线 */
.listItem:before {
content: "";
display: inline-block;
position: absolute;
top: 0;
left: 0;
width: 1px;
height: 100%;
border-right: 1px solid #f3f3f3;
left: 19px;
z-index: 1;
}
/* 列表项自带小圆点 */
.listItem:after {
content: "";
display: inline-block;
position: absolute;
width: 8px;
height: 8px;
background-color: #e0e0e0;
border-radius: 4px;
left: 16px;
top: 50%;
margin-top: -2px;
z-index: 1;
}
注意小圆点的margin-top
,这个-2px
不是目测的,与列表项间隔和小圆点高度有关:
// top 50%, marginTop -50%是小圆点相对于listItem竖直居中
h = listItemContent.height
pt = listItem.paddingTop
ch = 小圆点.height
y = (h + pt)/2 - ch/2
// 我们想要小圆点相对于listItemContent竖直居中
// 要去掉pt带来的向下偏移offsetY = pt/2 所以
top 50%, marginTop -ch/2 + offsetY
top 50%, marginTop -4 + 2
top 50%, marginTop -2
这是margin
转padding
套一层带来的麻烦
然后加上首项、末项的时间线不能超出小圆点的限制:
.listItem-first:before {
height: 50%;
top: 50%;
}
.listItem-last:before {
height: 50%;
}
最后添上高亮的效果:
/* 高亮小圆点 */
.listItem.highlight:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 16px;
height: 16px;
background-color: #3d93fd;
border: 4px solid #88bdfe;
border-radius: 8px;
left: 12px;
-webkit-box-shadow: 0 0 0 3px #d8e9ff;
box-shadow: 0 0 0 3px #d8e9ff;
z-index: 2;
}
/* 高亮列表项 */
.listItem.highlight > .listItemContent {
background-color: #3d93fd;
color: #fff;
}
/* 高亮列表项内容 */
.listItem.highlight .listItemContent-date{
color: #fff;
}
四.Demo
在线Demo:http://www.ayqy.net/temp/timeline/index.html
点击列表项高亮,列表项内容支持HTML和图片自适应
写在最后
最近在啃JS动画原理,感谢月影前辈的分享,功力深厚
之前看过几遍了,一直没有理解透彻,直到自己实现才发现数学公式与easing算子的关系
强烈推荐:关于动画,你需要知道的
文章格式很舒服,内容思路也很清晰。