前两天在 Youtube 上看视频时,无意间发现视频播放器的播放暂停切换按钮动画十分流畅,于是就想试着用 CSS 仿制一下,先上效果图:

等等,暂停按钮可以用border-left与border-right实现,播放的三角形也可以用边框实现,这岂不是骗小孩子的把戏?于是乎没几分钟,我们就可以写出这么一个实现:
可是致命的缺陷是,由于暂停按钮中间缝隙的关系,我们必须对width元素进行动画处理,这直接导致border-width的动画无法按照我们设想的方式工作。于是乎,换个方向考虑,只能使用伪元素或者再添加一个div元素将两个边框分别实现了。
在这里为了布局方便,能够使用flex布局,使用两个div来实现,实际也可以只用一个div配合伪元素以及普通定位方式来获得更好的兼容性。
首先用两个div的边框模拟出暂停按钮的两个大长棍:
1 | <head> |
然后为外层div添加一个click事件,在click事件触发时toggle两个子div元素的active类:
1 | $div = document.querySelector(".wrapper"); |
接下来我们就得定义这两根大棒在active状态下的属性了:左边的大棒在active状态下变换为梯形,右边的大棒在active状态下变换为三角形,且梯形的腰与三角形的两条边要在同一条直线上。这就要求border-left-width与border-top-width的比值一定,即可以使用公共的border-width系列属性。在这里为了让上下边框也能受到transition属性的影响,在.box中也要定义初始值。
1 | .box { |
为了使右边的大棒在active状态下缩小为三角形,需要将其高度设置为0;为了使左边的大棒缩小为梯形,需要将其高度设置为短边的长度,即24px/2 = 12px:
1 | .right.active { |
到这里这个简单的 CSS 动画就完成啦,完成效果:
当然,如果要完全不使用JavaScript,则可以使用input复选框与label标签的:active伪类以及::before、::after伪元素来实现,只不过语义性会有一定的缺失。并且,由于没有flexbox黑科技的支持,居中定位会变得麻烦一点。