WebberUI

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.jsonfiles[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型別預設值說明
textstring標題文字,以換行符 \n 分行
linesstring[]直接指定各行文字(優先於 text
as"h1"–"h6" | "p" | "div""h2"渲染的語意標籤
wdthMinnumber25wdth 軸求解下界(撐不滿時的最窄值)
wdthMaxnumber200wdth 軸求解上界(撐太寬時的最寬值)
entryWdthnumberwdthMin進場起始的極窄 wdth 值
entryCompressnumber0.34進場起始的額外水平壓縮比,彈開後回到 1
delaynumber0進場前的整體延遲(秒)
staggernumber0.09各行依序彈開的間隔(秒)
durationnumber0.9單行彈開的動畫時長(秒)
bouncenumber0.32單行彈開的彈跳量(0–1)
oncebooleantrue只在第一次進入視口時播放
lineClassNamestring附加到每一行的 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 調整)渲染,維持文件大綱層級

On this page