Woodtype Flush Block
木活字齊行標題:多行標題塊各行透過可變字體 wdth 軸自動求解拉伸至左右切齊撐滿容器,進場時各行從極窄字寬依序彈開到解出的寬度。
載入預覽⋯
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
200
0.34
0.09
0.9
0.32
<WoodtypeFlushBlock />
安裝
npx shadcn@latest add https://webberui.com/r/woodtype-flush-block.json或在 components.json 設定 registries 後,改用 @webberui/woodtype-flush-block 安裝。
安裝依賴後,從 registry JSON(/r/woodtype-flush-block.json 的 files[0].content)複製 woodtype-flush-block.tsx 原始碼到你的 components/ui/ 目錄:
npm install motion clsx tailwind-merge使用
import { WoodtypeFlushBlock } from "@/components/ui/woodtype-flush-block";
<WoodtypeFlushBlock
text={"THE\nWOODTYPE\nREVIVAL"}
className="font-black uppercase leading-[0.92]"
lineClassName="text-6xl"
/>以換行符 \n 分行,或改用 lines 直接傳入陣列:
<WoodtypeFlushBlock
lines={["THE", "WOODTYPE", "REVIVAL"]}
className="font-black uppercase"
/>要讓 wdth 軸真正生效,容器的字型需為帶 寬度(wdth)軸的可變字體(例如 Roboto Flex、Recursive、Fraunces)。字型若不支援該軸,元件會自動退回以水平縮放補足,仍能維持齊行與彈開效果。
Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
text | string | — | 標題文字,以換行符 \n 分行 |
lines | string[] | — | 直接指定各行文字(優先於 text) |
as | "h1"–"h6" | "p" | "div" | "h2" | 渲染的語意標籤 |
wdthMin | number | 25 | wdth 軸求解下界(撐不滿時的最窄值) |
wdthMax | number | 200 | wdth 軸求解上界(撐太寬時的最寬值) |
entryWdth | number | wdthMin | 進場起始的極窄 wdth 值 |
entryCompress | number | 0.34 | 進場起始的額外水平壓縮比,彈開後回到 1 |
delay | number | 0 | 進場前的整體延遲(秒) |
stagger | number | 0.09 | 各行依序彈開的間隔(秒) |
duration | number | 0.9 | 單行彈開的動畫時長(秒) |
bounce | number | 0.32 | 單行彈開的彈跳量(0–1) |
once | boolean | true | 只在第一次進入視口時播放 |
lineClassName | string | — | 附加到每一行的 class(常用來設定字級) |
細節
- 齊行求解:木活字排版最迷人之處,是不同字數的行都被撐到左右切齊。元件為每行建立一個隱藏量測 span,在不同
wdth下量測實際寬度,再以二分逼近求出能剛好填滿容器內容區寬度的wdth值——短行(字少)需要更寬的字寬、長行(字多)需要更窄的字寬,因而各行的wdth天然不同。 - 像素級補償:可變字體的
wdth軸各有上下限,遇到極短或極長的行時單靠字寬可能撐不滿或撐過頭。求解後元件會以殘差scaleX補足最後幾像素,確保每一行真正切齊;字體本身若不含wdth軸,scaleX便獨力完成齊行,效果依然成立。 - 彈開進場:進入視口時,各行從
entryWdth(極窄字寬)加上entryCompress的額外壓縮起手,像一柱細窄的木活字,依stagger依序以 spring 彈開到解出的寬度;bounce控制回彈手感。字寬經 CSS 變數--wb-wdth驅動,font-variation-settings即時反映其變化。 - 響應式重解:以
ResizeObserver監看容器寬度,並在document.fonts.ready(網頁字體載入完成)後再求解一次;容器改變寬度時各行會平滑地重新齊行。量測與求解都在 layout effect 中於首次繪製前完成,避免版面閃動。 - 排版建議:搭配粗字重(
font-black)、大寫(uppercase)與偏緊的leading最能呈現木活字海報的密實層疊感;字級建議寫在lineClassName上,容器className則放字重、字距與顏色等共用樣式。
可及性
- 使用者系統開啟「減少動態效果」時,直接以求解後的字寬呈現齊行標題,不做進場彈開動畫
- 完整標題文字放在
sr-only,供螢幕閱讀器一次朗讀;視覺層與隱藏量測層皆為aria-hidden的裝飾性複本,不會重複朗讀 - 標題以語意標籤(預設
h2,可經as調整)渲染,維持文件大綱層級