WebberUI

Vertical Writing Spread

以 CSS writing-mode 建構的中日文直排編輯版面,直欄自右向左流動、橫排引文與圖片穿插其間,進場逐字自上而下顯影,並支援水平捲動推進欄序。

載入預覽⋯

Playground

即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。

32
0.05
0.7
<VerticalWritingSpread />

安裝

npx shadcn@latest add https://webberui.com/r/vertical-writing-spread.json

或在 components.json 設定 registries 後,改用 @webberui/vertical-writing-spread 安裝。

安裝依賴後,從 registry JSON(/r/vertical-writing-spread.jsonfiles[0].content)複製 vertical-writing-spread.tsx 原始碼到你的 components/ui/ 目錄:

npm install motion clsx tailwind-merge

使用

VerticalWritingSpread 作為容器,內部依閱讀順序放入直排的 VerticalColumn 與橫排的 HorizontalInsert。版面自右向左流動,第一欄位於最右端;容器需要一個固定高度(直欄以此填滿):

import {
  VerticalWritingSpread,
  VerticalColumn,
  HorizontalInsert,
} from "@/components/ui/vertical-writing-spread";

<VerticalWritingSpread className="h-[320px]" showProgress fadeEdges>
  <VerticalColumn variant="heading">直排的秩序</VerticalColumn>
  <VerticalColumn>正文以直欄流動,自右向左閱讀……</VerticalColumn>

  <HorizontalInsert>
    <blockquote>「留白不是空白,而是呼吸。」</blockquote>
  </HorizontalInsert>

  <VerticalColumn>橫排引文與圖片穿插其間,成為視線的停頓……</VerticalColumn>
  <VerticalColumn variant="heading">版面即敘事</VerticalColumn>
</VerticalWritingSpread>

直欄在進入可視範圍時逐字自上而下顯影;預設開啟 wheelToHorizontal,垂直滾輪會轉為水平推進欄序,捲到兩端邊界時自動放行頁面捲動。

Props

VerticalWritingSpread

Prop型別預設值說明
childrenReact.ReactNode依閱讀順序放入 VerticalColumnHorizontalInsert,自右向左排列
gapnumber32欄與欄之間的水平間距(px)
columnHeightnumber | string"100%"直欄高度;預設填滿容器,容器需自帶固定高度
wheelToHorizontalbooleantrue將垂直滾輪轉為水平推進欄序,邊界處放行頁面捲動
showProgressbooleanfalse在底部顯示水平閱讀進度條
fadeEdgesbooleanfalse左右邊緣以遮罩淡出,暗示尚有內容可捲
staggernumber0.05直欄大標逐字進場的每字間隔(秒)
durationnumber0.7單欄/單字進場時長(秒)
oncebooleantrue只在第一次進入可視範圍時播放進場動畫
ariaLabelstring"直排跨頁版面"套用在可捲動區段的無障礙標籤
classNamestring附加到外層可捲動容器(在此設定高度)的 class
trackClassNamestring附加到內層水平軌道的 class(如左右內距)

VerticalColumn

Prop型別預設值說明
variant"heading" | "body""body"heading 為直排大標(純字串時逐字進場),body 為直排正文
childrenReact.ReactNode欄內容;大標傳入字串可逐字顯影
writingMode"vertical-rl" | "vertical-lr""vertical-rl"直排文字方向
classNamestring附加到欄容器的 class

HorizontalInsert

Prop型別預設值說明
childrenReact.ReactNode穿插於直排欄之間的橫排區塊:引文、圖片或圖說
align"start" | "center" | "end""center"在直排流中的垂直對齊位置
classNamestring附加到區塊容器的 class

細節

  • 直排以 CSS writing-mode: vertical-rl 建構,正文沿垂直方向落下、自動換行成多個直行;HorizontalInserthorizontal-tb 打斷直排流,承載橫排引文與圖片
  • 版面自右向左:軌道採 flex-row-reverse,第一欄位於最右端,掛載時自動捲至最右,符合中日文閱讀方向
  • 進場偵測以 IntersectionObserver(root 為捲動容器)驅動;大標逐字自上而下 stagger 顯影,正文欄以 clip-path 由上而下揭示
  • wheelToHorizontal 將垂直滾輪映射為水平推進,向下捲動使欄序前進(向左);到達兩端邊界時放行頁面捲動,不會鎖住滾動

可及性

  • 捲動區段為可聚焦的 role="region",帶 aria-labelArrowDown / Space 前進、ArrowUp 後退,並依 reduced motion 切換平滑或即時捲動
  • 逐字大標保留 sr-only 的完整文字,拆分後的字素對輔助科技隱藏(aria-hidden),朗讀時是完整詞句
  • 使用者系統開啟「減少動態效果」時,直排版面與水平捲動保留,僅停用進場的顯影與 stagger 動畫(內容即刻完整呈現)

On this page