文字織り
background-clip: textで文字に織り目の模様を流し、可変フォントのfont-variation-settingsで太さが糸のようにうねる。
background-clip: text + font-variation-settings
対応ブラウザ
| CSS機能 | Chrome / Edge | Firefox | Safari | 備考 |
|---|---|---|---|---|
| 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;
}
}