背景

极光漂移

两团模糊色斑用互不整除的周期各自漂移,所以整体图案不会肉眼可见地循环。两个伪元素搞定,不用图、不用 canvas。

怎么做到的

参数

Blob size
420px / 460px
Blur
90px
Opacity
0.55
Periods
18s / 22s, ease-in-out alternate
Travel
≤80px, scale ≤1.12

提示词

把这段丢给任意一个写代码的模型,就能从零长出这个效果。它把每个数值都写死了 ——「丝滑」「现代感」这种词每次生成出来的都不一样。

Create an ambient background using two pseudo-elements on a container. Each is a circle (420px and 460px) filled with a radial-gradient from a pastel colour to transparent at 70%, with filter: blur(90px) and opacity 0.55, positioned so they overflow opposite corners of the container. Animate each with a different period — 18s and 22s, ease-in-out, infinite alternate — moving them by no more than 80px with translate() and scaling to at most 1.12. Animate transform only, never top/left. Set overflow: hidden and isolation: isolate on the container, put the blobs at z-index: -1, and disable both animations under prefers-reduced-motion: reduce.

源码

整个文件。上面那个样板跑的就是它 —— 存成 .html 打开就能用,不需要别的任何东西。

aurora-drift.html
<!doctype html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Aurora drift</title>
<style>
  * { margin: 0; padding: 0; box-sizing: border-box; }
  body {
    min-height: 100vh;
    display: grid; place-items: center;
    background: #fbfbfd;
    font: 600 clamp(22px, 5vw, 34px)/1.1 -apple-system, BlinkMacSystemFont, "SF Pro Display", sans-serif;
    letter-spacing: -0.025em;
    color: #1d1d1f;
    /* The blobs deliberately overflow the viewport. Without this the page
       grows scrollbars around them. */
    overflow: hidden;
    position: relative;
    isolation: isolate;
  }

  /* Two large blurred blobs, each drifting on its own period.
     The periods are 18s and 22s — deliberately not equal, and not
     multiples of one another. Give both the same duration and the whole
     composition visibly repeats every cycle. */
  body::before, body::after {
    content: "";
    position: absolute; z-index: -1;
    border-radius: 50%;
    filter: blur(90px);
    opacity: 0.55;
    pointer-events: none;
  }
  body::before {
    width: 420px; height: 420px; top: -12%; left: -10%;
    background: radial-gradient(circle, #a6dcf5, transparent 70%);
    animation: drift-a 18s ease-in-out infinite alternate;
  }
  body::after {
    width: 460px; height: 460px; bottom: -14%; right: -12%;
    background: radial-gradient(circle, #f5cde8, transparent 70%);
    animation: drift-b 22s ease-in-out infinite alternate;
  }

  /* Animate transform only. Moving the blob by changing top/left would
     re-run the 90px blur every frame; a transform hands the already-blurred
     layer to the compositor and merely moves it. */
  @keyframes drift-a { to { transform: translate(70px, 50px) scale(1.12); } }
  @keyframes drift-b { to { transform: translate(-80px, -60px) scale(1.08); } }

  @media (prefers-reduced-motion: reduce) {
    body::before, body::after { animation: none; }
  }
</style>

<p>Quiet light, moving slowly.</p>

会翻车的地方