Circular Text <mv-circular-text>
围绕图标、logo 或头像旋转的一圈文字,沿真正的 SVG 圆形绘制,因此字体保留字距,环形首尾均匀闭合;悬停或聚焦会让旋转平滑地加快、减慢、停止或反转。
工作原理
围绕图标、logo 或头像旋转的一圈文字,沿真正的 SVG 圆形绘制,因此字体保留字距,环形首尾均匀闭合;悬停或聚焦会让旋转平滑地加快、减慢、停止或反转。屏幕阅读器只会读一次文字,在减少动态效果模式下圆环保持静止。
| 分类 | 动画文字 |
|---|---|
| 类型 | Web Component(<mv-circular-text>) |
| 状态 | 稳定版 |
| Keywords | circular, spinning-text, badge, sticker, scroll-indicator, rotate, svg, accessible |
When to use
- A round badge or sticker needs text spinning around a logo, avatar or icon
- A hero corner needs a looping indicator such as 'scroll down' or 'available for work'
- A spinning link badge should pause while it is hovered or focused so it can be read
Avoid when
- The text is long or must be read quickly; ring text is hard to scan beyond a few words
- Several words should replace each other inline inside a sentence → use Word Rotate instead
安装
node scripts/add.mjs circular-text --out ./src/marvelous使用 Marvelous UI MCP 服务器的 AI 智能体:install_components({ slugs: ["circular-text"], target_dir: "<absolute path>/src/marvelous", framework: "react" })。
复制的文件(含依赖):tokens/tokens.css, core/base.css, core/dom.js, core/element.js, core/motion.js, core/observe.js, components/circular-text/circular-text.js, components/circular-text/circular-text.css。
用法
标准标记,可在此基础上通过属性、data-* 和 CSS 变量进行定制:
<div style="display:flex;flex-wrap:wrap;gap:2.5rem;align-items:center;justify-content:center">
<a href="#circular-text" aria-label="Scroll to explore" style="color:inherit;text-decoration:none;border-radius:50%">
<mv-circular-text text="Scroll to explore • " hover="pause" duration="16000" style="font:600 .85rem/1 var(--mv-font-mono);text-transform:uppercase;letter-spacing:.08em">
<span data-center style="display:grid;place-items:center;width:3rem;height:3rem;border-radius:50%;background:var(--mv-fg);color:var(--mv-bg)">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 5v14M6 13l6 6 6-6"/></svg>
</span>
</mv-circular-text>
</a>
<mv-circular-text text="New • 2026 Edition • " repeat="2" hover="reverse" duration="12000" style="font:700 .95rem/1 var(--mv-font-display);text-transform:uppercase;letter-spacing:.12em;color:var(--mv-fg-on-accent);background:radial-gradient(circle at 30% 25%,color-mix(in oklch,var(--mv-accent),white 18%),var(--mv-accent) 60%);box-shadow:var(--mv-shadow-lg), inset 0 0 0 1px color-mix(in oklch, white 20%, transparent)">
<svg data-center width="34" height="34" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2.5l2.6 6.1 6.6.6-5 4.4 1.5 6.5L12 16.7l-5.7 3.4 1.5-6.5-5-4.4 6.6-.6z"/></svg>
</mv-circular-text>
<mv-circular-text text="Available for new projects • " hover="slow-down" direction="ccw" duration="22000" style="font:600 .8rem/1 var(--mv-font-sans);letter-spacing:.16em;text-transform:uppercase;color:var(--mv-fg-muted)">
<span data-center aria-hidden="true" style="display:grid;place-items:center;width:3.6rem;height:3.6rem;border-radius:50%;background:var(--mv-bg-muted);border:1px solid var(--mv-border);font:700 1.1rem/1 var(--mv-font-display);color:var(--mv-fg);position:relative">
AK
<span style="position:absolute;right:.1rem;bottom:.15rem;width:.7rem;height:.7rem;border-radius:50%;background:var(--mv-success);box-shadow:0 0 0 2px var(--mv-bg)"></span>
</span>
</mv-circular-text>
</div>API
Attributes
| Name | 类型 | Default | Description |
|---|---|---|---|
text | string | Ring text (otherwise the child text). A trailing separator (“ • ”) makes a clean loop; a space is added when there is none. | |
label | string | Replaces the screen reader text. By default it is the ring text, read once, with separators turned into commas. | |
repeat | number | 1 | Repeats the text around the ring (up to 12 times); screen readers still hear it once. |
duration | number (ms) | 20000 | Duration of one full turn. |
direction | cw | ccw | cw | Rotation direction. |
hover | speed-up | slow-down | pause | reverse | none | speed-up | Reaction to mouse hover and to keyboard focus, on the ring or on a wrapping link or button; the speed eases on a spring. Taps do not count as hover. |
paused | boolean | Stops the rotation. It also stops by itself off-screen, in hidden tabs and under reduced motion. |
Content structure
| Name | Description |
|---|---|
[data-center] | Centered element (icon, avatar, logo). The ring grows so it never overlaps it. |
CSS variables
| Name | Default | Description |
|---|---|---|
--mv-circular-text-radius | (auto, from the measured text) | Forced ring radius (to the middle of the letters); the spacing stretches or tightens to fill it. |
--mv-circular-text-spread | 1.05 | Spacing factor when the radius is automatic (1 = the font's natural spacing, 1.2 = 20% looser). |
--mv-circular-text-advance | 0.62em | Average width per character, used only while the text cannot be measured yet (hidden or not rendered). |
Accessibility
The ring is an aria-hidden SVG; a visually hidden copy gives screen readers the text once as a normal string, without repeats, with bullet separators read as commas (or the label attribute). Hover with a mouse or pen and keyboard focus (inside the badge or on a wrapping link or button) apply the hover reaction, so hover="pause" holds the text still to be read. The rotation also stops off-screen, in hidden tabs and under reduced motion, where the ring stays static and readable. The letters use currentColor, so forced colors apply. When the badge sits inside a link, give the link an explicit aria-label.