lab-css

文字織り

background-clip: textで文字に織り目の模様を流し、可変フォントのfont-variation-settingsで太さが糸のようにうねる。

全画面で見る
background-clip: textfont-variation-settings操作: 鑑賞のみ

対応ブラウザ

CSS機能Chrome / EdgeFirefoxSafari備考
background-clip: text対応対応対応全主要ブラウザ対応
font-variation-settings対応対応対応可変フォントが必要

コード

表示中のコードは作品の実行に使われているものと同一ソースです。そのままコピーして試せます。

/* 文字織り: 文字に織り目の模様を流し、可変フォントの太さ(wght軸)が
   糸のようにうねる。フォントはページ側で読み込む可変フォントを使用 */

.work-text-weave {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  display: grid;
  place-items: center;
  align-content: center;
  gap: 10px;
  background: #0d0d13;
}

/* 背景の織機: 経糸と緯糸のパターン */
.tw-loom {
  position: absolute;
  inset: 0;
  background-image:
    repeating-linear-gradient(90deg,
      rgba(242, 165, 184, 0.05) 0 2px, transparent 2px 26px),
    repeating-linear-gradient(0deg,
      rgba(124, 199, 242, 0.05) 0 2px, transparent 2px 26px);
}

.tw-word {
  position: relative;
  margin: 0;
  display: flex;
  font-family: var(--font-mplus1, "M PLUS Rounded 1c", sans-serif);
  font-size: clamp(56px, 18vmin, 170px);
  line-height: 1.15;
  letter-spacing: 0.02em;
}

/* 1文字ずつ同じ織り柄を少しずつずらして敷く。
   背景を文字の形にクリップし、文字色は透明にする */
.tw-ch {
  display: inline-block;
  background-image:
    repeating-linear-gradient(45deg,
      #f2a5b8 0 8px, #b98cf0 8px 16px, #7cc7f2 16px 24px, #9df0c8 24px 32px),
    repeating-linear-gradient(-45deg,
      rgba(255, 255, 255, 0.35) 0 4px, transparent 4px 12px);
  background-blend-mode: overlay;
  background-size: 200% 200%;
  background-position: calc(var(--i) * -12%) 0%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font-variation-settings: "wght" 400;
  animation:
    tw-flow 12s linear infinite,
    tw-thread 3.6s ease-in-out infinite;
  animation-delay: calc(var(--i) * -0.45s);
}

/* 織り柄が流れる */
@keyframes tw-flow {
  to {
    background-position: calc(var(--i) * -12% - 200%) 200%;
  }
}

/* 糸の太さがうねる(可変フォントのwght軸) */
@keyframes tw-thread {
  0%, 100% {
    font-variation-settings: "wght" 250;
    transform: translateY(0);
  }

  50% {
    font-variation-settings: "wght" 850;
    transform: translateY(-0.04em);
  }
}

.tw-caption {
  position: relative;
  margin: 0;
  color: rgba(235, 235, 240, 0.4);
  font-family: monospace;
  font-size: clamp(10px, 1.8vmin, 13px);
  letter-spacing: 0.08em;
}

/* 動きへの配慮: 停止し、CSSのみのチェックボックスでオプトイン再生 */
@media (prefers-reduced-motion: reduce) {
  .work-text-weave * {
    animation-play-state: paused !important;
  }

  .work-text-weave .motion-optin {
    display: inline-flex;
  }

  .work-text-weave:has(.motion-optin input:checked) * {
    animation-play-state: running !important;
  }
}