# 页面布局

`Layout` 组件把标题栏、侧边栏、正文和本页目录摆在页面上，并处理不同屏幕宽度下的变化。不需要的部分可以不写，想完全自己写布局时也可以不用它们。

## 完整的例子

```astro
---
import { Layout, Prose, Sidebar, Toc } from '@minidocs/astro/components';
import '@minidocs/astro/styles.css';
---

<html lang="zh">
  <body>
    <Layout.Root>
      <Layout.Header>
        <Layout.Title href="/docs/">我的文档</Layout.Title>
        <nav slot="end">...</nav>
      </Layout.Header>

      <Sidebar.Trigger target="sidebar" aria-label="菜单">
        <svg width="16" height="16" viewBox="0 0 16 16" aria-hidden="true">
          <path d="M2 4h12M2 8h12M2 12h12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" />
        </svg>
      </Sidebar.Trigger>

      <Layout.Sidebar>
        <Sidebar.Root id="sidebar" label="文档">...</Sidebar.Root>
      </Layout.Sidebar>

      <Layout.Main>
        <Prose>
          <h1>{entry.data.title}</h1>
          <Content />
        </Prose>
      </Layout.Main>

      <Layout.Aside title="本页目录">
        <Toc.Root>...</Toc.Root>
      </Layout.Aside>
    </Layout.Root>
  </body>
</html>
```

| 组件               | 渲染为         | 作用                                 |
| ---------------- | ----------- | ---------------------------------- |
| `Layout.Root`    | `<div>`     | 整个页面                               |
| `Layout.Header`  | `<header>`  | 固定在顶部的标题栏。默认 slot 靠左，`end` slot 靠右 |
| `Layout.Title`   | `<a>`       | 标题栏里的站点名称或 logo                    |
| `Layout.Sidebar` | `<aside>`   | 放侧边栏的一栏                            |
| `Layout.Main`    | `<main>`    | 放正文的一栏                             |
| `Layout.Aside`   | `<details>` | 放本页目录的一栏，`title` 是它的标题             |
| `Prose`          | `<article>` | 给 Markdown 正文排版                    |

## 不同宽度下的样子

| 宽度            | 布局                                      |
| ------------- | --------------------------------------- |
| 75rem 以上      | 三栏：侧边栏、正文、本页目录                          |
| 50rem 到 75rem | 两栏：侧边栏、正文。本页目录收进正文右上方的一个按钮，点击后展开        |
| 50rem 以下      | 一栏。侧边栏变成从左侧滑出的抽屉，由 `Sidebar.Trigger` 打开 |

收起后的本页目录按钮会显示当前读到的小节和阅读进度。`Sidebar.Trigger` 只在窄屏下显示，宽屏时不需要隐藏它。

宽屏下，没有本页目录的页面也会留出右边那一栏，这样侧边栏和正文在每一页的位置都一样。如果整个站点都不用本页目录，可以改成两栏：

```css
@media (width > 75rem) {
  .md-layout {
    grid-template-columns:
      [full-start] minmax(0, 1fr)
      [content-start] var(--md-layout-sidebar-width) minmax(0, var(--md-layout-main-width))
      [content-end] minmax(0, 1fr) [full-end];
    grid-template-areas:
      "header header header header"
      ". sidebar main .";
  }
}
```

## 页面本身

用了 `Layout.Root` 时，默认样式还会设置页面的背景色、文字颜色和字体，并让页面跟随系统的深浅色。

## 修改断点

两个断点 `50rem` 和 `75rem` 写在 `@minidocs/astro/styles/layout.css` 里，不能通过变量修改。想用别的断点，就不引入这个文件，自己写布局的样式，见[样式](/docs/guides/styling.md#%E9%80%89%E6%8B%A9%E6%A0%B7%E5%BC%8F%E6%96%87%E4%BB%B6)。在你希望本页目录收起的宽度，把 `--md-layout-aside-collapsible` 设成 `1`，`Layout.Aside` 就会变成可以展开的按钮。
