组件
Components 组件总览
44 个 L1 组件按分类一页浏览;节内演示与单页文档一致,点击「单页 →」进入一页一题。
基础Basic
按钮与链接式按钮;扁平直角,多风格、多尺寸、禁用态;:focus-visible 键盘焦点环。
变体
实心、描边、幽灵、危险及语义色(success / warning / info / secondary)。
<div class="pvs-cluster pvs-flex-wrap">
<button type="button" class="pvs-btn pvs-btn--primary">Primary</button>
<button type="button" class="pvs-btn pvs-btn--outline">Outline</button>
<button type="button" class="pvs-btn pvs-btn--ghost">Ghost</button>
<button type="button" class="pvs-btn pvs-btn--secondary">Secondary</button>
<button type="button" class="pvs-btn pvs-btn--success">Success</button>
<button type="button" class="pvs-btn pvs-btn--warning">Warning</button>
<button type="button" class="pvs-btn pvs-btn--info">Info</button>
<button type="button" class="pvs-btn pvs-btn--danger">Danger</button>
</div>尺寸
<div class="pvs-cluster pvs-items-center">
<button type="button" class="pvs-btn pvs-btn--primary pvs-btn--sm">Small</button>
<button type="button" class="pvs-btn pvs-btn--primary">Default</button>
<button type="button" class="pvs-btn pvs-btn--primary pvs-btn--lg">Large</button>
</div>禁用态
原生 disabled 或类 pvs-btn--disabled(用于 <a>)。
<div class="pvs-cluster">
<button type="button" class="pvs-btn pvs-btn--primary" disabled>Disabled</button>
<a class="pvs-btn pvs-btn--outline pvs-btn--disabled" href="#" role="button" aria-disabled="true">链接禁用</a>
</div>链接样式
a.pvs-btn 呈现为按钮外观的链接。
Button group
pvs-btn-group 合并相邻按钮边框;--vertical 竖排。
<div class="pvs-cluster pvs-flex-wrap pvs-gap-4">
<div class="pvs-btn-group" role="group" aria-label="对齐">
<button type="button" class="pvs-btn pvs-btn--outline pvs-btn--sm">左</button>
<button type="button" class="pvs-btn pvs-btn--outline pvs-btn--sm is-active">中</button>
<button type="button" class="pvs-btn pvs-btn--outline pvs-btn--sm">右</button>
</div>
<div class="pvs-btn-group pvs-btn-group--vertical" role="group" aria-label="操作">
<button type="button" class="pvs-btn pvs-btn--ghost pvs-btn--sm">上</button>
<button type="button" class="pvs-btn pvs-btn--ghost pvs-btn--sm">下</button>
</div>
</div>Outline semantic
pvs-btn--outline-success 等描边语义色,hover 铺 muted 底。
<div class="pvs-cluster pvs-flex-wrap">
<button type="button" class="pvs-btn pvs-btn--outline-success pvs-btn--sm">Success</button>
<button type="button" class="pvs-btn pvs-btn--outline-warning pvs-btn--sm">Warning</button>
<button type="button" class="pvs-btn pvs-btn--outline-danger pvs-btn--sm">Danger</button>
<button type="button" class="pvs-btn pvs-btn--outline-info pvs-btn--sm">Info</button>
</div>Toolbar
pvs-btn-toolbar 多组按钮横向工具栏。
<div class="pvs-btn-toolbar">
<div class="pvs-btn-group" role="group">
<button type="button" class="pvs-btn pvs-btn--outline pvs-btn--sm">粗体</button>
<button type="button" class="pvs-btn pvs-btn--outline pvs-btn--sm">斜体</button>
</div>
<div class="pvs-btn-group" role="group">
<button type="button" class="pvs-btn pvs-btn--ghost pvs-btn--sm">左</button>
<button type="button" class="pvs-btn pvs-btn--ghost pvs-btn--sm">右</button>
</div>
<button type="button" class="pvs-btn pvs-btn--primary pvs-btn--sm">保存</button>
</div>类名速查
| 类名 | 说明 |
|---|---|
pvs-btn | 根类 |
pvs-btn--primary / --outline / --ghost / --danger | 风格 |
pvs-btn--secondary / --success / --warning / --info | 语义色实心 |
pvs-btn--outline-success / -warning / -danger / -info | 描边语义色 |
pvs-btn--sm / --lg | 尺寸 |
pvs-btn-group / --vertical | 按钮组 |
pvs-btn-toolbar | 工具栏容器 |
disabled / pvs-btn--disabled | 禁用 |
:focus-visible | 键盘焦点环 |
文本链接样式:默认、弱化、无下划线、禁用;:focus-visible 轮廓环。
变体
<p class="pvs-m-0">
<a class="pvs-link" href="#">默认链接</a> · <a class="pvs-link pvs-link--muted" href="#">弱化</a> · <a class="pvs-link pvs-link--no-underline" href="#">无下划线</a> · <a class="pvs-link pvs-link--disabled" href="#" tabindex="-1">禁用</a>
</p>场景示例
段落、面包屑、列表中的链接。
<p class="pvs-m-0 pvs-text-sm">阅读 <a class="pvs-link" href="#">入门指南</a> 或查看 <a class="pvs-link pvs-link--muted" href="#">变更记录</a>。</p>
<ul class="pvs-breadcrumb pvs-mt-3">
<li class="pvs-breadcrumb__item">
<a class="pvs-breadcrumb__link pvs-link" href="#">文档</a>
</li>
<li class="pvs-breadcrumb__item pvs-breadcrumb__item--active">链接</li>
</ul>类名速查
| 类名 | 说明 |
|---|---|
pvs-link | 主色 + 悬停下划线 |
pvs-link--muted | 灰色弱化 |
pvs-link--no-underline | 默认无下划线 |
pvs-link--disabled | 禁用态 |
标题层级 h1–h6;可用语义标签或 pvs-heading-* 类。
级别
一级 pvs-h1
二级 pvs-h2
三级 pvs-h3
四级
五级
六级
<h1 class="pvs-h1">一级 pvs-h1</h1>
<h2 class="pvs-h2">二级 pvs-h2</h2>
<h3 class="pvs-h3">三级 pvs-h3</h3>
<h4 class="pvs-h4">四级</h4>
<h5 class="pvs-h5">五级</h5>
<h6 class="pvs-h6">六级</h6>次要与分隔
弱化标题
带底部分隔线
<h2 class="pvs-h3 pvs-heading--muted">弱化标题</h2>
<h2 class="pvs-h3 pvs-heading--divider">带底部分隔线</h2>类名速查
| 类名 | 说明 |
|---|---|
pvs-h1 … pvs-h6 | 标题尺度 |
pvs-heading + pvs-heading-1/2/3 | 非语义标签用 |
pvs-heading--muted | 次要色 |
pvs-heading--divider | 底部分隔线 |
关闭按钮;Alert、Modal、Toast、灯箱等共用;:focus-visible 键盘焦点环。
尺寸
<div class="pvs-cluster pvs-items-center">
<button type="button" class="pvs-close" aria-label="关闭">×</button>
<button type="button" class="pvs-close pvs-close--sm" aria-label="关闭">×</button>
</div>用于提示头
通知
与 Alert 组合。
<div class="pvs-alert">
<div class="pvs-alert__header">
<p class="pvs-alert__title">通知</p>
<button type="button" class="pvs-close pvs-close--sm" aria-label="关闭">×</button>
</div>
<p class="pvs-alert__body pvs-m-0">与 Alert 组合。</p>
</div>类名速查
| 类名 | 说明 |
|---|---|
pvs-close | 默认关闭钮 |
pvs-close--sm | 小号(Toast / Alert) |
水平 / 垂直 / 带文字的分隔线。
横排布局
上一段内容
下一段内容
<p class="pvs-m-0">上一段内容</p>
<hr class="pvs-divider" />
<p class="pvs-m-0">下一段内容</p>带文字
<div class="pvs-divider pvs-divider--text">或</div>垂直
行内工具条里用竖线分隔。
<div class="pvs-cluster">
<span>编辑</span>
<span class="pvs-divider pvs-divider--vertical" role="separator">
</span>
<span>删除</span>
</div>类名速查
| 类名 | 说明 |
|---|---|
pvs-divider | 水平 hr 或 div |
pvs-divider--text | 中间嵌入文字 |
pvs-divider--vertical | 行内竖线 |
行内状态标签,可贴在标题、按钮或列表项旁。
变体
默认 New · 主色 Beta · 弱化 草稿
<p class="pvs-m-0">默认 <span class="pvs-badge">New</span> · 主色 <span class="pvs-badge pvs-badge--primary">Beta</span> · 弱化 <span class="pvs-badge pvs-badge--muted">草稿</span>
</p>语义色
成功 / 警告 / 错误 / 信息浅底标签。
成功 警告 错误 信息
<p class="pvs-m-0">
<span class="pvs-badge pvs-badge--success">成功</span>
<span class="pvs-badge pvs-badge--warning">警告</span>
<span class="pvs-badge pvs-badge--danger">错误</span>
<span class="pvs-badge pvs-badge--info">信息</span>
</p>场景示例
与标题、按钮组合使用。
文档中心 12
<h3 class="pvs-h4 pvs-m-0">文档中心 <span class="pvs-badge pvs-badge--primary">12</span>
</h3>
<p class="pvs-mt-4 pvs-m-0">
<button type="button" class="pvs-btn pvs-btn--outline pvs-btn--sm">消息 <span class="pvs-badge pvs-badge--primary">3</span>
</button>
</p>Count badge
pvs-badge--count 数字角标;pvs-badge--dot 仅圆点提醒。
99+
<p class="pvs-m-0 pvs-cluster">
<button type="button" class="pvs-btn pvs-btn--outline pvs-btn--sm">收件箱 <span class="pvs-badge pvs-badge--danger pvs-badge--count">8</span>
</button>
<span class="pvs-badge pvs-badge--primary pvs-badge--count">99+</span>
<span class="pvs-badge pvs-badge--danger pvs-badge--dot" aria-label="有新消息">
</span>
</p>类名速查
| 类名 | 说明 |
|---|---|
pvs-badge | 默认灰底标签 |
pvs-badge--primary | 主色浅底 |
pvs-badge--success / --warning / --danger / --info | 语义浅底 |
pvs-badge--muted | 弱化文字色 |
pvs-badge--count | 数字角标(胶囊) |
pvs-badge--dot | 圆点提醒 |
可关闭的关键词标签;用于文档标签、筛选 chips、后台关键词。
默认
<div class="pvs-tags">
<span class="pvs-tag">默认 <button type="button" class="pvs-tag__close" aria-label="移除">×</button>
</span>
<span class="pvs-tag pvs-tag--primary">主色 <button type="button" class="pvs-tag__close" aria-label="移除">×</button>
</span>
</div>Semantic
<div class="pvs-tags">
<span class="pvs-tag pvs-tag--success">成功</span>
<span class="pvs-tag pvs-tag--warning">警告</span>
<span class="pvs-tag pvs-tag--danger">错误</span>
</div>类名速查
| 类名 | 说明 |
|---|---|
pvs-tag | 单标签 |
pvs-tag__close | 关闭按钮 |
pvs-tags | 多标签容器 |
pvs-tag--primary / --success / --warning / --danger | 语义色 |
用户头像或 LOGO;图片、首字母或图标占位。
Image & text
<div class="pvs-cluster pvs-items-center">
<span class="pvs-avatar">
<img class="pvs-avatar__img" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='80' height='80'%3E%3Crect fill='%232563eb' width='100%25' height='100%25'/%3E%3C/svg%3E" alt="用户" />
</span>
<span class="pvs-avatar">
<span class="pvs-avatar__text">AK</span>
</span>
<span class="pvs-avatar pvs-avatar--square">
<span class="pvs-avatar__text">站</span>
</span>
</div>Sizes & group
<div class="pvs-cluster pvs-items-center">
<span class="pvs-avatar pvs-avatar--sm">
<span class="pvs-avatar__text">S</span>
</span>
<span class="pvs-avatar">
<span class="pvs-avatar__text">M</span>
</span>
<span class="pvs-avatar pvs-avatar--lg">
<span class="pvs-avatar__text">L</span>
</span>
</div>
<div class="pvs-avatar-group pvs-mt-4">
<span class="pvs-avatar">
<span class="pvs-avatar__text">A</span>
</span>
<span class="pvs-avatar">
<span class="pvs-avatar__text">B</span>
</span>
<span class="pvs-avatar">
<span class="pvs-avatar__text">C</span>
</span>
</div>类名速查
| 类名 | 说明 |
|---|---|
pvs-avatar | 根容器 |
pvs-avatar__img / __text | 图片 / 首字母 |
pvs-avatar--sm / --lg / --xl | 尺寸 |
pvs-avatar--square | 方角 |
pvs-avatar-group | 头像叠放组 |
内容Content
内容容器:头图、标题、正文、页脚;支持横排与卡片网格。
默认
卡片标题
扁平卡片正文,适合功能简介或列表项摘要。
<div class="pvs-card" style="max-width:18rem">
<div class="pvs-card__body">
<h3 class="pvs-card__title">卡片标题</h3>
<p class="pvs-card__text">扁平卡片正文,适合功能简介或列表项摘要。</p>
</div>
</div>页眉与页脚
含全部组件与文档站。
<div class="pvs-card" style="max-width:18rem">
<div class="pvs-card__header">套餐 Pro</div>
<div class="pvs-card__body">
<p class="pvs-card__text pvs-m-0">含全部组件与文档站。</p>
</div>
<div class="pvs-card__footer">
<button type="button" class="pvs-btn pvs-btn--primary pvs-btn--sm">购买</button>
<button type="button" class="pvs-btn pvs-btn--ghost pvs-btn--sm">详情</button>
</div>
</div>头图置顶
头图卡片
pvs-card__img 通栏置顶。
<div class="pvs-card" style="max-width:16rem">
<img class="pvs-card__img" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='320' height='160'%3E%3Crect fill='%23cbd5e1' width='100%25' height='100%25'/%3E%3C/svg%3E" alt="" />
<div class="pvs-card__body">
<h3 class="pvs-card__title">头图卡片</h3>
<p class="pvs-card__text">pvs-card__img 通栏置顶。</p>
</div>
</div>横排布局
pvs-card--horizontal:小屏竖排,≥576px 左图右文。
横排卡片
博客列表、商品摘要常用布局。
<div class="pvs-card pvs-card--horizontal" style="max-width:28rem">
<img class="pvs-card__img" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='160'%3E%3Crect fill='%2394a3b8' width='100%25' height='100%25'/%3E%3C/svg%3E" alt="" />
<div class="pvs-card__body">
<h3 class="pvs-card__title">横排卡片</h3>
<p class="pvs-card__text pvs-m-0">博客列表、商品摘要常用布局。</p>
</div>
</div>卡片网格
A
自动填充列
B
minmax(16rem)
C
三列流
<div class="pvs-card-grid" style="max-width:36rem">
<div class="pvs-card pvs-card--hover">
<div class="pvs-card__body">
<h3 class="pvs-card__title">A</h3>
<p class="pvs-card__text pvs-m-0">自动填充列</p>
</div>
</div>
<div class="pvs-card">
<div class="pvs-card__body">
<h3 class="pvs-card__title">B</h3>
<p class="pvs-card__text pvs-m-0">minmax(16rem)</p>
</div>
</div>
<div class="pvs-card">
<div class="pvs-card__body">
<h3 class="pvs-card__title">C</h3>
<p class="pvs-card__text pvs-m-0">三列流</p>
</div>
</div>
</div>悬停
pvs-card--hover 悬停时加阴影,常用于可点击卡片网格。
可点击卡片
鼠标悬停查看阴影变化。
<div class="pvs-card pvs-card--hover" style="max-width:18rem;cursor:pointer">
<div class="pvs-card__body">
<h3 class="pvs-card__title">可点击卡片</h3>
<p class="pvs-card__text">鼠标悬停查看阴影变化。</p>
</div>
</div>结构
div.pvs-card → 可选 __img / __header / __body / __footer
类名速查
| 类名 | 说明 |
|---|---|
pvs-card | 根容器 |
pvs-card__img | 头图 |
pvs-card__header / __footer | 顶栏 / 底栏 |
pvs-card__body | 内边距区 |
pvs-card__title / __text | 标题 / 正文 |
pvs-card--horizontal | 横排(左图右文) |
pvs-card-grid | 响应式多卡网格壳 |
pvs-card--hover | 悬停阴影 |
无序/有序、数字、色块条目、行内与分隔线变体。
默认
- 项目一
- 项目二
- 项目三
<ul class="pvs-list">
<li>项目一</li>
<li>项目二</li>
<li>项目三</li>
</ul>有序与数字
- 第一步
- 第二步
- 第三步
- 附录 A
- 附录 B
<ol class="pvs-list pvs-list--ordered">
<li>第一步</li>
<li>第二步</li>
<li>第三步</li>
</ol>
<ol class="pvs-list pvs-list--roman pvs-mt-4" start="4">
<li>附录 A</li>
<li>附录 B</li>
</ol>无样式与行内
- 无符号 A
- 无符号 B
- 行内甲
- 行内乙
<ul class="pvs-list pvs-list--unstyled">
<li>无符号 A</li>
<li>无符号 B</li>
</ul>
<ul class="pvs-list pvs-list--inline pvs-mt-4">
<li>行内甲</li>
<li>行内乙</li>
</ul>色块与符号
色块左边线、语义色、彩色项目符号。
- 主色条 · 当前
- 成功态
- 警告态
- 危险态
- 主色圆点
- 第二项
- 斑马纹 A
- 斑马纹 B
- 斑马纹 C
<ul class="pvs-list pvs-list--tile" style="max-width:14rem">
<li class="pvs-list__item--primary">主色条 · 当前</li>
<li class="pvs-list__item--success">成功态</li>
<li class="pvs-list__item--warning">警告态</li>
<li class="pvs-list__item--danger">危险态</li>
</ul>
<ul class="pvs-list pvs-list--marker-primary pvs-mt-4">
<li>主色圆点</li>
<li>第二项</li>
</ul>
<ul class="pvs-list pvs-list--striped pvs-mt-4" style="max-width:14rem">
<li>斑马纹 A</li>
<li>斑马纹 B</li>
<li>斑马纹 C</li>
</ul>分隔与状态
- 当前项
- 普通项
- 弱化项
<ul class="pvs-list pvs-list--divider" style="max-width:12rem">
<li class="pvs-list__item--active">当前项</li>
<li>普通项</li>
<li class="pvs-list__item--muted">弱化项</li>
</ul>List group
pvs-list-group 可点击条目组;链接/按钮 :focus-visible 焦点环。
<ul class="pvs-list-group" style="max-width:16rem">
<li>
<a class="pvs-list-group__item pvs-list-group__item--active" href="#">当前套餐</a>
</li>
<li>
<a class="pvs-list-group__item" href="#">专业版</a>
</li>
<li>
<span class="pvs-list-group__item pvs-list-group__item--disabled">企业版(即将)</span>
</li>
</ul>类名速查
| 类名 | 说明 |
|---|---|
pvs-list | 默认无序列表 |
pvs-list--ordered / --roman / --alpha | 有序 / 罗马 / 字母 |
pvs-list--unstyled | 无项目符号 |
pvs-list--inline | 行内排列 |
pvs-list--tile + __item--* | 色块左边线条目 |
pvs-list--marker-primary | 彩色 ::marker |
pvs-list--striped | 斑马纹行 |
pvs-list--divider | 项间分隔线 |
pvs-list__item--active / --muted | 当前 / 弱化 |
pvs-list-group / __item | 可点击条目组 |
pvs-list-group__item--active / --disabled | 选中 / 禁用 |
响应式图片、缩略图、object-fit 与 figure 说明。
响应式
<img class="pvs-img pvs-img--fluid pvs-border" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='320' height='120'%3E%3Crect fill='%23e2e8f0' width='100%25' height='100%25'/%3E%3C/svg%3E" alt="响应式示例" style="max-width:16rem" />缩略图
<div class="pvs-cluster pvs-items-center">
<img class="pvs-img pvs-img--thumb pvs-img--rounded pvs-img--border" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='72' height='72'%3E%3Crect fill='%2394a3b8' width='100%25' height='100%25'/%3E%3C/svg%3E" alt="" />
<img class="pvs-img pvs-img--thumb-lg pvs-img--rounded-full pvs-img--border" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='112' height='112'%3E%3Crect fill='%232563eb' width='100%25' height='100%25'/%3E%3C/svg%3E" alt="" />
</div>图片填充
<div class="pvs-flex pvs-gap-4 pvs-flex-wrap">
<div class="pvs-aspect-video pvs-w-32 pvs-border pvs-overflow-hidden">
<img class="pvs-img pvs-img--cover pvs-w-full pvs-h-full" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='120'%3E%3Crect fill='%23cbd5e1' width='100%25' height='100%25'/%3E%3C/svg%3E" alt="cover" />
</div>
<div class="pvs-aspect-video pvs-w-32 pvs-border pvs-overflow-hidden pvs-bg-surface-muted">
<img class="pvs-img pvs-img--contain pvs-w-full pvs-h-full" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='120'%3E%3Crect fill='%232563eb' width='60%25' height='60%25' x='20%25' y='20%25'/%3E%3C/svg%3E" alt="contain" />
</div>
</div>图文
<figure class="pvs-figure" style="max-width:16rem">
<img class="pvs-img pvs-img--rounded pvs-img--border" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='320' height='180'%3E%3Crect fill='%23e2e8f0' width='100%25' height='100%25'/%3E%3C/svg%3E" alt="" />
<figcaption class="pvs-figure__caption">图 1:封面示意</figcaption>
</figure>类名速查
| 类名 | 说明 |
|---|---|
pvs-img / pvs-img--fluid | 响应式 max-width:100% |
pvs-img--thumb / --thumb-lg | 方形缩略图 |
pvs-img--cover / --contain | object-fit |
pvs-img--rounded / --rounded-full | 圆角 / 圆形 |
pvs-img--border | 边框 |
pvs-figure + __caption | 带说明的图片 |
行内 pvs-code 与代码块 pvs-code-block;pvs-tok-* 轻量 token 色(文档站手工或生成)。
Inline
安装:npm install pivcss,或 CDN 引入 pivcss.css。
<p class="pvs-m-0">安装:<code class="pvs-code">npm install pivcss</code>,或 CDN 引入 <code class="pvs-code">pivcss.css</code>。</p>Code block
<link rel="stylesheet" href="/assets/pivcss.css" /><script src="/assets/pivcss.min.js" defer></script><pre class="pvs-code-block">
<code><link rel="stylesheet" href="/assets/pivcss.css" /><script src="/assets/pivcss.min.js" defer></script></code>
</pre>Syntax tokens
手工 span.pvs-tok-* 或文档构建时注入;无 Prism 依赖。
function hello(name) { return 'Hi ' + name; }<pre class="pvs-code-block pvs-code-block--light">
<code>
<span class="pvs-tok-kw">function</span>
<span class="pvs-tok-fn">hello</span>(<span class="pvs-tok-str">name</span>) { <span class="pvs-tok-kw">return</span>
<span class="pvs-tok-str">'Hi '</span> + name; }</code>
</pre>类名速查
| 类名 | 说明 |
|---|---|
pvs-code | 行内代码 |
pvs-code-block / pvs-pre | 块级代码 |
pvs-code-block--light | 浅色底 |
pvs-tok-kw / -str / -cmt / -fn | token 色 |
折叠面板;基于原生 <details>;pvs-accordion__title(summary):focus-visible 焦点环。
默认
多个 details.pvs-accordion 叠放;open 属性控制默认展开。
第一节
第二节
<details class="pvs-accordion" open>
<summary class="pvs-accordion__title">第一节</summary>
<div class="pvs-accordion__body">第一节正文,可放任意块级内容。</div>
</details>
<details class="pvs-accordion">
<summary class="pvs-accordion__title">第二节</summary>
<div class="pvs-accordion__body">第二节默认收起。</div>
</details>扁平
pvs-accordion--flush 去掉左右边框,适合嵌在卡片或列表里。
Flush 样式
<div class="pvs-border pvs-p-4" style="max-width:20rem">
<details class="pvs-accordion pvs-accordion--flush" open>
<summary class="pvs-accordion__title">Flush 样式</summary>
<div class="pvs-accordion__body">无左右边框,与容器对齐。</div>
</details>
</div>Single panel
仅一个 details 时与 FAQ 区块相同;无需额外 JS。
常见问题
PivCSS 零构建,引入 CSS 即可。
<details class="pvs-accordion" open>
<summary class="pvs-accordion__title">常见问题</summary>
<div class="pvs-accordion__body">
<p class="pvs-m-0">PivCSS 零构建,引入 CSS 即可。</p>
</div>
</details>结构
details.pvs-accordion → summary.pvs-accordion__title + div.pvs-accordion__body
类名速查
| 类名 | 说明 |
|---|---|
pvs-accordion | 根容器 |
pvs-accordion__title | 可点击标题(summary) |
pvs-accordion__body | 折叠内容区 |
pvs-accordion--flush | 无左右边框 |
导航Navigation
Breadcrumb面包屑
单页 →路径导航,标明当前页在站点层级中的位置;链接 :focus-visible 焦点环。
默认
<ul class="pvs-breadcrumb">
<li class="pvs-breadcrumb__item">
<a class="pvs-breadcrumb__link" href="#">首页</a>
</li>
<li class="pvs-breadcrumb__item">
<a class="pvs-breadcrumb__link" href="#">文档</a>
</li>
<li class="pvs-breadcrumb__item pvs-breadcrumb__item--active">Alert</li>
</ul>箭头分隔
pvs-breadcrumb--arrow 使用 › 分隔符。
<ul class="pvs-breadcrumb pvs-breadcrumb--arrow">
<li class="pvs-breadcrumb__item">
<a class="pvs-breadcrumb__link" href="#">产品</a>
</li>
<li class="pvs-breadcrumb__item">
<a class="pvs-breadcrumb__link" href="#">定价</a>
</li>
<li class="pvs-breadcrumb__item pvs-breadcrumb__item--active">企业版</li>
</ul>类名速查
| 类名 | 说明 |
|---|---|
pvs-breadcrumb | ul 根 |
pvs-breadcrumb__item | li 项 |
pvs-breadcrumb__link | 可点击链接 |
pvs-breadcrumb__item--active | 当前页(无链接) |
pvs-breadcrumb--arrow | › 分隔符样式 |
标签页切换;data-pvs-tabs 由 pivcss.min.js 驱动;Tab 按钮 :focus-visible 焦点环。
data-pvs-tab 按钮,仅与之 data-pvs-panel 值相同且带 is-active 的面板可见,其余面板隐藏(display:none)。初始页须在按钮与一个面板上同时加 is-active。默认标签页
面板 A 内容
面板 B 内容
<div data-pvs-tabs>
<ul class="pvs-tabs__nav">
<li class="pvs-tabs__tab">
<button type="button" class="pvs-tabs__btn is-active" data-pvs-tab="ta">概述</button>
</li>
<li class="pvs-tabs__tab">
<button type="button" class="pvs-tabs__btn" data-pvs-tab="tb">API</button>
</li>
</ul>
<div class="pvs-tabs__panel is-active" data-pvs-panel="ta">
<p class="pvs-m-0">面板 A 内容</p>
</div>
<div class="pvs-tabs__panel" data-pvs-panel="tb">
<p class="pvs-m-0">面板 B 内容</p>
</div>
</div>胶囊样式
<div data-pvs-tabs class="pvs-tabs--pill">
<ul class="pvs-tabs__nav">
<li class="pvs-tabs__tab">
<button type="button" class="pvs-tabs__btn is-active" data-pvs-tab="p1">One</button>
</li>
<li class="pvs-tabs__tab">
<button type="button" class="pvs-tabs__btn" data-pvs-tab="p2">Two</button>
</li>
</ul>
<div class="pvs-tabs__panel is-active" data-pvs-panel="p1">药丸风格面板 1</div>
<div class="pvs-tabs__panel" data-pvs-panel="p2">面板 2</div>
</div>左侧标签
pvs-tabs--start 标签在左、内容在右。
左侧 Tab · 面板 1
面板 2
<div data-pvs-tabs class="pvs-tabs--start" style="max-width:24rem">
<ul class="pvs-tabs__nav">
<li class="pvs-tabs__tab">
<button type="button" class="pvs-tabs__btn is-active" data-pvs-tab="ls1">概览</button>
</li>
<li class="pvs-tabs__tab">
<button type="button" class="pvs-tabs__btn" data-pvs-tab="ls2">设置</button>
</li>
</ul>
<div class="pvs-tabs__panel is-active" data-pvs-panel="ls1">
<p class="pvs-m-0">左侧 Tab · 面板 1</p>
</div>
<div class="pvs-tabs__panel" data-pvs-panel="ls2">
<p class="pvs-m-0">面板 2</p>
</div>
</div>右侧标签
pvs-tabs--end 标签在右。
右侧 Tab · 内容 A
内容 B
<div data-pvs-tabs class="pvs-tabs--end" style="max-width:24rem">
<ul class="pvs-tabs__nav">
<li class="pvs-tabs__tab">
<button type="button" class="pvs-tabs__btn is-active" data-pvs-tab="re1">A</button>
</li>
<li class="pvs-tabs__tab">
<button type="button" class="pvs-tabs__btn" data-pvs-tab="re2">B</button>
</li>
</ul>
<div class="pvs-tabs__panel is-active" data-pvs-panel="re1">
<p class="pvs-m-0">右侧 Tab · 内容 A</p>
</div>
<div class="pvs-tabs__panel" data-pvs-panel="re2">
<p class="pvs-m-0">内容 B</p>
</div>
</div>Vertical alias
pvs-tabs--vertical 与 --start 等价,文档与迁移更直观。
竖向 Tab 面板
面板 2
<div data-pvs-tabs class="pvs-tabs--vertical" style="max-width:24rem">
<ul class="pvs-tabs__nav">
<li class="pvs-tabs__tab">
<button type="button" class="pvs-tabs__btn is-active" data-pvs-tab="v1">账户</button>
</li>
<li class="pvs-tabs__tab">
<button type="button" class="pvs-tabs__btn" data-pvs-tab="v2">安全</button>
</li>
</ul>
<div class="pvs-tabs__panel is-active" data-pvs-panel="v1">
<p class="pvs-m-0">竖向 Tab 面板</p>
</div>
<div class="pvs-tabs__panel" data-pvs-panel="v2">
<p class="pvs-m-0">面板 2</p>
</div>
</div>Tab keyboard
水平 Tab:←/→/Home/End;垂直 pvs-tabs--start/end 用 ↑/↓。JS 自动补 role 与 aria-selected。
方向键切换
面板 2
面板 3
<div data-pvs-tabs>
<ul class="pvs-tabs__nav">
<li class="pvs-tabs__tab">
<button type="button" class="pvs-tabs__btn is-active" data-pvs-tab="kb1">Tab 1</button>
</li>
<li class="pvs-tabs__tab">
<button type="button" class="pvs-tabs__btn" data-pvs-tab="kb2">Tab 2</button>
</li>
<li class="pvs-tabs__tab">
<button type="button" class="pvs-tabs__btn" data-pvs-tab="kb3">Tab 3</button>
</li>
</ul>
<div class="pvs-tabs__panel is-active" data-pvs-panel="kb1">
<p class="pvs-m-0">方向键切换</p>
</div>
<div class="pvs-tabs__panel" data-pvs-panel="kb2">
<p class="pvs-m-0">面板 2</p>
</div>
<div class="pvs-tabs__panel" data-pvs-panel="kb3">
<p class="pvs-m-0">面板 3</p>
</div>
</div>结构
div[data-pvs-tabs] → ul.pvs-tabs__nav + 多个 div.pvs-tabs__panel;tab 与 panel 用相同 data-pvs-tab / data-pvs-panel 值配对;仅一个 panel 带 is-active 时显示
数据属性
| 类名 | 说明 |
|---|---|
data-pvs-tabs | 根容器,JS 初始化 |
data-pvs-tab | 按钮上的 tab id |
data-pvs-panel | 面板 id,与 tab 对应 |
Tab 键盘 | ←→/↑↓/Home/End · roving tabindex |
.is-active | 当前 tab 按钮与 panel |
类名速查
| 类名 | 说明 |
|---|---|
pvs-tabs__nav / __tab / __btn | 标签栏 |
pvs-tabs__panel | 内容面板 |
pvs-tabs--pill | 药丸风格 |
pvs-tabs--start | 左侧竖向标签 |
pvs-tabs--vertical | 竖向别名(同 start) |
pvs-tabs--end | 右侧竖向标签 |
分页导航:当前页、禁用上一页/下一页;链接 :focus-visible 焦点环。
默认
<ul class="pvs-pagination">
<li class="pvs-pagination__item--disabled">
<span class="pvs-pagination__link">‹</span>
</li>
<li class="pvs-pagination__item--active">
<a class="pvs-pagination__link" href="#">1</a>
</li>
<li>
<a class="pvs-pagination__link" href="#">2</a>
</li>
<li>
<a class="pvs-pagination__link" href="#">3</a>
</li>
<li>
<a class="pvs-pagination__link" href="#">›</a>
</li>
</ul>链接修饰
也可直接在 a.pvs-pagination__link 上加 --active / --disabled。
<ul class="pvs-pagination">
<li>
<a class="pvs-pagination__link pvs-pagination__link--disabled" href="#">‹</a>
</li>
<li>
<a class="pvs-pagination__link pvs-pagination__link--active" href="#">1</a>
</li>
<li>
<a class="pvs-pagination__link" href="#">2</a>
</li>
</ul>尺寸
<div class="pvs-stack">
<ul class="pvs-pagination pvs-pagination--sm">
<li>
<a class="pvs-pagination__link pvs-pagination__link--active" href="#">1</a>
</li>
<li>
<a class="pvs-pagination__link" href="#">2</a>
</li>
</ul>
<ul class="pvs-pagination pvs-pagination--lg">
<li>
<a class="pvs-pagination__link pvs-pagination__link--active" href="#">1</a>
</li>
<li>
<a class="pvs-pagination__link" href="#">2</a>
</li>
</ul>
</div>类名速查
| 类名 | 说明 |
|---|---|
pvs-pagination | ul 根 |
pvs-pagination__link | 页码链接 |
pvs-pagination__item--active | li 当前页 |
pvs-pagination__item--disabled | li 禁用 |
pvs-pagination__link--active / --disabled | 链接级状态 |
pvs-pagination--sm / --lg | 紧凑 / 大号 |
吸顶工具条壳;也可直接用布局原语 pvs-sticky pvs-top-0。
吸顶条
<div class="pvs-sticky-bar pvs-sticky-bar--shadow">
<div class="pvs-container pvs-sticky-bar__inner">
<span class="pvs-text-sm pvs-font-semibold">文档</span>
<ul class="pvs-subnav pvs-subnav--pill" style="margin:0">
<li class="pvs-subnav__item pvs-subnav__item--active">
<a class="pvs-subnav__link" href="#">概述</a>
</li>
<li class="pvs-subnav__item">
<a class="pvs-subnav__link" href="#">API</a>
</li>
</ul>
</div>
</div>浅底
<div class="pvs-sticky-bar pvs-sticky-bar--muted">
<div class="pvs-container pvs-sticky-bar__inner">
<span class="pvs-text-sm">浅底吸顶条 pvs-sticky-bar--muted</span>
</div>
</div>布局原语
任意块级元素加 pvs-sticky pvs-top-0(见布局 · 定位)。
pvs-sticky pvs-top-0 — 滚动页面时吸顶<div class="pvs-sticky pvs-top-0 pvs-p-3 pvs-border pvs-bg-surface pvs-z-10">
<code>pvs-sticky pvs-top-0</code> — 滚动页面时吸顶</div>
<div style="height:8rem">
</div>类名速查
| 类名 | 说明 |
|---|---|
pvs-sticky-bar | 吸顶条壳 |
pvs-sticky-bar__inner | 容器内 flex |
pvs-sticky-bar--shadow / --muted | 阴影 / 浅底 |
pvs-sticky + pvs-top-0 | 布局原语吸顶 |
Back to top回到顶部
单页 →回到顶部浮动按钮;data-pvs-backtop 挂载 JS,滚动超过偏移后显示。
默认
右下角固定;data-pvs-backtop-offset="320" 为显示阈值(像素)。
文档预览强制 is-visible;实页滚动后由 JS 切换。
<button type="button" class="pvs-backtop is-visible" data-pvs-backtop aria-label="回到顶部">↑</button>
<p class="pvs-text-sm pvs-text-muted pvs-m-0">文档预览强制 <code>is-visible</code>;实页滚动后由 JS 切换。</p>Custom offset
长文档可提高阈值;配合 prefers-reduced-motion 平滑滚动。
data-pvs-backtop-offset="600" — 滚动 600px 后显示。
<div class="pvs-stack pvs-gap-2" style="max-width:18rem">
<button type="button" class="pvs-backtop is-visible" data-pvs-backtop data-pvs-backtop-offset="600" aria-label="回到顶部">↑</button>
<p class="pvs-text-sm pvs-text-muted pvs-m-0">
<code>data-pvs-backtop-offset="600"</code> — 滚动 600px 后显示。</p>
</div>类名速查
| 类名 | 说明 |
|---|---|
pvs-backtop | 浮动钮(需 data-pvs-backtop) |
is-visible | JS 滚动后添加 |
data-pvs-backtop-offset | 显示阈值(默认 320) |
表单Forms
L1 表单原子:input / select / textarea / checkbox / radio / switch / range / file 等;校验态与 input-group。数字步进、日期、颜色、上传见独立组件页。
Form overview
典型「账户设置」一屏组合:文本、下拉、多行、勾选、开关与提交钮。
<form class="pvs-stack pvs-gap-4" style="max-width:26rem" onsubmit="return false">
<div class="pvs-form-group">
<label class="pvs-label" for="fo-name">姓名</label>
<input class="pvs-input" id="fo-name" type="text" placeholder="张三" />
</div>
<div class="pvs-form-group">
<label class="pvs-label" for="fo-email">邮箱</label>
<input class="pvs-input" id="fo-email" type="email" placeholder="you@example.com" />
<p class="pvs-form-hint">用于登录与通知</p>
</div>
<div class="pvs-form-group">
<label class="pvs-label" for="fo-pass">密码</label>
<input class="pvs-input" id="fo-pass" type="password" placeholder="••••••" />
</div>
<div class="pvs-form-group">
<label class="pvs-label" for="fo-role">角色</label>
<select class="pvs-select" id="fo-role">
<option>编辑</option>
<option>管理员</option>
</select>
</div>
<div class="pvs-form-group">
<label class="pvs-label" for="fo-bio">简介</label>
<textarea class="pvs-textarea" id="fo-bio" rows="2" placeholder="一句话介绍">
</textarea>
</div>
<div class="pvs-form-check">
<input class="pvs-form-check__input" id="fo-agree" type="checkbox" />
<label class="pvs-label" for="fo-agree" style="margin:0">同意服务条款</label>
</div>
<label class="pvs-switch">
<input class="pvs-switch__input" type="checkbox" checked />
<span class="pvs-switch__track" aria-hidden="true">
</span>
<span class="pvs-text-sm">接收邮件通知</span>
</label>
<div class="pvs-cluster pvs-gap-2">
<button type="submit" class="pvs-btn pvs-btn--primary pvs-btn--sm">保存</button>
<button type="reset" class="pvs-btn pvs-btn--ghost pvs-btn--sm">重置</button>
</div>
</form>基础字段
用于接收通知。
<div class="pvs-form-group" style="max-width:20rem">
<label class="pvs-label" for="fd-email">邮箱</label>
<input class="pvs-input" id="fd-email" type="email" placeholder="you@example.com" />
<p class="pvs-form-hint">用于接收通知。</p>
</div>尺寸
--sm / 默认 / --lg 适用于 input、select、textarea。
<div class="pvs-stack" style="max-width:20rem">
<input class="pvs-input pvs-input--sm" placeholder="pvs-input--sm" />
<input class="pvs-input" placeholder="default" />
<input class="pvs-input pvs-input--lg" placeholder="pvs-input--lg" />
<select class="pvs-select pvs-select--sm">
<option>pvs-select--sm</option>
</select>
<select class="pvs-select pvs-select--lg">
<option>pvs-select--lg</option>
</select>
<textarea class="pvs-textarea" rows="2" placeholder="pvs-textarea">
</textarea>
</div>校验
pvs-input--invalid / --valid 右侧内联 SVG 图标(无图标字体依赖)+ 语义边框色。
至少 3 个字符
格式正确
<div class="pvs-form-group" style="max-width:20rem">
<label class="pvs-label" for="fd-bad">用户名</label>
<input class="pvs-input pvs-input--invalid" id="fd-bad" value="a" />
<p class="pvs-field-error">至少 3 个字符</p>
</div>
<div class="pvs-form-group pvs-mt-4" style="max-width:20rem">
<label class="pvs-label" for="fd-ok">域名</label>
<input class="pvs-input pvs-input--valid" id="fd-ok" value="pivark.com" />
<p class="pvs-field-success">格式正确</p>
</div>Input types
常见 HTML5 type 共用 pvs-input;日期/时间复杂面板见 Date picker。
<div class="pvs-stack pvs-gap-3" style="max-width:20rem">
<div class="pvs-form-group pvs-m-0">
<label class="pvs-label" for="ft-pass">password</label>
<input class="pvs-input" id="ft-pass" type="password" value="secret" />
</div>
<div class="pvs-form-group pvs-m-0">
<label class="pvs-label" for="ft-tel">tel</label>
<input class="pvs-input" id="ft-tel" type="tel" placeholder="13800000000" />
</div>
<div class="pvs-form-group pvs-m-0">
<label class="pvs-label" for="ft-url">url</label>
<input class="pvs-input" id="ft-url" type="url" placeholder="https://pivark.com" />
</div>
<div class="pvs-form-group pvs-m-0">
<label class="pvs-label" for="ft-num">number</label>
<input class="pvs-input" id="ft-num" type="number" min="0" max="99" value="3" />
</div>
<div class="pvs-form-group pvs-m-0">
<label class="pvs-label" for="ft-search">search</label>
<input class="pvs-input" id="ft-search" type="search" placeholder="站内搜索" />
</div>
<div class="pvs-form-group pvs-m-0">
<label class="pvs-label" for="ft-date">date</label>
<input class="pvs-input" id="ft-date" type="date" />
</div>
</div>Textarea & select validation
校验修饰符同样作用于 pvs-textarea / pvs-select。
至少 10 字
已选择有效区域
<div class="pvs-stack pvs-gap-4" style="max-width:20rem">
<div class="pvs-form-group pvs-m-0">
<label class="pvs-label" for="fv-ta">备注</label>
<textarea class="pvs-textarea pvs-textarea--invalid" id="fv-ta" rows="2">太短</textarea>
<p class="pvs-field-error">至少 10 字</p>
</div>
<div class="pvs-form-group pvs-m-0">
<label class="pvs-label" for="fv-sel">地区</label>
<select class="pvs-select pvs-select--valid" id="fv-sel">
<option selected>华东</option>
</select>
<p class="pvs-field-success">已选择有效区域</p>
</div>
</div>复选框
<div class="pvs-form-check">
<input class="pvs-form-check__input" id="fd-agree" type="checkbox" />
<label class="pvs-label" for="fd-agree" style="margin:0">同意服务条款</label>
</div>Checkbox group
多个 pvs-form-check 叠放;横向可用 pvs-cluster 包一层。
<fieldset class="pvs-stack pvs-gap-2" style="max-width:20rem;border:0;padding:0;margin:0">
<legend class="pvs-label">通知渠道</legend>
<div class="pvs-form-check">
<input class="pvs-form-check__input" id="fc-mail" type="checkbox" checked />
<label class="pvs-label" for="fc-mail" style="margin:0">邮件</label>
</div>
<div class="pvs-form-check">
<input class="pvs-form-check__input" id="fc-sms" type="checkbox" />
<label class="pvs-label" for="fc-sms" style="margin:0">短信</label>
</div>
<div class="pvs-form-check">
<input class="pvs-form-check__input" id="fc-push" type="checkbox" />
<label class="pvs-label" for="fc-push" style="margin:0">站内信</label>
</div>
</fieldset>多行与下拉
<div class="pvs-stack" style="max-width:20rem">
<textarea class="pvs-textarea" rows="2" placeholder="pvs-textarea">
</textarea>
<select class="pvs-select">
<option>pvs-select</option>
</select>
</div>行内表单
pvs-form-inline 横向排列表单项。
<form class="pvs-form-inline">
<div class="pvs-form-group">
<label class="pvs-label" for="fd-q">搜索</label>
<input class="pvs-input pvs-input--sm" id="fd-q" type="search" />
</div>
<button type="submit" class="pvs-btn pvs-btn--primary pvs-btn--sm">搜</button>
</form>单选
<div class="pvs-stack pvs-gap-2" style="max-width:20rem">
<div class="pvs-form-check pvs-form-check--radio">
<input class="pvs-form-check__input" id="fd-r1" name="fd-plan" type="radio" checked />
<label class="pvs-label" for="fd-r1" style="margin:0">免费版</label>
</div>
<div class="pvs-form-check pvs-form-check--radio">
<input class="pvs-form-check__input" id="fd-r2" name="fd-plan" type="radio" />
<label class="pvs-label" for="fd-r2" style="margin:0">专业版</label>
</div>
</div>开关
<label class="pvs-switch">
<input class="pvs-switch__input" type="checkbox" checked />
<span class="pvs-switch__track" aria-hidden="true">
</span>
<span class="pvs-text-sm">启用暗色模式</span>
</label>输入组
<div class="pvs-input-group" style="max-width:20rem">
<span class="pvs-input-group__addon">https://</span>
<input class="pvs-input" type="text" placeholder="域名" />
<span class="pvs-input-group__addon">.com</span>
</div>Input group + button
前后缀与 pvs-btn 同一行;按钮不参与圆角拼接时需自行控制顺序。
<div class="pvs-input-group" style="max-width:22rem">
<input class="pvs-input" type="search" placeholder="搜索文档" />
<button type="button" class="pvs-btn pvs-btn--primary pvs-btn--sm">搜</button>
</div>
<div class="pvs-input-group pvs-mt-3" style="max-width:22rem">
<span class="pvs-input-group__addon">¥</span>
<input class="pvs-input" type="number" placeholder="0.00" />
<button type="button" class="pvs-btn pvs-btn--outline pvs-btn--sm">应用</button>
</div>禁用态
禁用态适用于 input / select / textarea;开关与原生 checkbox 用 HTML disabled。
<div class="pvs-stack pvs-gap-3" style="max-width:20rem">
<input class="pvs-input" value="不可编辑" disabled />
<select class="pvs-select" disabled>
<option>禁用下拉</option>
</select>
<textarea class="pvs-textarea" rows="2" disabled>禁用多行</textarea>
<label class="pvs-switch">
<input class="pvs-switch__input" type="checkbox" disabled />
<span class="pvs-switch__track" aria-hidden="true">
</span>
<span class="pvs-text-sm">禁用开关</span>
</label>
</div>Readonly
只读可复制,不可改值。
<div class="pvs-form-group" style="max-width:20rem">
<label class="pvs-label" for="fr-id">站点 ID</label>
<input class="pvs-input" id="fr-id" type="text" value="pivark-demo-001" readonly />
<p class="pvs-form-hint">只读可复制,不可改值。</p>
</div>Floating label
pvs-form-floating:标签在输入获得焦点或已有内容时上浮;支持 input / textarea / select。
<div class="pvs-stack pvs-gap-4" style="max-width:20rem">
<div class="pvs-form-floating">
<input class="pvs-input" id="fd-float" type="email" placeholder="you@example.com" />
<label class="pvs-label" for="fd-float">邮箱</label>
</div>
<div class="pvs-form-floating">
<select class="pvs-select" id="fd-float-sel">
<option value="" hidden>
</option>
<option selected>华东</option>
<option>华北</option>
</select>
<label class="pvs-label" for="fd-float-sel">区域</label>
</div>
<div class="pvs-form-floating">
<textarea class="pvs-textarea" id="fd-float-ta" placeholder="备注" rows="1">
</textarea>
<label class="pvs-label" for="fd-float-ta">备注</label>
</div>
</div>Range
<div style="max-width:20rem">
<label class="pvs-label" for="fd-range">音量</label>
<input class="pvs-range" id="fd-range" type="range" min="0" max="100" value="40" />
</div>File input
<div class="pvs-form-group" style="max-width:20rem">
<label class="pvs-label" for="fd-file">附件</label>
<input class="pvs-form-file" id="fd-file" type="file" />
</div>结构
L1 Form 只管原生控件样式与布局原语;带 JS 契约的控件拆成独立页,避免单页混杂 data-pvs-*。
类名速查
| 类名 | 说明 |
|---|---|
pvs-form-group | 字段组 |
pvs-label | 标签 |
pvs-input / pvs-select / pvs-textarea | 控件(:focus-visible 焦点环) |
pvs-input--sm / --lg | input / select 尺寸 |
pvs-input--invalid / --valid | 校验边框 + 右侧 SVG 图标 |
pvs-textarea--invalid / pvs-select--valid | 多行与下拉校验 |
pvs-field-error / pvs-field-success | 校验文案 |
pvs-form-hint | 辅助说明 |
pvs-form-check + __input | 复选 / 单选行 |
pvs-form-check--radio | 单选圆点 |
pvs-switch / __track | 开关 |
pvs-input-group / __addon | 前后缀输入组 |
pvs-form-floating | 浮动标签(input/textarea/select) |
pvs-range | 滑块 |
pvs-form-file | 文件选择 |
pvs-form-inline | 横向表单 |
→ number-input / upload / datepicker / colorpicker | 进阶控件独立页 |
Number input数字输入
单页 →数字步进输入样式壳;± 按钮与数字框均用 :focus-visible 焦点环;步进行为由业务 JS 绑定。
默认
<div class="pvs-number-input">
<button type="button" class="pvs-number-input__btn" aria-label="减少">−</button>
<input class="pvs-number-input__field" type="number" value="1" min="0" max="99" aria-label="数量" />
<button type="button" class="pvs-number-input__btn" aria-label="增加">+</button>
</div>Small & block
pvs-number-input--sm 紧凑;--block 撑满容器宽。
<div class="pvs-cluster pvs-items-center">
<div class="pvs-number-input pvs-number-input--sm">
<button type="button" class="pvs-number-input__btn">−</button>
<input class="pvs-number-input__field" type="number" value="3" />
<button type="button" class="pvs-number-input__btn">+</button>
</div>
</div>
<div class="pvs-number-input pvs-number-input--block pvs-mt-4" style="max-width:14rem">
<button type="button" class="pvs-number-input__btn">−</button>
<input class="pvs-number-input__field" type="number" value="10" />
<button type="button" class="pvs-number-input__btn">+</button>
</div>类名速查
| 类名 | 说明 |
|---|---|
pvs-number-input | 根容器 |
pvs-number-input__btn / __field | 步进钮与数字框 |
pvs-number-input--sm / --block | 紧凑 / 块级 |
Color picker颜色选择
单页 →颜色选择;data-pvs-colorpicker 预设色板 + 原生 color input,触发 pvs-colorpicker:change。
默认
<div class="pvs-colorpicker" data-pvs-colorpicker data-pvs-colorpicker-value="#2563eb" style="max-width:12rem">
<button type="button" class="pvs-colorpicker__trigger">
<span class="pvs-colorpicker__swatch">
</span>
<span class="pvs-colorpicker__value">#2563eb</span>
</button>
<div class="pvs-colorpicker__panel">
<div class="pvs-colorpicker__grid">
</div>
<input class="pvs-colorpicker__native" type="color" />
</div>
</div>Preset grid
JS 根据主题色生成预设格;选中后更新 __value 与 __swatch。
<div class="pvs-colorpicker is-open" data-pvs-colorpicker style="max-width:14rem">
<button type="button" class="pvs-colorpicker__trigger">
<span class="pvs-colorpicker__swatch" style="background:#059669">
</span>
<span class="pvs-colorpicker__value">#059669</span>
</button>
<div class="pvs-colorpicker__panel">
<div class="pvs-colorpicker__grid pvs-cluster pvs-gap-1" style="flex-wrap:wrap">
<button type="button" class="pvs-colorpicker__option is-selected" style="background:#2563eb" aria-label="#2563eb">
</button>
<button type="button" class="pvs-colorpicker__option" style="background:#059669" aria-label="#059669">
</button>
<button type="button" class="pvs-colorpicker__option" style="background:#d97706" aria-label="#d97706">
</button>
</div>
<input class="pvs-colorpicker__native" type="color" value="#059669" />
</div>
</div>数据属性
| 类名 | 说明 |
|---|---|
data-pvs-colorpicker | 初始化色板 |
data-pvs-colorpicker-value | 默认色值 |
pvs-colorpicker:change | CustomEvent · detail.value |
类名速查
| 类名 | 说明 |
|---|---|
pvs-colorpicker | 根(需 data-pvs-colorpicker) |
pvs-colorpicker__trigger / __swatch | 触发器与色块 |
pvs-colorpicker__grid / __option | 预设色板 |
pvs-colorpicker__native | 原生 color input |
Date picker日期选择
单页 →日期选择器;data-pvs-datepicker 挂载 JS,点击输入框展开月历并写回 YYYY-MM-DD。
Interactive
需加载 pivcss.min.js;面板格子由 JS 渲染,Esc 或点外关闭。
<div class="pvs-datepicker" data-pvs-datepicker style="max-width:14rem">
<input class="pvs-input pvs-datepicker__input" type="text" readonly placeholder="选择日期" aria-label="选择日期" />
<div class="pvs-datepicker__panel">
<div class="pvs-datepicker__header">
<button type="button" class="pvs-datepicker__nav" data-pvs-datepicker-prev aria-label="上月">‹</button>
<span class="pvs-datepicker__title">
</span>
<button type="button" class="pvs-datepicker__nav" data-pvs-datepicker-next aria-label="下月">›</button>
</div>
<div class="pvs-datepicker__weekdays">
<span>一</span>
<span>二</span>
<span>三</span>
<span>四</span>
<span>五</span>
<span>六</span>
<span>日</span>
</div>
<div class="pvs-datepicker__grid">
</div>
</div>
</div>Panel markup
文档预览静态展开面板;实页由 JS 填充 __grid 与 __title。
<div class="pvs-datepicker is-open" data-pvs-datepicker style="max-width:16rem">
<input class="pvs-input pvs-datepicker__input" type="text" readonly value="2026-06-15" />
<div class="pvs-datepicker__panel">
<div class="pvs-datepicker__header">
<button type="button" class="pvs-datepicker__nav">‹</button>
<span class="pvs-datepicker__title">2026 年 6 月</span>
<button type="button" class="pvs-datepicker__nav">›</button>
</div>
<div class="pvs-datepicker__weekdays">
<span>一</span>
<span>二</span>
<span>三</span>
<span>四</span>
<span>五</span>
<span>六</span>
<span>日</span>
</div>
<div class="pvs-datepicker__grid pvs-cluster pvs-gap-1" style="flex-wrap:wrap">
<span class="pvs-datepicker__day is-muted">26</span>
<span class="pvs-datepicker__day is-selected">15</span>
<span class="pvs-datepicker__day is-today">15</span>
</div>
</div>
</div>数据属性
| 类名 | 说明 |
|---|---|
data-pvs-datepicker | 初始化月历;输出 YYYY-MM-DD |
类名速查
| 类名 | 说明 |
|---|---|
pvs-datepicker | 根容器(需 data-pvs-datepicker) |
pvs-datepicker__panel | 下拉面板 |
pvs-datepicker__grid / __day | 7 列日期格(JS 渲染) |
is-today / is-selected / is-muted | 今日 / 选中 / 非本月 |
pvs-datepicker--up | 面板向上展开 |
文件上传;本地列表用 data-pvs-upload;加 data-pvs-upload-auto + URL 走 XHR(主题/CMS 表单)。PivAdmin SPA 仍用 admin/src/api/pivark/system/upload.ts。
Dropzone
<div data-pvs-upload-wrap style="max-width:22rem">
<label class="pvs-upload" data-pvs-upload>
<span class="pvs-upload__icon" aria-hidden="true">⬆</span>
<p class="pvs-upload__title">点击或拖拽文件到此处</p>
<p class="pvs-upload__hint">选文件后下方列表自动追加</p>
<input class="pvs-upload__input" type="file" multiple />
</label>
<ul class="pvs-upload__filelist">
</ul>
</div>Progress row
进度条 DOM 仍由业务填充;JS 默认只追加文件名与大小。
- banner.jpg
<ul class="pvs-upload__filelist" style="max-width:22rem">
<li class="pvs-upload__file pvs-upload__file--uploading">
<span class="pvs-upload__file-name">banner.jpg</span>
<span class="pvs-upload__file-meta">上传中…</span>
<div class="pvs-upload__progress">
<span style="width:65%">
</span>
</div>
</li>
</ul>XHR auto upload
配置 data-pvs-upload-url(如 PivArk /upload/file)+ CSRF meta/属性;触发 pvs-upload:done。
文档站无后台会话时请求会失败,仅演示 DOM/进度条;生产页须带 CSRF 与登录 Cookie。
<div data-pvs-upload-wrap style="max-width:22rem">
<label class="pvs-upload" data-pvs-upload data-pvs-upload-auto data-pvs-upload-url="/upload/file" data-pvs-upload-scene="attachment">
<p class="pvs-upload__title">选文件即 POST(需后端 + CSRF)</p>
<input class="pvs-upload__input" type="file" />
</label>
<ul class="pvs-upload__filelist">
</ul>
</div>
<p class="pvs-text-sm pvs-text-muted pvs-mt-2 pvs-m-0">文档站无后台会话时请求会失败,仅演示 DOM/进度条;生产页须带 CSRF 与登录 Cookie。</p>数据属性
| 类名 | 说明 |
|---|---|
data-pvs-upload | 初始化拖拽 + 列表 |
data-pvs-upload-auto | 选文件后自动 XHR |
data-pvs-upload-url | POST 地址(相对后台 API 根) |
data-pvs-upload-scene | PivArk scene 字段(可选) |
data-pvs-upload-csrf-* | 或 meta pvs-csrf-field/token |
pvs-upload:done / :error | XHR 结果事件 |
PivCss.uploadFile() | 编程式上传 API |
类名速查
| 类名 | 说明 |
|---|---|
pvs-upload | 拖拽区(需 data-pvs-upload) |
pvs-upload__filelist / __file | 已选文件列表 |
pvs-upload__progress | XHR 进度条 |
data-pvs-upload-auto | 自动 POST |
PivAdmin | upload.ts · 去重/分片 · 不用 pivcss.js |
星级评分样式壳;is-active 由业务 JS 切换,只读用 pvs-rate--readonly。
默认
<div class="pvs-cluster pvs-items-center">
<ul class="pvs-rate" aria-label="评分 4 星">
<li>
<button type="button" class="pvs-rate__star is-active" aria-label="1 星">★</button>
</li>
<li>
<button type="button" class="pvs-rate__star is-active" aria-label="2 星">★</button>
</li>
<li>
<button type="button" class="pvs-rate__star is-active" aria-label="3 星">★</button>
</li>
<li>
<button type="button" class="pvs-rate__star is-active" aria-label="4 星">★</button>
</li>
<li>
<button type="button" class="pvs-rate__star" aria-label="5 星">★</button>
</li>
</ul>
<span class="pvs-rate__text">4.0</span>
</div>Readonly
- ★
- ★
- ★
- ★
- ★
<ul class="pvs-rate pvs-rate--readonly pvs-rate--sm" aria-label="平均 3.5 星">
<li>
<span class="pvs-rate__star is-active">★</span>
</li>
<li>
<span class="pvs-rate__star is-active">★</span>
</li>
<li>
<span class="pvs-rate__star is-active">★</span>
</li>
<li>
<span class="pvs-rate__star is-half">★</span>
</li>
<li>
<span class="pvs-rate__star">★</span>
</li>
</ul>类名速查
| 类名 | 说明 |
|---|---|
pvs-rate | ul 根 |
pvs-rate__star | 单星(button 或 span) |
is-active / is-half | 实心 / 半星 |
pvs-rate--readonly / --sm | 只读 / 紧凑 |
pvs-rate__text | 旁注分数 |
反馈Feedback
页面内提示块:主色 / 成功 / 警告 / 错误;可带标题与关闭按钮。
语义色
在 pvs-alert 上叠加 pvs-alert--* 语义色。
主色提示:新功能已上线。
成功:保存完成。
警告:配额即将用尽。
错误:提交失败,请重试。
<div class="pvs-stack">
<div class="pvs-alert pvs-alert--primary">
<p class="pvs-alert__body pvs-m-0">主色提示:新功能已上线。</p>
</div>
<div class="pvs-alert pvs-alert--success">
<p class="pvs-alert__body pvs-m-0">成功:保存完成。</p>
</div>
<div class="pvs-alert pvs-alert--warning">
<p class="pvs-alert__body pvs-m-0">警告:配额即将用尽。</p>
</div>
<div class="pvs-alert pvs-alert--danger">
<p class="pvs-alert__body pvs-m-0">错误:提交失败,请重试。</p>
</div>
</div>带标题
长说明用 pvs-alert__title + pvs-alert__body 分层。
注意备份
升级前请导出站点数据,过程约 5 分钟。
<div class="pvs-alert pvs-alert--warning">
<p class="pvs-alert__title">注意备份</p>
<p class="pvs-alert__body pvs-m-0">升级前请导出站点数据,过程约 5 分钟。</p>
</div>可关闭
pvs-alert__header 内放标题与 pvs-close(见 Close 组件)。
可关闭提示
点击右侧 × 关闭(需自行写 JS 或移除节点)。
<div class="pvs-alert pvs-alert--primary">
<div class="pvs-alert__header">
<p class="pvs-alert__title">可关闭提示</p>
<button type="button" class="pvs-close pvs-close--sm" aria-label="关闭">×</button>
</div>
<p class="pvs-alert__body pvs-m-0">点击右侧 × 关闭(需自行写 JS 或移除节点)。</p>
</div>类名速查
| 类名 | 说明 |
|---|---|
pvs-alert | 根容器 |
pvs-alert--primary / --success / --warning / --danger | 语义色 |
pvs-alert__title | 标题 |
pvs-alert__body | 正文 |
pvs-alert__header | 标题 + 关闭按钮行 |
吐司通知;角落固定,可手动或 JS 关闭。
语义吐司
保存成功
磁盘空间不足
同步失败
<div class="pvs-stack" style="max-width:20rem">
<div class="pvs-toast pvs-toast--success">
<p class="pvs-toast__body">保存成功</p>
<button type="button" class="pvs-close pvs-close--sm" data-pvs-toast-dismiss>×</button>
</div>
<div class="pvs-toast pvs-toast--warning">
<p class="pvs-toast__body">磁盘空间不足</p>
</div>
<div class="pvs-toast pvs-toast--danger">
<p class="pvs-toast__body">同步失败</p>
</div>
</div>固定容器
页面级固定容器:pvs-toast-container--top-end / --bottom-end。
右上角吐司
<div class="pvs-toast-container pvs-toast-container--top-end" style="position:relative;inset:auto;width:auto">
<div class="pvs-toast pvs-toast--success">
<p class="pvs-toast__body">右上角吐司</p>
</div>
</div>JavaScript API
PivCss.toast(message, { variant, duration, position }) 动态插入;文档演示按钮用 data-pvs-toast-demo。
<button type="button" class="pvs-btn pvs-btn--primary pvs-btn--sm" data-pvs-toast-demo="保存成功" data-pvs-toast-variant="success">PivCss.toast 演示</button>数据属性
| 类名 | 说明 |
|---|---|
data-pvs-toast-dismiss | 关闭该条 toast |
data-pvs-toast-demo | 文档演示按钮文案 |
PivCss.toast() | API · variant / duration / position |
类名速查
| 类名 | 说明 |
|---|---|
pvs-toast | 单条通知 |
pvs-toast--success / --warning / --danger | 语义色 |
pvs-toast__body | 文案 |
pvs-toast-container | 固定定位容器 |
pvs-toast-container--top-end / --bottom-end | 角落位置 |
PivCss.toast(msg, opts) | JS 动态通知 |
对话框遮罩层;需 pivcss.min.js(Tab 焦点陷阱 + Esc 回到触发按钮)。
基础
确认删除
此操作不可撤销,是否继续?
<button type="button" class="pvs-btn pvs-btn--primary pvs-btn--sm" data-pvs-modal-open="demo-modal">打开 Modal</button>
<div class="pvs-modal" id="demo-modal">
<div class="pvs-modal__backdrop">
</div>
<div class="pvs-modal__dialog">
<div class="pvs-modal__header">
<h3 class="pvs-modal__title">确认删除</h3>
<button type="button" class="pvs-close" data-pvs-modal-close aria-label="关闭">×</button>
</div>
<div class="pvs-modal__body">
<p class="pvs-m-0">此操作不可撤销,是否继续?</p>
</div>
<div class="pvs-modal__footer">
<button type="button" class="pvs-btn pvs-btn--ghost" data-pvs-modal-close>取消</button>
<button type="button" class="pvs-btn pvs-btn--danger">删除</button>
</div>
</div>
</div>尺寸
对话框宽度:pvs-modal--sm / 默认 / --lg。
小号对话框
根元素 pvs-modal--sm
默认宽度
无尺寸修饰符时的标准宽度。
大号对话框
根元素 pvs-modal--lg,适合表单或宽表格。
<div class="pvs-flex pvs-gap-2 pvs-flex-wrap">
<button type="button" class="pvs-btn pvs-btn--outline pvs-btn--sm" data-pvs-modal-open="demo-modal-sm">小号</button>
<button type="button" class="pvs-btn pvs-btn--outline pvs-btn--sm" data-pvs-modal-open="demo-modal-md">默认</button>
<button type="button" class="pvs-btn pvs-btn--outline pvs-btn--sm" data-pvs-modal-open="demo-modal-lg">大号</button>
</div>
<div class="pvs-modal pvs-modal--sm" id="demo-modal-sm">
<div class="pvs-modal__backdrop">
</div>
<div class="pvs-modal__dialog">
<div class="pvs-modal__header">
<h3 class="pvs-modal__title">小号对话框</h3>
<button type="button" class="pvs-close" data-pvs-modal-close aria-label="关闭">×</button>
</div>
<div class="pvs-modal__body">
<p class="pvs-m-0 pvs-text-sm">根元素 <code>pvs-modal--sm</code>
</p>
</div>
<div class="pvs-modal__footer">
<button type="button" class="pvs-btn pvs-btn--ghost pvs-btn--sm" data-pvs-modal-close>关闭</button>
</div>
</div>
</div>
<div class="pvs-modal" id="demo-modal-md">
<div class="pvs-modal__backdrop">
</div>
<div class="pvs-modal__dialog">
<div class="pvs-modal__header">
<h3 class="pvs-modal__title">默认宽度</h3>
<button type="button" class="pvs-close" data-pvs-modal-close aria-label="关闭">×</button>
</div>
<div class="pvs-modal__body">
<p class="pvs-m-0">无尺寸修饰符时的标准宽度。</p>
</div>
<div class="pvs-modal__footer">
<button type="button" class="pvs-btn pvs-btn--ghost" data-pvs-modal-close>关闭</button>
</div>
</div>
</div>
<div class="pvs-modal pvs-modal--lg" id="demo-modal-lg">
<div class="pvs-modal__backdrop">
</div>
<div class="pvs-modal__dialog">
<div class="pvs-modal__header">
<h3 class="pvs-modal__title">大号对话框</h3>
<button type="button" class="pvs-close" data-pvs-modal-close aria-label="关闭">×</button>
</div>
<div class="pvs-modal__body">
<p class="pvs-m-0">根元素 <code>pvs-modal--lg</code>,适合表单或宽表格。</p>
</div>
<div class="pvs-modal__footer">
<button type="button" class="pvs-btn pvs-btn--ghost" data-pvs-modal-close>关闭</button>
</div>
</div>
</div>Full & scroll body
pvs-modal--full 全屏;pvs-modal--scroll 仅 body 区滚动。
可滚动正文
pvs-modal--scroll:header/footer 固定,body 溢出滚动。
…
…
…
<button type="button" class="pvs-btn pvs-btn--outline pvs-btn--sm" data-pvs-modal-open="demo-modal-scroll">长内容 Modal</button>
<div class="pvs-modal pvs-modal--scroll" id="demo-modal-scroll">
<div class="pvs-modal__backdrop">
</div>
<div class="pvs-modal__dialog">
<div class="pvs-modal__header">
<h3 class="pvs-modal__title">可滚动正文</h3>
<button type="button" class="pvs-close" data-pvs-modal-close aria-label="关闭">×</button>
</div>
<div class="pvs-modal__body">
<p class="pvs-m-0">pvs-modal--scroll:header/footer 固定,body 溢出滚动。</p>
<p class="pvs-mt-4">…</p>
<p class="pvs-mt-4">…</p>
<p class="pvs-mt-4">…</p>
</div>
<div class="pvs-modal__footer">
<button type="button" class="pvs-btn pvs-btn--primary pvs-btn--sm" data-pvs-modal-close>确定</button>
</div>
</div>
</div>结构
div.pvs-modal#id → backdrop + div.pvs-modal__dialog → header / body / footer
数据属性
| 类名 | 说明 |
|---|---|
data-pvs-modal-open | 值为 modal id |
data-pvs-modal-close | 关闭(按钮或遮罩逻辑由 JS 处理) |
类名速查
| 类名 | 说明 |
|---|---|
pvs-modal | 根(默认隐藏) |
pvs-modal__dialog | 对话框卡片 |
pvs-modal__header / __title | 标题区 |
pvs-modal__body | 正文 |
pvs-modal__footer | 底栏按钮区 |
pvs-modal--sm / --lg | 宽度 |
pvs-modal--full | 全屏对话框 |
pvs-modal--scroll | body 区滚动 |
Tab 陷阱 | 打开后焦点在对话框内循环 |
Esc | 关闭并焦点回到 data-pvs-modal-open 按钮 |
body.pvs-modal-open | 打开时锁滚动 |
下拉菜单原子;pivcss.min.js 负责开关、点外关闭与方向键导航。
默认
容器 pvs-dropdown;触发器加 data-pvs-dropdown-toggle。
<div class="pvs-dropdown">
<button type="button" class="pvs-btn pvs-btn--outline pvs-dropdown__toggle" data-pvs-dropdown-toggle aria-expanded="false">菜单 ▾</button>
<div class="pvs-dropdown__menu">
<a class="pvs-dropdown__item" href="#">项一</a>
<a class="pvs-dropdown__item" href="#">项二</a>
<span class="pvs-dropdown__divider">
</span>
<a class="pvs-dropdown__item" href="#">退出</a>
</div>
</div>弹出方位
--right 右对齐;--up 向上展开。
<div class="pvs-flex pvs-gap-6 pvs-flex-wrap">
<div class="pvs-dropdown pvs-dropdown--right">
<button type="button" class="pvs-btn pvs-btn--ghost pvs-btn--sm" data-pvs-dropdown-toggle>右对齐 ▾</button>
<div class="pvs-dropdown__menu">
<a class="pvs-dropdown__item" href="#">A</a>
</div>
</div>
<div class="pvs-dropdown pvs-dropdown--up" style="margin-top:4rem">
<button type="button" class="pvs-btn pvs-btn--ghost pvs-btn--sm" data-pvs-dropdown-toggle>向上 ▴</button>
<div class="pvs-dropdown__menu">
<a class="pvs-dropdown__item" href="#">B</a>
</div>
</div>
</div>Submenu
pvs-dropdown__item--has-submenu + 嵌套 pvs-dropdown__submenu;hover/focus-within 展开。
<div class="pvs-dropdown">
<button type="button" class="pvs-btn pvs-btn--outline pvs-btn--sm" data-pvs-dropdown-toggle>更多 ▾</button>
<div class="pvs-dropdown__menu">
<a class="pvs-dropdown__item" href="#">概览</a>
<div class="pvs-dropdown__item--has-submenu">
<button type="button" class="pvs-dropdown__item">导出</button>
<div class="pvs-dropdown__submenu">
<a class="pvs-dropdown__item" href="#">HTML</a>
<a class="pvs-dropdown__item" href="#">PDF</a>
</div>
</div>
</div>
</div>Keyboard
触发器 ↓/Enter 打开并聚焦首项;菜单内 ↑↓ 移动,Esc 关闭并回到触发器。
<div class="pvs-dropdown">
<button type="button" class="pvs-btn pvs-btn--outline pvs-btn--sm" data-pvs-dropdown-toggle aria-haspopup="true">键盘试试 ▾</button>
<div class="pvs-dropdown__menu">
<a class="pvs-dropdown__item" href="#">项一</a>
<a class="pvs-dropdown__item" href="#">项二</a>
<a class="pvs-dropdown__item" href="#">项三</a>
</div>
</div>弹出层
轻量弹出说明 pvs-popover;data-pvs-popover-toggle 开关。
12 轨栅格
原生 CSS Grid 分栏,非 flex 列。
<div class="pvs-popover">
<button type="button" class="pvs-btn pvs-btn--outline pvs-btn--sm pvs-popover__toggle" data-pvs-popover-toggle aria-expanded="false">什么是 Grid?</button>
<div class="pvs-popover__bubble">
<p class="pvs-popover__title">12 轨栅格</p>
<p class="pvs-m-0 pvs-text-sm">原生 CSS Grid 分栏,非 flex 列。</p>
</div>
</div>弹出方位
pvs-popover--top 向上;--end 右对齐。
气泡在按钮上方
气泡右缘对齐触发器
<div class="pvs-flex pvs-gap-6 pvs-flex-wrap pvs-items-center" style="padding-top:5rem">
<div class="pvs-popover pvs-popover--top">
<button type="button" class="pvs-btn pvs-btn--ghost pvs-btn--sm" data-pvs-popover-toggle>向上 ▴</button>
<div class="pvs-popover__bubble">
<p class="pvs-m-0 pvs-text-sm">气泡在按钮上方</p>
</div>
</div>
<div class="pvs-popover pvs-popover--end">
<button type="button" class="pvs-btn pvs-btn--ghost pvs-btn--sm" data-pvs-popover-toggle>右对齐</button>
<div class="pvs-popover__bubble">
<p class="pvs-m-0 pvs-text-sm">气泡右缘对齐触发器</p>
</div>
</div>
</div>Popover keyboard
触发器 Enter/Space 切换;Esc 关闭并回焦(与 Dropdown 一致)。
标题
Enter 开关 · Esc 关闭
<div class="pvs-popover">
<button type="button" class="pvs-btn pvs-btn--outline pvs-btn--sm" data-pvs-popover-toggle aria-expanded="false">键盘 Popover</button>
<div class="pvs-popover__bubble">
<p class="pvs-popover__title">标题</p>
<p class="pvs-m-0 pvs-text-sm">Enter 开关 · Esc 关闭</p>
</div>
</div>结构
div.pvs-dropdown → toggle + div.pvs-dropdown__menu → a.pvs-dropdown__item
数据属性
| 类名 | 说明 |
|---|---|
data-pvs-dropdown-toggle | 点击展开/收起菜单 |
键盘 | ↓/Enter 打开 · ↑↓ 项间移动 · Esc 关闭 |
data-pvs-popover-toggle | 点击展开/收起弹出层 |
Popover 键盘 | Enter/Space 切换 · Esc 回触发器 |
类名速查
| 类名 | 说明 |
|---|---|
pvs-dropdown | 根容器;打开时加 is-open |
pvs-dropdown__toggle | 触发按钮(可选) |
pvs-dropdown__menu | 菜单面板 |
pvs-dropdown__item | 菜单项 |
pvs-dropdown__divider | 项间分隔线 |
pvs-dropdown--right / --up | 对齐与方向 |
pvs-dropdown__item--has-submenu | 多级子菜单容器 |
pvs-dropdown__submenu | 右侧飞出子菜单 |
pvs-popover / __bubble | 弹出说明层 |
pvs-popover--top / --end | 向上 / 右对齐 |
data-pvs-popover-toggle | 弹出层开关 |
侧滑抽屉;左右方向,带遮罩。
左侧滑出
<button type="button" class="pvs-btn pvs-btn--outline pvs-btn--sm" data-pvs-offcanvas-open="demo-offcanvas">打开左侧抽屉</button>
<div class="pvs-offcanvas-backdrop" data-pvs-offcanvas-backdrop="demo-offcanvas">
</div>
<div class="pvs-offcanvas pvs-offcanvas--start" id="demo-offcanvas">
<div class="pvs-offcanvas__header">
<h3 class="pvs-offcanvas__title">菜单</h3>
<button type="button" class="pvs-close" data-pvs-offcanvas-close>×</button>
</div>
<div class="pvs-offcanvas__body">
<ul class="pvs-list pvs-list--unstyled">
<li>
<a class="pvs-link" href="#">首页</a>
</li>
<li>
<a class="pvs-link" href="#">设置</a>
</li>
</ul>
</div>
</div>右侧滑出
pvs-offcanvas--end 从右侧滑入。
购物车
右侧抽屉 · 常用于购物车、筛选面板。
<button type="button" class="pvs-btn pvs-btn--outline pvs-btn--sm" data-pvs-offcanvas-open="demo-offcanvas-end">打开右侧抽屉</button>
<div class="pvs-offcanvas-backdrop" data-pvs-offcanvas-backdrop="demo-offcanvas-end">
</div>
<div class="pvs-offcanvas pvs-offcanvas--end" id="demo-offcanvas-end">
<div class="pvs-offcanvas__header">
<h3 class="pvs-offcanvas__title">购物车</h3>
<button type="button" class="pvs-close" data-pvs-offcanvas-close>×</button>
</div>
<div class="pvs-offcanvas__body">
<p class="pvs-m-0 pvs-text-sm">右侧抽屉 · 常用于购物车、筛选面板。</p>
</div>
</div>Off-canvas keyboard
打开后焦点进入抽屉;Tab 在抽屉内循环;Esc 回到 data-pvs-offcanvas-open 按钮。
<button type="button" class="pvs-btn pvs-btn--outline pvs-btn--sm" data-pvs-offcanvas-open="demo-offcanvas-kb">键盘抽屉</button>
<div class="pvs-offcanvas-backdrop" data-pvs-offcanvas-backdrop="demo-offcanvas-kb">
</div>
<div class="pvs-offcanvas pvs-offcanvas--start" id="demo-offcanvas-kb">
<div class="pvs-offcanvas__header">
<h3 class="pvs-offcanvas__title">导航</h3>
<button type="button" class="pvs-close" data-pvs-offcanvas-close aria-label="关闭">×</button>
</div>
<div class="pvs-offcanvas__body">
<a class="pvs-link" href="#">链接 A</a> · <a class="pvs-link" href="#">链接 B</a>
</div>
</div>数据属性
| 类名 | 说明 |
|---|---|
data-pvs-offcanvas-open | 值为 offcanvas id |
data-pvs-offcanvas-close | 关闭 |
data-pvs-offcanvas-backdrop | 遮罩,值为 id |
Off-canvas 键盘 | Tab 陷阱 · Esc 回触发器 |
类名速查
| 类名 | 说明 |
|---|---|
pvs-offcanvas | 抽屉根 |
pvs-offcanvas--start / --end | 左 / 右 |
pvs-offcanvas__header / __title | 标题区 |
pvs-offcanvas__body | 内容 |
pvs-offcanvas-backdrop | 遮罩层 |
body.pvs-offcanvas-open | 打开时锁滚动 |
悬停 / 聚焦显示的轻提示;纯 CSS,无需 JS(Popover 为点击展开、可含标题)。
默认
将 pvs-tooltip__bubble 放在触发器内;鼠标悬停或键盘聚焦时显示。
<span class="pvs-tooltip">
<button type="button" class="pvs-btn pvs-btn--ghost pvs-btn--sm pvs-tooltip__trigger" aria-describedby="tt-demo">栅格</button>
<span class="pvs-tooltip__bubble" id="tt-demo" role="tooltip">12 轨 CSS Grid</span>
</span>弹出方位
pvs-tooltip--top 向上;--start / --end 水平对齐。
<div class="pvs-flex pvs-gap-8 pvs-flex-wrap pvs-items-center" style="padding:4rem 0 2rem">
<span class="pvs-tooltip pvs-tooltip--top">
<button type="button" class="pvs-btn pvs-btn--outline pvs-btn--sm">向上</button>
<span class="pvs-tooltip__bubble" role="tooltip">Top</span>
</span>
<span class="pvs-tooltip pvs-tooltip--end">
<button type="button" class="pvs-btn pvs-btn--outline pvs-btn--sm">右对齐</button>
<span class="pvs-tooltip__bubble" role="tooltip">End 对齐</span>
</span>
</div>类名速查
| 类名 | 说明 |
|---|---|
pvs-tooltip | 根容器 |
pvs-tooltip__trigger | 触发元素(可选) |
pvs-tooltip__bubble | 提示气泡 |
pvs-tooltip--top / --start / --end | 方位 |
role="tooltip" + aria-describedby | 无障碍建议 |
进度条;用内联 style="width:%" 控制进度。
默认
45%
<div class="pvs-progress">
<span class="pvs-progress__bar" style="width:45%">
</span>
</div>
<p class="pvs-text-sm pvs-text-muted pvs-mt-2 pvs-m-0">45%</p>语义与尺寸
<div class="pvs-stack">
<div class="pvs-progress pvs-progress--sm">
<span class="pvs-progress__bar" style="width:30%">
</span>
</div>
<div class="pvs-progress pvs-progress--success">
<span class="pvs-progress__bar" style="width:70%">
</span>
</div>
<div class="pvs-progress pvs-progress--warning pvs-progress--lg">
<span class="pvs-progress__bar" style="width:50%">
</span>
</div>
<div class="pvs-progress pvs-progress--danger">
<span class="pvs-progress__bar" style="width:90%">
</span>
</div>
</div>Striped & animated
pvs-progress--striped 条纹;叠加 --animated 流动动画。
<div class="pvs-stack">
<div class="pvs-progress pvs-progress--striped">
<span class="pvs-progress__bar" style="width:55%">
</span>
</div>
<div class="pvs-progress pvs-progress--striped pvs-progress--animated pvs-progress--success">
<span class="pvs-progress__bar" style="width:70%">
</span>
</div>
</div>类名速查
| 类名 | 说明 |
|---|---|
pvs-progress | 轨道 |
pvs-progress__bar | 填充条(设 width) |
pvs-progress--sm / --lg | 高度 |
pvs-progress--success / --warning / --danger | 语义色 |
pvs-progress--striped / --animated | 条纹 / 动画 |
加载旋转指示器,可嵌在按钮或页面居中。
尺寸
<div class="pvs-cluster pvs-items-center">
<span class="pvs-spinner">
</span>
<span class="pvs-spinner pvs-spinner--sm">
</span>
<span class="pvs-spinner pvs-spinner--lg">
</span>
</div>深色底浅色
<div class="pvs-p-4 pvs-bg-primary pvs-inline-block pvs-rounded-md">
<span class="pvs-spinner pvs-spinner--light">
</span>
</div>按钮内
<button type="button" class="pvs-btn pvs-btn--primary" disabled>
<span class="pvs-spinner pvs-spinner--sm pvs-spinner--light">
</span> 加载中…</button>Ring variant
pvs-spinner--ring 缺口圆环变体。
<div class="pvs-cluster pvs-items-center">
<span class="pvs-spinner pvs-spinner--ring">
</span>
<span class="pvs-spinner pvs-spinner--ring pvs-spinner--lg">
</span>
</div>类名速查
| 类名 | 说明 |
|---|---|
pvs-spinner | 默认尺寸 |
pvs-spinner--sm / --lg | 小 / 大 |
pvs-spinner--light | 浅色(深底上用) |
pvs-spinner--ring | 缺口圆环 |
Placeholder骨架占位
单页 →骨架屏占位块;pvs-skeleton 组合列表/媒体/表格布局。
Pulse
<div class="pvs-stack pvs-gap-3" style="max-width:18rem">
<span class="pvs-placeholder pvs-placeholder--heading">
</span>
<span class="pvs-placeholder pvs-placeholder--text">
</span>
<span class="pvs-placeholder pvs-placeholder--text-sm">
</span>
<span class="pvs-placeholder pvs-placeholder--btn">
</span>
</div>Glow
pvs-placeholder--glow 扫光动画变体。
<div class="pvs-stack pvs-gap-3" style="max-width:18rem">
<span class="pvs-placeholder pvs-placeholder--glow pvs-placeholder--heading">
</span>
<span class="pvs-placeholder pvs-placeholder--glow pvs-placeholder--text">
</span>
</div>Card skeleton
<div style="max-width:14rem">
<span class="pvs-placeholder pvs-placeholder--avatar pvs-mb-3">
</span>
<span class="pvs-placeholder pvs-placeholder--card">
</span>
</div>Media row
pvs-skeleton--media 头像 + 两行文字。
<div class="pvs-skeleton pvs-skeleton--media" style="max-width:18rem">
<span class="pvs-placeholder pvs-placeholder--avatar">
</span>
<div class="pvs-skeleton__body">
<span class="pvs-placeholder pvs-placeholder--heading">
</span>
<span class="pvs-placeholder pvs-placeholder--text-sm">
</span>
</div>
</div>List skeleton
<ul class="pvs-skeleton-list" style="max-width:18rem">
<li class="pvs-skeleton-list__item">
<span class="pvs-placeholder pvs-placeholder--avatar">
</span>
<span class="pvs-placeholder pvs-placeholder--text">
</span>
</li>
<li class="pvs-skeleton-list__item">
<span class="pvs-placeholder pvs-placeholder--avatar">
</span>
<span class="pvs-placeholder pvs-placeholder--text-sm">
</span>
</li>
</ul>Table skeleton
<table class="pvs-skeleton-table" style="max-width:20rem">
<tbody>
<tr>
<td>
<span class="pvs-placeholder pvs-placeholder--table-cell">
</span>
</td>
<td>
<span class="pvs-placeholder pvs-placeholder--table-cell" style="width:60%">
</span>
</td>
</tr>
<tr>
<td>
<span class="pvs-placeholder pvs-placeholder--table-cell">
</span>
</td>
<td>
<span class="pvs-placeholder pvs-placeholder--table-cell" style="width:75%">
</span>
</td>
</tr>
</tbody>
</table>类名速查
| 类名 | 说明 |
|---|---|
pvs-placeholder | 根类(脉冲) |
pvs-placeholder--glow | 扫光动画 |
pvs-skeleton / --media | 组合骨架 |
pvs-skeleton-list | 列表行骨架 |
pvs-skeleton-table | 表格行骨架 |
pvs-placeholder--avatar / --card | 头像 / 卡片块 |
Empty state空状态
单页 →列表或搜索无数据时的占位;可带图标、说明与操作按钮。
默认
暂无文档
还没有创建任何内容,点击下方按钮开始第一篇。
<div class="pvs-empty pvs-border pvs-rounded-md" style="max-width:24rem">
<div class="pvs-empty__icon" aria-hidden="true">📭</div>
<p class="pvs-empty__title">暂无文档</p>
<p class="pvs-empty__desc">还没有创建任何内容,点击下方按钮开始第一篇。</p>
<div class="pvs-empty__actions">
<button type="button" class="pvs-btn pvs-btn--primary pvs-btn--sm">新建文档</button>
</div>
</div>Compact
pvs-empty--compact 减小上下留白,适合嵌在卡片或表格下方。
无匹配结果
试试更换关键词或清空筛选。
<div class="pvs-empty pvs-empty--compact pvs-border pvs-rounded-md" style="max-width:20rem">
<p class="pvs-empty__title">无匹配结果</p>
<p class="pvs-empty__desc">试试更换关键词或清空筛选。</p>
</div>类名速查
| 类名 | 说明 |
|---|---|
pvs-empty | 根容器 |
pvs-empty__icon / __title / __desc | 图标、标题、说明 |
pvs-empty__actions | 底部按钮区 |
pvs-empty--compact | 紧凑留白 |
数据Data
数据表格:斑马纹、无边框、紧凑;--sortable / --selectable 为 DataTable 纯样式层(排序/选中 JS 由 CMS 负责)。
默认
| 名称 | 角色 | 状态 |
|---|---|---|
| Alice | 编辑 | 启用 |
| Bob | 访客 | 停用 |
<div class="pvs-table-wrap">
<table class="pvs-table">
<thead>
<tr>
<th>名称</th>
<th>角色</th>
<th>状态</th>
</tr>
</thead>
<tbody>
<tr>
<td>Alice</td>
<td>编辑</td>
<td>启用</td>
</tr>
<tr>
<td>Bob</td>
<td>访客</td>
<td>停用</td>
</tr>
</tbody>
</table>
</div>条纹 / 无边框 / 紧凑
| SKU | 库存 |
|---|---|
| A-01 | 120 |
| B-02 | 8 |
| C-03 | 45 |
| 列1 | 列2 |
|---|---|
| 无竖线 | 表格 |
<div class="pvs-table-wrap">
<table class="pvs-table pvs-table--striped pvs-table--compact">
<thead>
<tr>
<th>SKU</th>
<th>库存</th>
</tr>
</thead>
<tbody>
<tr>
<td>A-01</td>
<td>120</td>
</tr>
<tr>
<td>B-02</td>
<td>8</td>
</tr>
<tr>
<td>C-03</td>
<td>45</td>
</tr>
</tbody>
</table>
</div>
<div class="pvs-table-wrap pvs-mt-4">
<table class="pvs-table pvs-table--borderless">
<thead>
<tr>
<th>列1</th>
<th>列2</th>
</tr>
</thead>
<tbody>
<tr>
<td>无竖线</td>
<td>表格</td>
</tr>
</tbody>
</table>
</div>悬停行
默认表格行悬停有浅蓝底(无需额外类)。
| 用户 | 邮箱 |
|---|---|
| Alice | alice@ex.com |
| Bob | bob@ex.com |
| Carol | carol@ex.com |
鼠标悬停行查看高亮
<div class="pvs-table-wrap">
<table class="pvs-table">
<thead>
<tr>
<th>用户</th>
<th>邮箱</th>
</tr>
</thead>
<tbody>
<tr>
<td>Alice</td>
<td>alice@ex.com</td>
</tr>
<tr>
<td>Bob</td>
<td>bob@ex.com</td>
</tr>
<tr>
<td>Carol</td>
<td>carol@ex.com</td>
</tr>
</tbody>
</table>
</div>
<p class="pvs-text-sm pvs-text-muted pvs-mt-2 pvs-m-0">鼠标悬停行查看高亮</p>DataTable shell
工具条 + 可排序表头 + 可选中行;is-sorted-asc / is-selected 由业务 JS 切换。
| 名称 | 角色 | 更新时间 | |
|---|---|---|---|
| Alice | 编辑 | 06-15 | |
| Bob | 访客 | 06-14 |
<div class="pvs-table__toolbar">
<span class="pvs-text-sm pvs-font-semibold">用户列表</span>
<div class="pvs-table__toolbar-actions">
<button type="button" class="pvs-btn pvs-btn--outline pvs-btn--sm">导出</button>
<button type="button" class="pvs-btn pvs-btn--primary pvs-btn--sm">新建</button>
</div>
</div>
<div class="pvs-table-wrap">
<table class="pvs-table pvs-table--striped pvs-table--sortable pvs-table--selectable">
<thead>
<tr>
<th class="pvs-table__check">
<input type="checkbox" aria-label="全选" />
</th>
<th class="is-sorted-asc">名称</th>
<th>角色</th>
<th class="is-sorted-desc">更新时间</th>
</tr>
<tr class="pvs-table__filter-row">
<th>
</th>
<th>
<input class="pvs-input pvs-input--sm" type="search" placeholder="筛选…" />
</th>
<th>
<select class="pvs-select pvs-input--sm">
<option>全部</option>
</select>
</th>
<th>
</th>
</tr>
</thead>
<tbody>
<tr class="is-selected">
<td class="pvs-table__check">
<input type="checkbox" checked />
</td>
<td>Alice</td>
<td>编辑</td>
<td>06-15</td>
</tr>
<tr>
<td class="pvs-table__check">
<input type="checkbox" />
</td>
<td>Bob</td>
<td>访客</td>
<td>06-14</td>
</tr>
</tbody>
</table>
</div>类名速查
| 类名 | 说明 |
|---|---|
pvs-table-wrap | 横向滚动外壳 |
pvs-table | 表格根 |
pvs-table--striped | 斑马纹 |
pvs-table--borderless | 无竖线 |
pvs-table--compact | 紧凑行高 |
pvs-table--sortable | 可排序表头箭头 |
pvs-table--selectable | 可选中行高亮 |
pvs-table__toolbar | 表格上方工具条 |
pvs-table__filter-row | 表头下筛选行 |
is-sorted-asc / is-sorted-desc | 排序方向(JS 切换) |
is-selected | 选中行(JS 切换) |
树形列表;data-pvs-tree + 勾选/选中 JS;节点与 summary :focus-visible 焦点环。
Checkboxes & select
- 全站
内容
- 文档
- 回收站
<ul class="pvs-tree" data-pvs-tree data-pvs-tree-checkboxes data-pvs-tree-selectable style="max-width:16rem">
<li class="pvs-tree__item">
<span class="pvs-tree__label">
<input class="pvs-tree__check" type="checkbox" /> 全站</span>
</li>
<li class="pvs-tree__item">
<details open>
<summary class="pvs-tree__label">
<span class="pvs-tree__toggle">
</span>
<input class="pvs-tree__check" type="checkbox" /> 内容</summary>
<ul>
<li class="pvs-tree__item">
<span class="pvs-tree__label">
<input class="pvs-tree__check" type="checkbox" /> 文档</span>
</li>
<li class="pvs-tree__item pvs-tree__item--disabled">
<span class="pvs-tree__label">
<input class="pvs-tree__check" type="checkbox" disabled /> 回收站</span>
</li>
</ul>
</details>
</li>
</ul>Compact & lines
pvs-tree--compact 缩进行高;pvs-tree--lines 显示层级引导线。
- 根
栏目
- 当前页
<ul class="pvs-tree pvs-tree--compact pvs-tree--lines" data-pvs-tree style="max-width:14rem">
<li class="pvs-tree__item">
<span class="pvs-tree__label">根</span>
</li>
<li class="pvs-tree__item">
<details open>
<summary class="pvs-tree__label">
<span class="pvs-tree__toggle">
</span>栏目</summary>
<ul>
<li class="pvs-tree__item pvs-tree__item--selected">
<span class="pvs-tree__label">当前页</span>
</li>
</ul>
</details>
</li>
</ul>数据属性
| 类名 | 说明 |
|---|---|
data-pvs-tree | 初始化树交互 |
data-pvs-tree-checkboxes | 父节点勾选联动子节点 |
data-pvs-tree-selectable | 点击 label 切换 --selected |
data-pvs-tree-single | 单选高亮(可选) |
类名速查
| 类名 | 说明 |
|---|---|
pvs-tree | ul 根(需 data-pvs-tree) |
pvs-tree__label | 节点行 |
pvs-tree__item--selected / --disabled | 选中 / 禁用 |
pvs-tree--compact | 紧凑行高 |
步骤条:安装向导、发布流程等多步任务进度展示。
横排布局
- 填写信息
- 确认订单当前步骤
- 完成支付
<ol class="pvs-steps" style="max-width:36rem">
<li class="pvs-steps__item pvs-steps__item--done">
<span class="pvs-steps__label">填写信息</span>
</li>
<li class="pvs-steps__item pvs-steps__item--active">
<span class="pvs-steps__label">确认订单</span>
<span class="pvs-steps__hint">当前步骤</span>
</li>
<li class="pvs-steps__item">
<span class="pvs-steps__label">完成支付</span>
</li>
</ol>垂直
pvs-steps--vertical 纵向排列,适合侧栏或窄屏。
- 环境检测已通过
- 数据库配置
- 创建管理员
<ol class="pvs-steps pvs-steps--vertical" style="max-width:16rem">
<li class="pvs-steps__item pvs-steps__item--done">
<div class="pvs-steps__body">
<span class="pvs-steps__label">环境检测</span>
<span class="pvs-steps__hint">已通过</span>
</div>
</li>
<li class="pvs-steps__item pvs-steps__item--active">
<div class="pvs-steps__body">
<span class="pvs-steps__label">数据库配置</span>
</div>
</li>
<li class="pvs-steps__item">
<div class="pvs-steps__body">
<span class="pvs-steps__label">创建管理员</span>
</div>
</li>
</ol>类名速查
| 类名 | 说明 |
|---|---|
pvs-steps | ol 根 |
pvs-steps__item | 单步 |
pvs-steps__item--active / --done | 当前 / 已完成 |
pvs-steps--vertical | 纵向布局 |
时间线:审核记录、操作日志等按时间排列的事件列表。
默认
提交审核
编辑提交了文档「快速开始」。
审核通过
已发布至线上。
定时下线
计划任务已创建。
<ul class="pvs-timeline" style="max-width:22rem">
<li class="pvs-timeline__item">
<time class="pvs-timeline__time">2026-06-15 10:00</time>
<p class="pvs-timeline__title">提交审核</p>
<p class="pvs-timeline__desc">编辑提交了文档「快速开始」。</p>
</li>
<li class="pvs-timeline__item pvs-timeline__item--success">
<time class="pvs-timeline__time">10:32</time>
<p class="pvs-timeline__title">审核通过</p>
<p class="pvs-timeline__desc">已发布至线上。</p>
</li>
<li class="pvs-timeline__item pvs-timeline__item--muted">
<time class="pvs-timeline__time">11:00</time>
<p class="pvs-timeline__title">定时下线</p>
<p class="pvs-timeline__desc">计划任务已创建。</p>
</li>
</ul>Semantic dots
--success / --warning / --muted 节点语义色。
配额告警
存储使用 85%。
备份完成
<ul class="pvs-timeline" style="max-width:18rem">
<li class="pvs-timeline__item pvs-timeline__item--warning">
<p class="pvs-timeline__title">配额告警</p>
<p class="pvs-timeline__desc">存储使用 85%。</p>
</li>
<li class="pvs-timeline__item pvs-timeline__item--success">
<p class="pvs-timeline__title">备份完成</p>
</li>
</ul>类名速查
| 类名 | 说明 |
|---|---|
pvs-timeline | ul 根 |
pvs-timeline__time / __title / __desc | 时间、标题、说明 |
pvs-timeline__item--success / --warning / --muted | 节点语义色 |
媒体Media
轮播幻灯;data-pvs-carousel 挂载 JS,支持自动播放与指示点。
默认
根节点加 data-pvs-carousel;data-pvs-carousel-autoplay="5000" 毫秒自动轮播(悬停/聚焦暂停)。
<div class="pvs-carousel pvs-carousel--ratio-16x9" data-pvs-carousel data-pvs-carousel-autoplay="6000" style="max-width:32rem">
<div class="pvs-carousel__viewport">
<div class="pvs-carousel__track">
<div class="pvs-carousel__slide is-active">
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='640' height='360'%3E%3Crect fill='%232563eb' width='100%25' height='100%25'/%3E%3Ctext x='50%25' y='50%25' fill='white' font-size='32' text-anchor='middle' dominant-baseline='middle'%3E1%3C/text%3E%3C/svg%3E" alt="幻灯 1" />
</div>
<div class="pvs-carousel__slide">
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='640' height='360'%3E%3Crect fill='%23059669' width='100%25' height='100%25'/%3E%3Ctext x='50%25' y='50%25' fill='white' font-size='32' text-anchor='middle' dominant-baseline='middle'%3E2%3C/text%3E%3C/svg%3E" alt="幻灯 2" />
</div>
<div class="pvs-carousel__slide">
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='640' height='360'%3E%3Crect fill='%23d97706' width='100%25' height='100%25'/%3E%3Ctext x='50%25' y='50%25' fill='white' font-size='32' text-anchor='middle' dominant-baseline='middle'%3E3%3C/text%3E%3C/svg%3E" alt="幻灯 3" />
</div>
</div>
</div>
<button type="button" class="pvs-carousel__prev" aria-label="上一张">‹</button>
<button type="button" class="pvs-carousel__next" aria-label="下一张">›</button>
<div class="pvs-carousel__indicators" role="tablist" aria-label="幻灯指示">
<button type="button" class="pvs-carousel__indicator is-active" aria-label="第 1 张">
</button>
<button type="button" class="pvs-carousel__indicator" aria-label="第 2 张">
</button>
<button type="button" class="pvs-carousel__indicator" aria-label="第 3 张">
</button>
</div>
</div>Manual only
去掉 data-pvs-carousel-autoplay 则仅箭头/指示器切换,无自动轮播。
<div class="pvs-carousel pvs-carousel--ratio-16x9" data-pvs-carousel style="max-width:24rem">
<div class="pvs-carousel__viewport">
<div class="pvs-carousel__track">
<div class="pvs-carousel__slide is-active">
<div class="pvs-carousel__caption">手动轮播 · 无 autoplay</div>
</div>
<div class="pvs-carousel__slide">
<div class="pvs-carousel__caption">第二屏</div>
</div>
</div>
</div>
<button type="button" class="pvs-carousel__prev" aria-label="上一张">‹</button>
<button type="button" class="pvs-carousel__next" aria-label="下一张">›</button>
</div>结构
div.pvs-carousel → __viewport → __track → __slide;可选 prev/next 与 indicators
类名速查
| 类名 | 说明 |
|---|---|
pvs-carousel | 根(需 data-pvs-carousel) |
pvs-carousel__track / __slide | 轨道与单页 |
pvs-carousel__prev / __next | 前后切换 |
pvs-carousel__indicator | 底部圆点 |
pvs-carousel--ratio-16x9 | 固定 16:9 画幅 |
data-pvs-carousel-autoplay | 自动播放间隔(毫秒) |
全屏图片灯箱;需 pivcss.min.js。
基础
<button type="button" class="pvs-btn pvs-btn--outline pvs-btn--sm" data-pvs-lightbox-open="demo-lightbox">打开灯箱</button>
<div class="pvs-lightbox" id="demo-lightbox">
<div class="pvs-lightbox__backdrop">
</div>
<div class="pvs-lightbox__stage">
<button type="button" class="pvs-close pvs-lightbox__close" data-pvs-lightbox-close aria-label="关闭">×</button>
<img class="pvs-lightbox__img pvs-img" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='260'%3E%3Crect fill='%23e2e8f0' width='100%25' height='100%25'/%3E%3Ctext x='50%25' y='50%25' text-anchor='middle' dy='.3em' fill='%2364748b'%3E预览图%3C/text%3E%3C/svg%3E" alt="示例" />
</div>
</div>Lightbox keyboard
打开后焦点进入舞台;Tab 在舞台内循环;Esc 或关闭按钮回到触发器。
<button type="button" class="pvs-btn pvs-btn--outline pvs-btn--sm" data-pvs-lightbox-open="demo-lightbox-kb">键盘灯箱</button>
<div class="pvs-lightbox" id="demo-lightbox-kb">
<div class="pvs-lightbox__backdrop">
</div>
<div class="pvs-lightbox__stage">
<button type="button" class="pvs-close pvs-lightbox__close" data-pvs-lightbox-close aria-label="关闭">×</button>
<img class="pvs-lightbox__img pvs-img" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='260'%3E%3Crect fill='%23e2e8f0' width='100%25' height='100%25'/%3E%3C/svg%3E" alt="示例" />
</div>
</div>Thumbnail gallery
data-pvs-lightbox-gallery 绑定灯箱 id;缩略图用 data-pvs-lightbox-thumb + data-pvs-lightbox-src。
<div class="pvs-lightbox-gallery" data-pvs-lightbox-gallery="demo-gallery-lb">
<button type="button" class="pvs-lightbox-gallery__thumb is-active" data-pvs-lightbox-thumb data-pvs-lightbox-src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='640' height='420'%3E%3Crect fill='%232563eb' width='100%25' height='100%25'/%3E%3Ctext x='50%25' y='50%25' fill='white' font-size='28' text-anchor='middle'%3E1%3C/text%3E%3C/svg%3E" data-pvs-lightbox-alt="图 1">
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='80' height='80'%3E%3Crect fill='%232563eb' width='100%25' height='100%25'/%3E%3C/svg%3E" alt="" />
</button>
<button type="button" class="pvs-lightbox-gallery__thumb" data-pvs-lightbox-thumb data-pvs-lightbox-src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='640' height='420'%3E%3Crect fill='%23059669' width='100%25' height='100%25'/%3E%3Ctext x='50%25' y='50%25' fill='white' font-size='28' text-anchor='middle'%3E2%3C/text%3E%3C/svg%3E" data-pvs-lightbox-alt="图 2">
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='80' height='80'%3E%3Crect fill='%23059669' width='100%25' height='100%25'/%3E%3C/svg%3E" alt="" />
</button>
</div>
<div class="pvs-lightbox" id="demo-gallery-lb">
<div class="pvs-lightbox__backdrop">
</div>
<div class="pvs-lightbox__stage">
<button type="button" class="pvs-lightbox__nav pvs-lightbox__nav--prev" data-pvs-lightbox-prev aria-label="上一张">‹</button>
<button type="button" class="pvs-close pvs-lightbox__close" data-pvs-lightbox-close aria-label="关闭">×</button>
<img class="pvs-lightbox__img pvs-img" src="" alt="" />
<button type="button" class="pvs-lightbox__nav pvs-lightbox__nav--next" data-pvs-lightbox-next aria-label="下一张">›</button>
</div>
</div>数据属性
| 类名 | 说明 |
|---|---|
data-pvs-lightbox-open | 值为灯箱 id |
data-pvs-lightbox-close | 关闭按钮 |
data-pvs-lightbox-gallery | 缩略图组 → 灯箱 id |
data-pvs-lightbox-thumb | 画廊缩略图触发 |
Lightbox 键盘 | Tab 陷阱 · Esc 回触发器 |
类名速查
| 类名 | 说明 |
|---|---|
pvs-lightbox | 根(默认隐藏) |
pvs-lightbox__backdrop | 遮罩,点击关闭 |
pvs-lightbox__stage | 居中舞台 |
pvs-lightbox__img | 图片 |
pvs-lightbox-gallery | 缩略图画廊 |
pvs-lightbox__nav--prev / --next | 画廊切换 |
body.pvs-lightbox-open | 打开时锁滚动 |
Infinite scroll无限滚动
单页 →列表底部哨兵触发加载;data-pvs-infinite-url 拉 HTML 片段,或监听 pvs-infinite:load 自行追加。
Scroll sentinel
容器 data-pvs-infinite;滚入视口时 POST/GET 下一页或走自定义事件。
- 条目 1
- 条目 2
- 条目 3
无 URL 时监听 pvs-infinite:load,在 detail.done(html, hasMore) 追加行。
<div class="pvs-infinite-scroll" data-pvs-infinite data-pvs-infinite-page="1" style="max-width:20rem;max-height:12rem;overflow:auto;border:1px solid var(--pvs-border-color)">
<ul class="pvs-infinite-scroll__list" data-pvs-infinite-list>
<li class="pvs-list__item">条目 1</li>
<li class="pvs-list__item">条目 2</li>
<li class="pvs-list__item">条目 3</li>
</ul>
<div class="pvs-infinite-scroll__loader">
<span class="pvs-spinner pvs-spinner--sm">
</span> 加载中…</div>
<div class="pvs-infinite-scroll__sentinel" data-pvs-infinite-sentinel aria-hidden="true">
</div>
<div class="pvs-infinite-scroll__end">没有更多了</div>
</div>
<p class="pvs-text-sm pvs-text-muted pvs-mt-2 pvs-m-0">无 URL 时监听 <code>pvs-infinite:load</code>,在 <code>detail.done(html, hasMore)</code> 追加行。</p>URL pagination
data-pvs-infinite-url 中 {page} 由 JS 替换;响应 HTML 片段 append 到 list。
- 已加载 #1
- 已加载 #2
下一页请求 /api/items?page=3(演示占位 URL)。
<div class="pvs-infinite-scroll" data-pvs-infinite data-pvs-infinite-url="/api/items?page={page}" data-pvs-infinite-page="2" style="max-width:20rem">
<ul class="pvs-infinite-scroll__list" data-pvs-infinite-list>
<li class="pvs-list__item">已加载 #1</li>
<li class="pvs-list__item">已加载 #2</li>
</ul>
<div class="pvs-infinite-scroll__loader">
<span class="pvs-spinner pvs-spinner--sm">
</span>
</div>
<div class="pvs-infinite-scroll__sentinel" data-pvs-infinite-sentinel>
</div>
</div>
<p class="pvs-text-sm pvs-text-muted pvs-m-0">下一页请求 <code>/api/items?page=3</code>(演示占位 URL)。</p>数据属性
| 类名 | 说明 |
|---|---|
data-pvs-infinite | 初始化 IntersectionObserver |
data-pvs-infinite-url | 下一页地址,{page} 占位 |
data-pvs-infinite-list | 追加目标(默认根容器) |
data-pvs-infinite-root | 滚动根选择器(可选) |
pvs-infinite:load | 无 URL 时自定义加载 |
pvs-infinite:error | 请求失败 |
类名速查
| 类名 | 说明 |
|---|---|
pvs-infinite-scroll | 根容器 |
pvs-infinite-scroll__list | 列表区 |
pvs-infinite-scroll__loader | 加载提示 |
is-loading / is-done | 状态类 |