卡片與網格
郵票外框
以純 CSS clip-path 算出四邊扇貝齒孔的郵票外框 React 元件,可包圖片或任意內容,附面額說明列與可選的 SVG 郵戳疊層(hover 淡入)。
把任何內容包成一張郵票。四邊的扇貝齒孔由一條 clip-path: polygon() 算出——每個齒孔用 7 個點近似半圓,位置用百分比、深度用 px,尺寸改變時不需重算;紙面帶 145° 白色高光與兩層投影。底部可放面額與名稱的說明列,右上角可疊一枚 SVG 郵戳(雙圓環、繞圓文字、中央日期與三條波浪註銷線),預設在 hover 或鍵盤聚焦時淡入。本體沒有動畫。
把這個效果裝進你的專案
在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。
npx webberui@latest add postage-stamp-framePlayground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
12
15
6
14
200
編輯中的呼叫預設屬性
<PostageStampFrame/>
完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。
安裝
npx webberui@latest add https://webberui.com/r/postage-stamp-frame.json或在 components.json 設定 registries 後,改用 @webberui/postage-stamp-frame 安裝。
使用
import { PostageStampFrame } from "@/components/ui/postage-stamp-frame";
<div className="w-48">
<PostageStampFrame
horizontalPerforations={12}
verticalPerforations={15}
postmark={{ text: "台北 TAIPEI", date: "2026.10.25" }}
caption={
<>
<span>NT$ 12</span>
<span>雲嶺晨霧</span>
</>
}
>
<img src="/stamps/mountain.jpg" alt="晨霧中的山景" />
</PostageStampFrame>
</div>Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
children | ReactNode | — | 郵票內容;直接放 img 時自動 object-cover 填滿 |
horizontalPerforations | number | 12 | 上下兩邊各有幾個齒孔 |
verticalPerforations | number | 15 | 左右兩邊各有幾個齒孔 |
perforationDepth | number | 6 | 齒孔半圓的凹陷深度(px) |
padding | number | 14 | 內容區與齒孔之間的留白(px) |
aspect | string | "4 / 5" | 郵票長寬比(CSS aspect-ratio 值) |
paper | string | "#fbfaf7" | 紙面顏色;未提供時讀 --wb-stamp-paper |
ink | string | "#262626" | 墨色,用於說明列與郵戳;未提供時讀 --wb-stamp-ink |
caption | ReactNode | — | 齒孔內底部的一列說明(面額、名稱等),等寬字 10px |
postmark | PostageStampPostmark | boolean | — | 右上角郵戳疊層;true 用預設文字「POST · 郵資已付」,傳物件可自訂 |
postmarkOnHover | boolean | true | 郵戳是否只在 hover/鍵盤聚焦時淡入;false 則常駐顯示 |
postmarkDuration | number | 200 | 郵戳淡入時長(ms);未提供時讀 --wb-stamp-postmark-duration |
className | string | — | 透傳到最外層容器 |
PostageStampPostmark
| 欄位 | 型別 | 預設值 | 說明 |
|---|---|---|---|
text | string | — | 沿郵戳外圈排列的文字(例如地名) |
date | string | — | 郵戳中央的日期字串 |
細節
- 齒孔:每一段齒距的中點往內凹一個半圓,用
calc(百分比 ± px)寫每個點,所以元件寬度改變時齒孔大小不變、也不需要 ResizeObserver。齒數多且齒深大時相鄰半圓會重疊,可降低perforationDepth。 - 投影:兩層
drop-shadow放在clip-path元素的父層,否則陰影會被一起裁掉。 - 紙色在暗色模式下保持不變(郵票本身是一張紙),內容文字預設繼承墨色。
- 主題變數:
--wb-stamp-paper、--wb-stamp-ink、--wb-stamp-postmark-duration;對應的 prop 有傳值時以 prop 為準。 - 郵戳疊在外框之外、以
mix-blend-multiply與 75% 不透明度印在紙上,旋轉 −12°,允許超出郵票邊緣。
可及性
- 外框是純裝飾容器,不設
role;內容的語意由你提供(圖片請給alt,CSS 繪製的插畫可加role="img"與aria-label) - 郵戳 SVG 設定
aria-hidden,不會被螢幕閱讀器朗讀;若日期等資訊重要,請另外以文字呈現 - 郵戳除了 hover,也會在外框內任何元素取得鍵盤焦點時(
focus-within)顯示 - 使用者系統開啟「減少動態效果」時,郵戳不做淡入,直接顯示或直接隱藏