# 富元素

> 表格、提示框、标签页、步骤、卡片、徽章、按钮、文件树、主题令牌和布局。

少量 `htmlpress-*` 元素覆盖了 HTML 没有对应元素的场景。它们是轻量 DOM（light DOM）自定义元素，因此其内容仍是普通 HTML，即使在脚本加载之前也能良好阅读。每个元素的样式和脚本只在使用它的页面上引入。在组件中放置块级内容（`<p>`、`<h3>`、`<pre>`），而不是裸文本。

## 表格

`<table>` 会直接应用样式，带有 `<thead>` 的表格点击任意表头即可按该列排序：

**HTML**

```html
<table>
  <thead><tr><th>Language</th><th>Year</th><th>Typing</th></tr></thead>
  <tbody><tr><td>TypeScript</td><td>2012</td><td>Static</td></tr>…</tbody>
</table>
```

**Markdown**

```md
| Language | Year | Typing |
| --- | --- | --- |
| TypeScript | 2012 | Static |
```

渲染为：

| 语言         | 年份   | 类型系统 |
| ---------- | ---- | ---- |
| TypeScript | 2012 | 静态   |
| Python     | 1991 | 动态   |
| Rust       | 2010 | 静态   |
| JavaScript | 1995 | 动态   |

## 提示框

提示框用于突出重要信息。`type` 可以是 `info`（默认）、 `note`、`tip`、`warning` 或 `danger`，`title` 会替换该类型自带的标题：

**HTML**

```html
<htmlpress-callout><p>This is a note.</p></htmlpress-callout>

<htmlpress-callout type="warning" title="Breaking Change">
  <p>This API has been removed in v2.</p>
</htmlpress-callout>
```

**Markdown**

```md
:::info
This is a note.
:::

:::warning[Breaking Change]
This API has been removed in v2.
:::
```

渲染为：

> **Info**
>
> 这是一条注释。

> **Tip**
>
> 所有页面均已构建。

> **Warning**
>
> 使用时请小心。

> **Danger**
>
> 切勿编辑 `.htmlpress/build`：每次构建都会替换它。

> **破坏性变更**
>
> 此 API 已在 v2 中移除。

提示框内的标题不会进入页面目录。

## 可展开内容

无需组件：主题会为普通的 `<details>` 设置样式。

**HTML**

```html
<details>
  <summary>Click to expand</summary>
  <p>Hidden content here with <strong>HTML</strong> support.</p>
</details>
```

**Markdown**

```md
:::details[Click to expand]
Hidden content here with **Markdown** support.
:::
```

渲染为：

点击展开

这里是隐藏的内容，支持 **HTML**。

其中可以嵌套任何 HTML，包括代码块、列表和提示框：

配置示例

```yaml
site: https://htmlpress.dev
title: Htmlpress
```

## 代码标签页

只包含代码块的标签页会合并为一个带边框的块。每个 `<section>` 是一个标签页，以其 `title` 命名：

**HTML**

```html
<htmlpress-tabs sync="lang">
  <htmlpress-tab title="JavaScript"><pre><code>console.log("hello")</code></pre></htmlpress-tab>
  <htmlpress-tab title="Python"><pre><code>print("hello")</code></pre></htmlpress-tab>
</htmlpress-tabs>
```

**Markdown**

````md
```js tab="JavaScript" sync="lang"
console.log("hello")
```

```python tab="Python"
print("hello")
```
````

渲染为：

**JavaScript**

```
console.log("hello")
```

**Python**

```
print("hello")
```

添加 `sync="key"` 可让多个标签页组保持同步，详见下文“内容标签页”。

## 内容标签页

用 `<htmlpress-tabs>` 把任意内容分组为标签页，每个标签页对应一个 `<htmlpress-tab title>`。

添加 `sync` 属性可在多个标签页组之间同步选中状态。当读者在某个组中选择一个标签页时，所有具有相同 `sync` 键的其他组都会切换到对应的标签页，并且该选择会通过 `localStorage` 在页面之间记住。

**HTML**

```html
<htmlpress-tabs sync="channel">
  <htmlpress-tab title="cargo"><p>From crates.io, built on your machine.</p></htmlpress-tab>
  <htmlpress-tab title="npm"><p>A prebuilt binary per platform.</p></htmlpress-tab>
  <htmlpress-tab title="pip"><p>A binary wheel.</p></htmlpress-tab>
</htmlpress-tabs>
```

**Markdown**

```md
:::tab{title="cargo" sync="channel"}
From crates.io, built on your machine.
:::

:::tab{title="npm"}
A prebuilt binary per platform.
:::

:::tab{title="pip"}
A binary wheel.
:::
```

渲染为（两个组共享 `sync="channel"`；切换其中一个试试）：

**cargo**

```sh
cargo install htmlpress
```

**npm**

```
npm install -g gethtmlpress
```

**pip**

```sh
pip install htmlpress
```

**cargo**

来自 crates.io，在你的机器上构建。

**npm**

每个平台一个预构建的二进制文件。

**pip**

一个二进制 wheel。

## 步骤

带 `data-step` 的标题是一个带编号的步骤，步骤在整个页面中依次计数； 其内容照常跟在后面。这些标题不会进入页面目录。

**HTML**

```html
<h3 data-step>Install</h3>
<p>…</p>
<h3 data-step>Write a page</h3>
<p>…</p>
```

**Markdown**

```md
### Install [step]

…

### Write a page [step]

…
```

渲染为：

### 安装

从上面的标签页中选择一个渠道。

### 编写页面

文件夹中的任意 `.html` 文件。

### 启动

运行 `htmlpress start` 并打开它输出的 URL。

## 卡片

`<htmlpress-cards>` 中的卡片排成两列，窄屏时为一列。卡片的 `title` 是它的标题，`href` 让整张卡片可点击，`icon` 以强调色显示在标题前，卡片的内容就是它的正文。

**HTML**

```html
<htmlpress-cards>
  <htmlpress-card title="Getting Started" href="/introduction/" icon="rocket">
    <p>Learn how to set up your first project.</p>
  </htmlpress-card>
  <htmlpress-card title="Plain HTML"><p>…</p></htmlpress-card>
</htmlpress-cards>
```

**Markdown**

```md
:::card{title="Getting Started" href="/introduction/" icon="rocket"}
Learn how to set up your first project.
:::

:::card{title="Plain HTML"}
…
:::
```

渲染为：

### [快速开始](/zh/introduction/)

了解如何搭建你的第一个项目。

### [配置](/zh/customization/configuration-file/)

配置你的 htmlpress 项目。

### [GitHub](https://github.com/datisthq/htmlpress)

在 GitHub 上查看源代码。

### 纯 HTML

没有链接的卡片不可点击。

卡片内的标题不会进入页面目录。

## 徽章

行内标签。`variant` 为 `secondary` 或 `outline` 时样式更朴素，为 `positive`、`warning` 或 `destructive` 时带有色调；不设置时使用强调色。

**HTML**

```html
<htmlpress-badge>New</htmlpress-badge>
<htmlpress-badge variant="positive">Stable</htmlpress-badge>
```

**Markdown**

```md
:badge[New] :badge[Stable]{variant="positive"}
```

渲染为： 新 次要 稳定 测试版 已移除 描边

## 按钮

`<htmlpress-button href label>` 是一个链接到其 `href` 的行动号召按钮。`variant` 为 `secondary`、`outline`、 `ghost` 或 `link` 时更低调，为 `positive`、 `warning` 或 `destructive` 时带有色调；`size` 可以是 `sm` 或 `lg`。

**HTML**

```html
<htmlpress-button href="/introduction/" label="Get Started"></htmlpress-button>
<htmlpress-button href="…" label="GitHub" variant="secondary"></htmlpress-button>
```

**Markdown**

```md
::button[Get Started]{href="/introduction/"}

::button[GitHub]{href="…" variant="secondary"}
```

渲染为：

[快速开始](/zh/introduction/) [GitHub](https://github.com/datisthq/htmlpress) [描边](#按钮) [链接](#按钮)

## 图标

`<htmlpress-icon name="…">` 以行内方式绘制一个内置的 [Lucide](https://lucide.dev) 图标，使用文本的颜色和大小；同样的名称也可用于链接或分区的 `icon`。未知的名称会导致构建失败。以下是全部 114 个内置图标：

**HTML**

```html
<htmlpress-icon name="rocket"></htmlpress-icon> Get started
```

**Markdown**

```md
:icon{name="rocket"} Get started
```

activity

archive

arrow-right

badge-check

bell

blocks

book

book-marked

book-open

book-text

bookmark

bot

box

braces

brain

bug

calendar

chart-column

check

circle-help

clock

cloud

cloud-upload

code

codepen

coffee

compass

cpu

database

download

external-link

feather

figma

file

file-code

file-pen-line

file-text

flag

flask-conical

folder

git-branch

git-commit-horizontal

git-pull-request

github

gitlab

globe

graduation-cap

hammer

heading

heart

heart-handshake

history

house

image

info

key

layers

layout-grid

layout-panel-left

library

life-buoy

lightbulb

link

linkedin

list

lock

mail

map

megaphone

message-circle

monitor

newspaper

notebook-pen

package

palette

pencil

pencil-ruler

play

plug

presentation

puzzle

rocket

route

rss

scale

scroll

search

server

settings

shield

sliders-horizontal

smartphone

sparkles

square-dashed

square-stack

star

table

tag

terminal

triangle

trophy

twitter

type

upload

user

users

video

webhook

wind

workflow

wrench

x

youtube

zap

## 文件树

`<htmlpress-filetree>` 中的嵌套列表；包含列表的项即为文件夹。

**HTML**

```html
<htmlpress-filetree>
  <ul>
    <li>docs<ul><li>index.html</li></ul></li>
    <li>htmlpress.yaml</li>
  </ul>
</htmlpress-filetree>
```

**Markdown**

```md
:::filetree
- docs
  - index.html
- htmlpress.yaml
:::
```

渲染为：

- docs

  - index.html
  - guides
    - build.html

- htmlpress.yaml

## 分栏

`<htmlpress-columns>` 把子元素并排布局，默认两列，用 `cols` 最多四列，每个 `<htmlpress-column>` 是一列：

**HTML**

```html
<htmlpress-columns cols="2">
  <htmlpress-column><p><strong>Left column</strong> with content.</p></htmlpress-column>
  <htmlpress-column><p><strong>Right column</strong> with more content.</p></htmlpress-column>
</htmlpress-columns>
```

**Markdown**

```md
:::column
**Left column** with content.
:::

:::column
**Right column** with more content.
:::
```

渲染为：

**左栏**包含内容，包括列表：

- 第一项
- 第二项

**右栏**包含更多内容：

> 引用块在这里同样可用。

## 主题令牌

颜色、字体和宽度都是 `:root` 上的 CSS 自定义属性，在 `prefers-color-scheme` 或页眉的主题切换下有一套深色值： `--htmlpress-accent`、`--htmlpress-accent-text`、 `--htmlpress-banner`、`--htmlpress-banner-text`、 `--htmlpress-highlight`、`--htmlpress-highlight-text`、 `--htmlpress-bg`、`--htmlpress-surface`、 `--htmlpress-text`、`--htmlpress-muted`、 `--htmlpress-border`、`--htmlpress-info`、 `--htmlpress-success`、`--htmlpress-warning`、 `--htmlpress-danger`、`--htmlpress-font`、 `--htmlpress-mono`、`--htmlpress-radius`、 `--htmlpress-shadow`、`--htmlpress-width` 和 `--htmlpress-nav-width`。可在页面自己的样式表中覆盖它们：

```
:root {
  --htmlpress-accent: oklch(0.6 0.18 30);
  --htmlpress-font: "Inter", system-ui, sans-serif;
  --htmlpress-width: 52rem;
}
```

## 布局

布局就是普通 HTML。Htmlpress 会填充它的 `<head>`（字符集、视口、标题、描述、社交预览标签、规范链接、favicon、主题、页面所用组件的样式和脚本、`htmlpress.yaml` 中的 `head` 标签，最后是页面自己的 head 标签），并在构建时替换以下元素：

- `<htmlpress-content>`

  页面内容。

- `<htmlpress-brand>`

  站点标题及其下方的 `description`，设置了 `logo` 时位于其后，链接到首页。

- `<htmlpress-banner>`

  `htmlpress.yaml` 中的 `banner`。

- `<htmlpress-breadcrumbs>`

  首页、页面之上的每个文件夹（有索引页时以索引页命名并链接到它），然后是页面本身。

- `<htmlpress-nav>`

  当前打开分区的页面（未设置 `sections` 时为所有页面），在“文章”标签下按顶层文件夹分组（博客中为“文章”，更新日志中为“版本”）；文件夹的分组以其索引页命名并链接到它。侧边栏分区位于其开头，侧边栏 `links` 位于其末尾，归在“链接”之下。

- `<htmlpress-links>`

  页眉分区（标记当前打开的分区），然后是 `htmlpress.yaml` 中的页眉 `links`。

- `<htmlpress-page-toc>`

  页面的 `<h2>` 和 `<h3>`，并高亮当前可见的那个。没有 `id` 的标题会根据其文本获得一个 ID。

- `<htmlpress-pager>`

  按导航顺序排列的上一页和下一页。

- `<htmlpress-edit>`

  根据 `htmlpress.yaml` 中的 `edit` 生成的“编辑此页”链接。

- `<htmlpress-search>`

  借助脚本搜索所有页面：页眉中的一个按钮，也可以通过 `S`、`/` 或 `⌘K` / `Ctrl K` 打开。构建会把索引写入 `_htmlpress/search.json`，并在每个页面的标题处拆分，对话框在首次打开时加载它。查询中的任一词语都可匹配；结果会以 `?highlight=` 加查询打开其页面，匹配处用 `--htmlpress-highlight` 标出并滚动到可见位置。宽度小于 56rem 时，搜索框会占据页眉而不是弹出对话框。

- `<htmlpress-toolbar>`

  指向页面 Markdown 副本的链接；脚本会添加“复制 Markdown”“在 ChatGPT 中打开”和“在 Claude 中打开”。

- `<htmlpress-footer>`

  “用 Htmlpress 构建”的署名。

- `<htmlpress-language>`

  语言选择器，链接到本页面的各语言版本，以下拉菜单显示，在手机上则以底部面板显示；仅在启用了 [翻译](/zh/customization/translations/)的站点上显示。

- `<htmlpress-shortcuts>`

  页眉中的键盘快捷键菜单，需要脚本，列出所有按键并禁用本页面不可用的按键，例如没有下一页时禁用 `L`；点击某一行也会触发该按键。宽度小于 56rem 时隐藏，因为没有键盘可用。

- `<htmlpress-skip>`

  “跳到正文”链接，仅在获得焦点时显示。

这些元素及其脚本显示的所有字符串都使用页面的语言。脚本从 htmlpress 写入 head 的 `<script type="application/json" id="htmlpress-messages">` 中读取字符串，缺少它时回退为英语。

没有内容可显示的元素会被移除。 `<htmlpress-nav-toggle>`（在手机上把侧边栏变为抽屉；在更宽的屏幕上则折叠侧边栏并记住该状态）、 `<htmlpress-theme-toggle>`（浅色、深色和系统选择的菜单，以下拉菜单显示，在手机上则以底部面板显示）和 `<htmlpress-back-to-top>` 由脚本在浏览器中构建。它们的快捷键与 Livemark 一致：`M` 切换侧边栏，`T` 在浅色和深色之间切换， `U` 返回顶部，而 `J` 和 `K` 可在任何页面上向下和向上滚动，`D` 跳到底部。页面上有 `<htmlpress-pager>` 时，`L` 和 `H` 前往下一页和上一页。在输入框中输入时，这些快捷键都不会触发。

手机上的每个底部面板（目录、主题、语言和侧边栏的栏目选择）都是同一个由脚本添加到 body 的 `<htmlpress-sheet>`。向下滑动、点击背景、按 `Esc` 或点击关闭按钮都会关闭它，因此转义 `components/sheet/sheet.css` 即可为所有面板重新设置样式。

它们周围的框架同样由元素构成。这些元素本身不包含内容，只负责为其中的内容设置样式和定位，因此布局可以保留需要的元素，并以属性的形式为它们赋予地标角色：

- `<htmlpress-shell>`

  侧边栏与其余部分并排；在手机上堆叠排列。

- `<htmlpress-sidebar>`

  品牌和导航；在手机上为抽屉。

- `<htmlpress-main>`

  侧边栏旁边的栏。

- `<htmlpress-header>`

  顶部的粘性栏，仅在手机上显示品牌和菜单按钮。

- `<htmlpress-page>`

  它包含的 `<main>` 与侧栏并排。

- `<htmlpress-aside>`

  内容旁边的栏，为空或屏幕较窄时隐藏。

项目中的 `.htmlpress/layout.html` 会替换内置布局，页面也可以从 `.htmlpress/layouts/` 中选择自己的布局。每个组件的样式和脚本都可以用同样的方式替换或添加：见 [覆盖/弹出](/zh/customization/overriding-escaping/)。
