CSS
关注 JS 太久,会养成任何功能都用 JS 实现的习惯,而忘记了 HTML 与 CSS 也具备一定的功能特征。其实有些功能用 JS 实现吃力不讨好,要综合使用技术工具,而不是只依赖 JS。
5 things you don’t need Javascript for 这里就从 5 个例子出发,说明哪些功能不一定非要用 JS 做。

概述

使用 css 控制 svg 动画

原文绘制了一个放烟花的 例子,本质上是用 css 控制 svg 产生动画效果,核心代码:

  1. .trail {
  2. stroke-width: 2;
  3. stroke-dasharray: 1 10 5 10 10 5 30 150;
  4. animation-name: trail;
  5. animation-timing-function: ease-out;
  6. }
  7. @keyframes trail {
  8. from,
  9. 20% {
  10. stroke-width: 3;
  11. stroke-dashoffset: 80;
  12. }
  13. 100%,
  14. to {
  15. stroke-width: 0.5;
  16. stroke-dashoffset: -150;
  17. }
  18. }

可以看到,主要使用 stroke-dasharray 控制线条实虚线的样式,再利用动画效果对 stroke-dashoffset 产生变化,从而实现对线条起始点进行位移,实现线条 “绘图” 的效果,且该 css 样式对 svg 绘制的路径是生效的。

sidebar

可以完全使用 css 实现 hover 时才出现的侧边栏:

  1. nav {
  2. position: 'absolute';
  3. right: 100%;
  4. transition: 0.2s transform;
  5. }
  6. nav:hover,
  7. nav:focus-within {
  8. transform: translateX(100%);
  9. }

核心在于 hover 时设置 transform 属性可以让元素偏移,且 translateX(100%) 可以位移当前元素宽度的身位。
另一个有意思的是,如果使用 TABS 按键聚焦到 sidebar 内元素也要让 sidebar 出来,可以直接用 :focus-within 实现。如果需要 hover 后延迟展示可以使用 transition-delay 属性。

sticky position

使用 position: sticky 来黏住一个元素:

  1. .square {
  2. position: sticky;
  3. top: 2em;
  4. }

这样该元素会始终展示在其父容器内,但一旦其出现在视窗时,当 top 超过 2em 后就会变为 fixed 定位并保持原位。
使用 JS 判断还是挺复杂的,得设法监听父元素滚动,并且在定位切换时可能产生一些抖动,因为 JS 的执行与 CSS 之间是异步关系。但当只用 CSS 描述这个行为时,浏览器就有办法解决转换时的抖动问题。

手风琴菜单

使用 <details> 标签可以实现类似一个简易的折叠手风琴效果:

  1. <details>
  2. <summary>title</summary>
  3. <p>1</p>
  4. <p>2</p>
  5. </details>

<details> 标签内的 <summary> 标签内容总是会展示,且点击后会切换 <details> 内其他元素的显隐藏。虽然这做不了特殊动画效果,但如果只为了做一个普通的展开折叠功能,用 HTML 标签就够了。

暗色主题

虽然直觉上暗色主题好像是一种定制业务逻辑,但其实因为暗色主题太过于普遍,以至于操作系统和浏览器都内置实现了,而 CSS 也实现了对应的方法判断当前系统的主题到底是亮色还是暗色:prefers-color-scheme。
所以如果系统要实现暗色系主题,最好可以和操作系统设置保持一致,这样用户体验也会更好:

  1. @media (prefers-color-scheme: light) {
  2. /** ... */
  3. }
  4. @media (prefers-color-scheme: dark) {
  5. /** ... */
  6. }
  7. @media (prefers-color-scheme: no-preference) {
  8. /** ... */
  9. }

如果使用 Checkbox 勾选是否开启暗色主题,也可以仅用 CSS 变量判断,核心代码是:

  1. #checkboxId:checked ~ .container {
  2. background-color: black;
  3. }

~ 这个符号表示,selector1 ~ selector2 时,为选择器 selector1 之后满足 selector2 条件的兄弟节点设置样式。

精读

除了上面例子外,再追加几个例子。

幻灯片滚动

幻灯片滚动即每次滚动有固定的步长,把子元素完整的展示在可视区域,不可能出现上下或者左右两个子元素各出现一部分的 “割裂” 情况。
该场景除了用浏览器实现幻灯片外,在许多网站首页也被频繁使用,比如将首页切割为 5 个纵向滚动的区块,每个区块展示一个产品特性,此时滚动不再是连续的,而是从一个区块到另一个区块的完整切换。
其实这种效果无需 JS 实现:

  1. html {
  2. scroll-snap-type: y mandatory;
  3. }
  4. .child {
  5. scroll-snap-align: start;
  6. }

这样便将页面设置为精准捕捉子元素滚动位置,在滚轮触发、鼠标点击滚动条松手或者键盘上下按键时,scroll-snap-type: y mandatory 可以精准捕捉这一垂直滚动行为,并将子元素完全滚动到可视区域。

颜色选择器

使用 HTML 原生就能实现颜色选择器:

  1. <input type="color" value="#000000">

2022-07-10-18-30-46-901693.png
该选择器的好处是性能、可维护性都非常非常的好,甚至可以捕捉桌面的颜色,不好的地方是无法对拾色器进行定制。