用纯 CSS 制作播放/暂停按钮

Avatar of Daniel Abdilla
Daniel Abdilla

DigitalOcean 提供适用于旅程每个阶段的云产品。 立即开始使用 200 美元的免费积分!

在全球范围内,媒体控制图标是任何界面中最普遍理解的视觉语言之一。 设计师可以简单地假设每个用户不仅知道 ▶️ = 播放,而且用户会寻找该图标以观看任何视频或动画。

据报道,该播放箭头是由瑞典工程师菲利普·奥尔森在 1960 年代推出的,最初设计用于指示磁带在卷盘式磁带机上播放时的前进方向。 从那时起,我们从盒式磁带转向 CD,从 iPod 转向 Spotify,但媒体控制图标保持不变。

播放 ▶️ 图标是标准符号(有自己的 unicode),用于启动音频/视频媒体,以及其他符号,如停止、暂停、快进、倒带等。

有播放按钮图标的 unicode 和表情符号选项,但如果你想要自定义内容,你可能会使用图标字体或自定义资源。 但是,如果你想在图标之间切换呢? 这变化可以平滑吗? 一种解决方案可能是使用 SVG。 但是,如果它可以在 10 行 CSS 中完成呢? 真是太酷了!

在本文中,我们将用 CSS 构建播放按钮和暂停按钮,然后探索如何使用 CSS 过渡在它们之间进行动画。

播放按钮

第一步

我们想要实现一个指向右边的三角形。 让我们从创建一个具有粗边框的框开始。 目前,框是制作三角形的首选基础方法。 我们将从粗边框和亮色开始,以帮助我们看到我们的更改。

<button class='button play'></button>
.button.play {
  width: 74px;
  height: 74px;
  border-style: solid;
  border-width: 37px;
  border-color: #202020;
}

第二步

渲染纯色边框会产生上述结果。 在边框颜色后面隐藏着一个巧妙的小技巧。 边框究竟是如何渲染的? 让我们改变边框颜色,每边一种颜色,这将帮助我们看到边框是如何渲染的。

.button.play {
  ...
  border-width: 37px 37px 37px 37px;
  border-color: red blue green yellow;
}

第三步

在每个边框的交点处,你会注意到形成了一个 45 度角。 这是浏览器渲染边框的一种有趣方式,因此,它为不同的形状(如三角形)打开了可能性。 正如我们在下面将看到的,如果我们将 border-left 设置得足够宽,看起来我们可能可以实现一个三角形!

.button.play {
  ...
  border-width: 37px 0px 37px 74px;
  border-color: red blue green yellow;
}

第四步

好吧,这与预期结果不符。 似乎内部框(实际的 div)坚持保留其宽度。 原因与 box-sizing 属性 有关,该属性默认值为 content-box。 值 content-box 指示 div 将任何边框放在外部,从而增加宽度或高度。

如果我们将此值更改为 border-box,则边框将添加到框的内部

.button.play {
  ...
  box-sizing: border-box;
  width: 74px;
  height: 74px;
  border-width: 37px 0px 37px 74px;
}

最后一步

现在我们得到了一个合适的三角形。 接下来,我们需要去除顶部和底部部分(红色和绿色)。 我们通过将这些边的 border-color 设置为 transparent 来实现。 宽度还可以控制三角形的形状和大小。

.button.play {
  ...
  border-color: transparent transparent transparent #202020;
}

这是一个解释该动画的动画,如果它有帮助的话。

暂停按钮

第一步

我们将从另一个具有粗边框的框开始继续制作暂停符号,因为前一个框效果很好。

<button class='button pause'></button>
.button.pause {
  width: 74px;
  height: 74px;
  border-style: solid;
  border-width: 37px;
  border-color: #202020;
}

第二步

这次我们将使用另一个 CSS 属性来实现两条平行线的预期结果。 我们将 border-style 更改为 doubleborder-style 中的 double 属性非常简单,它通过在两条边框之间添加透明笔划来使边框加倍。 笔划或空隙将占给定边框宽度的 33%。

.button.pause {
  ...
  border-style: double;
  border-width: 0px 37px 0px 37px;
}

最后一步

border-width 属性。 使用 border-width 将使过渡在下一步中平滑地工作。

.button.pause{
  ...
  border-width: 0px 0px 0px 37px;
  border-color: #202020;
}

动画过渡

在我们上面创建的两个按钮中,请注意它们有很多相似之处,但有两个区别:border-widthborder-style。 如果我们使用 CSS 过渡,我们可以在这两个符号之间切换。 border-style 没有过渡效果,但 border-width 效果很好。

现在,pause 类切换将在播放和暂停状态之间进行动画。

以下是 SCSS 中的最终样式

.button {
  box-sizing: border-box;
  height: 74px;
  
  border-color: transparent transparent transparent #202020;
  transition: 100ms all ease;
  will-change: border-width;
  cursor: pointer;

  // play state
  border-style: solid;
  border-width: 37px 0 37px 60px;

  // paused state
  &.pause {
    border-style: double;
    border-width: 0px 0 0px 60px;
  }
}

演示

查看 CodePen 上 Chris Coyier (@chriscoyier) 的 带有边框的按钮过渡

无需 JavaScript 切换

对于实际的播放/暂停按钮,你几乎肯定会在使用 JavaScript 来切换按钮的状态。 但是,了解用 CSS 来实现这一点很有趣,它利用了输入和标签:复选框技巧

<div class="play-pause">
  <input type="checkbox" value="" id="playPauseCheckbox" name="playPauseCheckbox" />
  <label for="playPauseCheckbox"></label>
</div>
.playpause {
  label {
    display: block;
    box-sizing: border-box;
    
    width: 0;
    height: 74px;
    
    cursor: pointer;

    border-color: transparent transparent transparent #202020;
    transition: 100ms all ease;
    will-change: border-width;
    
    // paused state
    border-style: double;
    border-width: 0px 0 0px 60px;
  }
  input[type='checkbox'] {
    visibility: hidden;
    
    &:checked + label {
      // play state
      border-style: solid;
      border-width: 37px 0 37px 60px;
    }
  }
}

演示

查看 CodePen 上 Chris Coyier (@chriscoyier) 的 带有复选框的切换按钮

我非常希望听到你的想法和反馈。 请在下面的评论中添加它们。