概览
我们使用一大块连接的链接来进行分页,使链接不易被错过且易于扩展,同时提供较大的点击区域。分页是用列表 HTML 元素构建的,因此屏幕阅读器可以宣布可用链接的数量。使用一个包装的 <nav> 元素将其标识为导航区域,以便屏幕阅读器和其他辅助技术识别。
此外,由于页面可能有不止一个这样的导航部分,建议提供一个描述性 aria-label 为了 <nav> 以反映其目的。例如,如果分页组件用于在一组搜索结果之间导航,一个合适的标签可能是 aria-label="Search results pages".
<nav aria-label="Page navigation example">
<ul class="pagination">
<li class="page-item"><a class="page-link" href="#">Previous</a></li>
<li class="page-item"><a class="page-link" href="#">1</a></li>
<li class="page-item"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item"><a class="page-link" href="#">Next</a></li>
</ul>
</nav>使用图标
想在某些分页链接中使用图标或符号代替文字吗?请确保使用aria属性为屏幕阅读器提供适当支持。
<nav aria-label="Page navigation example">
<ul class="pagination">
<li class="page-item">
<a class="page-link" href="#" aria-label="上一个">
<span aria-hidden="true">«</span>
</a>
</li>
<li class="page-item"><a class="page-link" href="#">1</a></li>
<li class="page-item"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item">
<a class="page-link" href="#" aria-label="下一个">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>活跃
添加 .active 以指示 .page-item 是当前正在查看的。如果在当前页面使用 <a>,应为辅助技术添加 aria-current="page"。
<nav aria-label="...">
<ul class="pagination">
<li class="page-item"><a href="#" class="page-link">Previous</a></li>
<li class="page-item"><a class="page-link" href="#">1</a></li>
<li class="page-item active">
<a class="page-link" href="#" aria-current="page">2</a>
</li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item"><a class="page-link" href="#">Next</a></li>
</ul>
</nav>如果使用非交互元素,例如当前页面的<span>,可以省略aria-current属性。
<li class="page-item active">
<span class="page-link">2</span>
</li>
残疾
添加 .disabled 到一个 .page-item 让它看起来无法点击。与此同时 .disabled 使用 pointer-events: none 为了禁用链接的交互性,该 CSS 属性尚未标准化,也不考虑键盘导航。因此,你应该始终添加 tabindex="-1" 在禁用的链接上,并使用自定义 JavaScript 完全禁用它们的功能。
<nav aria-label="...">
<ul class="pagination">
<li class="page-item disabled">
<a class="page-link">Previous</a>
</li>
<li class="page-item"><a class="page-link" href="#">1</a></li>
<li class="page-item active">
<a class="page-link" href="#" aria-current="page">2</a>
</li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item">
<a class="page-link" href="#">Next</a>
</li>
</ul>
</nav>就像活动页面项目一样,你可以将禁用的 <a> 替换为 <span>,以移除点击功能并防止键盘聚焦,同时保留预期的样式。
<li class="page-item disabled">
<span class="page-link">Previous</span>
</li>
变体
添加一个 .theme-{color} 上课到 .pagination 在整个组件中应用语义主题颜色,包括悬停、聚焦和活动页面项。
<ul class="pagination theme-primary">
<!-- Page items here -->
</ul>尺寸
想要更大或更小的页码?添加.pagination-lg或.pagination-sm以获得额外尺寸。
<nav aria-label="…">
<ul class="pagination pagination-sm">…</ul>
</nav>
<nav aria-label="…">
<ul class="pagination pagination">…</ul>
</nav>
<nav aria-label="…">
<ul class="pagination pagination-lg">…</ul>
</nav>
对齐
使用 flexbox 工具 更改分页组件的对齐方式。例如,使用 .justify-content-center:
<nav aria-label="Page navigation example">
<ul class="pagination justify-content-center">
<li class="page-item disabled">
<a class="page-link">Previous</a>
</li>
<li class="page-item"><a class="page-link" href="#">1</a></li>
<li class="page-item"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item">
<a class="page-link" href="#">Next</a>
</li>
</ul>
</nav>或者用 .justify-content-end:
<nav aria-label="Page navigation example">
<ul class="pagination justify-content-end">
<li class="page-item disabled">
<a class="page-link">Previous</a>
</li>
<li class="page-item"><a class="page-link" href="#">1</a></li>
<li class="page-item"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item">
<a class="page-link" href="#">Next</a>
</li>
</ul>
</nav>CSS
变量
分页在.pagination上使用本地 CSS 变量以实现实时自定义。CSS 变量的值由每个组件独有的 Sass map生成,并应用于上述类。
// stylelint-disable-next-line scss/dollar-variable-default
$pagination-tokens: defaults(
(
--pagination-min-height: var(--btn-input-min-height),
--pagination-padding-x: var(--btn-input-padding-x),
--pagination-padding-y: var(--btn-input-padding-y),
--pagination-font-size: var(--btn-input-font-size),
--pagination-color: var(--link-color),
--pagination-bg: var(--bg-body),
--pagination-border-width: var(--border-width),
--pagination-border-color: var(--border-color),
--pagination-border-radius: var(--btn-input-border-radius),
--pagination-hover-color: var(--link-hover-color),
--pagination-hover-bg: var(--bg-1),
--pagination-hover-border-color: var(--border-color),
--pagination-active-color: var(--theme-contrast, var(--primary-contrast)),
--pagination-active-bg: var(--theme-bg, var(--primary-bg)),
--pagination-active-border-color: var(--theme-bg, var(--primary-bg)),
--pagination-disabled-color: var(--fg-3),
--pagination-disabled-bg: var(--bg-2),
--pagination-disabled-border-color: var(--border-color),
),
$pagination-tokens
);
Sass 尺寸
$pagination-sizes: ();
// stylelint-disable-next-line scss/dollar-variable-default
$pagination-sizes: defaults(
("sm", "lg"),
$pagination-sizes
);
// scss-docs-end pagination-sizes
// stylelint-enable custom-property-no-missing-var-function
@layer components {
.pagination {
@include tokens($pagination-tokens);
display: flex;
@include list-unstyled();
}
.page-link {
position: relative;
display: flex;
align-items: center;
justify-content: center;
min-height: var(--pagination-min-height);
padding: var(--pagination-padding-y) var(--pagination-padding-x);
font-size: var(--pagination-font-size);
color: var(--theme-fg, var(--pagination-color));
text-decoration: none;
background-color: var(--pagination-bg);
border: var(--pagination-border-width) solid var(--pagination-border-color);
@include transition(color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out);
&:hover {
z-index: 2;
color: var(--theme-fg-emphasis, var(--pagination-hover-color));
background-color: var(--theme-bg-subtle, var(--pagination-hover-bg));
border-color: var(--theme-border, var(--pagination-hover-border-color));
}
&:focus-visible {
z-index: 3;
@include focus-ring(true, var(--theme-focus-ring, var(--focus-ring-color)));
}
&.active,
.active > & {
z-index: 3;
color: var(--theme-contrast, var(--pagination-active-color));
background-color: var(--theme-bg, var(--pagination-active-bg));
border-color: var(--theme-bg, var(--pagination-active-border-color));
}
&.disabled,
.disabled > & {
color: var(--pagination-disabled-color);
pointer-events: none;
background-color: var(--pagination-disabled-bg);
border-color: var(--pagination-disabled-border-color);
}
}
.page-item {
&:not(:first-child) .page-link {
margin-inline-start: calc(-1 * var(--pagination-border-width));
}
&:first-child {
.page-link {
@include border-start-radius(var(--pagination-border-radius));
}
}
&:last-child {
.page-link {
@include border-end-radius(var(--pagination-border-radius));
}
}
}
//
// Sizing
//
// scss-docs-start pagination-sizes-loop
@each $size, $_ in $pagination-sizes {
.pagination-#{$size} {
--pagination-min-height: var(--btn-input-#{$size}-min-height);
--pagination-padding-y: var(--btn-input-#{$size}-padding-y);
--pagination-padding-x: var(--btn-input-#{$size}-padding-x);
--pagination-font-size: var(--btn-input-#{$size}-font-size);
--pagination-border-radius: var(--btn-input-#{$size}-border-radius);
}
}
@each $size, $_ in $pagination-sizes {
.pagination-#{$size} {
--pagination-min-height: var(--btn-input-#{$size}-min-height);
--pagination-padding-y: var(--btn-input-#{$size}-padding-y);
--pagination-padding-x: var(--btn-input-#{$size}-padding-x);
--pagination-font-size: var(--btn-input-#{$size}-font-size);
--pagination-border-radius: var(--btn-input-#{$size}-border-radius);
}
}