Page

The skeleton of a page's content, with a header, body and aside.

Galgame

サクラノ詩

Makura · 2015-10-23 · Written by Sca-ji

The synopsis and details go here.

PageBody sets the spacing between sections.

<script setup lang="ts">
  import { Button, Card, NavLink, Page, PageAside, PageBody, PageHeader, Text } from '@hina-ui/vue'
</script>

<template>
  <Card :padded="false" class="w-full overflow-hidden">
    <Page size="lg">
      <PageHeader
        eyebrow="Galgame"
        title="サクラノ詩"
        description="Makura · 2015-10-23 · Written by Sca-ji"
      >
        <template #actions>
          <Button variant="soft" tone="neutral" size="sm">Favourite</Button>
          <Button size="sm">Mark as playing</Button>
        </template>
      </PageHeader>

      <PageBody>
        <Text size="sm" tone="muted">The synopsis and details go here.</Text>
        <Text size="sm" tone="muted">PageBody sets the spacing between sections.</Text>
      </PageBody>

      <template #aside>
        <PageAside label="On this page">
          <NavLink href="#" label="Overview">Overview</NavLink>
          <NavLink href="#" label="Characters">Characters</NavLink>
          <NavLink href="#" label="Staff">Staff</NavLink>
        </PageAside>
      </template>
    </Page>
  </Card>
</template>
vue

Usage

import { Page, PageAside, PageBody, PageHeader } from '@hina-ui/vue'
ts

Page is the container for a page’s content and handles the maximum width, centring and vertical padding. PageHeader is the title region, PageBody the main content and PageAside the secondary column on the right, passed through the aside slot.

Page and AppShell work at two different levels: AppShell divides the sidebar, top bar and main area, while Page structures what sits inside that main area. They stack, and either can be used alone.

My shelf

48 titles collected.

Page content.

<script setup lang="ts">
  import { Card, Page, PageBody, PageHeader, Text } from '@hina-ui/vue'
</script>

<template>
  <Card :padded="false" class="w-full overflow-hidden">
    <Page size="sm">
      <PageHeader title="My shelf" description="48 titles collected." />
      <PageBody>
        <Text size="sm" tone="muted">Page content.</Text>
      </PageBody>
    </Page>
  </Card>
</template>
vue

The title on PageHeader renders as the page’s top-level heading, so a page should hold only one PageHeader.

size sets the maximum width of the content and passes through to the underlying Container: sm is 48rem, md 64rem, lg 72rem and xl 80rem, defaulting to md. Long-form reading wants a narrower step; a detail page with an aside wants a wider one.

Examples

Aside

PageAside suits an in-page contents list, related entries and similar secondary content. It sticks to the top as the page scrolls and is hidden entirely below a viewport width of 1280 pixels, so nothing that exists only here may go in it.

label renders as the aside’s small heading and doubles as the accessible name of the region.

Staff

Main column. The aside is hidden below a viewport width of 1280 pixels.

<script setup lang="ts">
  import { Card, NavLink, Page, PageAside, PageBody, PageHeader, Text } from '@hina-ui/vue'
</script>

<template>
  <Card :padded="false" class="w-full overflow-hidden">
    <Page size="lg">
      <PageHeader title="Staff" />
      <PageBody>
        <Text size="sm" tone="muted">
          Main column. The aside is hidden below a viewport width of 1280 pixels.
        </Text>
      </PageBody>

      <template #aside>
        <PageAside label="Related">
          <NavLink href="#" label="Same brand">Same brand</NavLink>
          <NavLink href="#" label="Same writer">Same writer</NavLink>
        </PageAside>
      </template>
    </Page>
  </Card>
</template>
vue

Behaviour

  • Direct children of Page are spaced 8 units apart, and children of PageBody 6 units apart.
  • The aside sits beside the main column, which takes the remaining width, with 10 units between them.
  • The aside sticks to the top of the container and stays in view while the page scrolls.
  • From medium screens up the header moves its actions to the right of the title; on narrow screens they wrap underneath.

Accessibility

  • PageHeader renders as header and PageAside as an aside landmark.
  • title is the page’s top-level heading and should appear only once per page.
  • Given a label, PageAside generates a second-level heading and links it with aria-labelledby, so several asides can be told apart in a screen reader’s landmark list.
  • The aside is hidden on narrow screens, so its content must be reachable elsewhere too.

API

Page

Prop
Type
Default
Description
size
'sm' | 'md' | 'lg' | 'xl'
'md'
Maximum width of the content
class
string
—
Classes appended to the root
Slot
Description
default
Content of the main column
aside
The secondary column on the right

PageHeader

Prop
Type
Default
Description
eyebrow
string
—
Small line above the title
title
string
—
Page title, rendered as the top-level heading
description
string
—
Sentence beneath the title
class
string
—
Classes appended to the root
Slot
Description
default
Content at the end of the header
actions
Page-level actions

PageBody

Prop
Type
Default
Description
class
string
—
Classes appended to the root
Slot
Description
default
Main content

PageAside

Prop
Type
Default
Description
label
string
—
Small heading, doubling as the accessible name
class
string
—
Classes appended to the root
Slot
Description
default
Content of the aside