Skip to main content
/
/
/
Page

Page

Consistent page layout with header, content and footer

React
import Page from "@intility/bifrost-react/Page";
Props

Basic layout

The base <Page> component supplies an outer framework for laying out page sections.

The <Page.Content> component:

  • applies responsive .bf-page-padding (remove top and bottom padding with noPadding)
  • centers and constrains children to max-width: 1200px by default

The max-width can be customized with <Page width> prop, here set to 400px:

I am a Box placed inside Page.Content

The <Page.Header> component renders a <header> element with the same padding and max-width as <Page.Content>, plus:

Note that the background stretches to full width regardless of <Page width>.

A standard header layout contains <Breadcrumbs> and a <h1> with 12px gap, optionally followed by a description paragraph with a 8px gap and .bf-large font size.

Header with illustration

To add an illustration to the header, use <Page.Header noPadding> and apply .bf-page-header-padding-y to the text content, so the illustration can reach the top and bottom edges of the header.

For this specific illustration, we've placed the image with alignSelf: "end" so it sits on the bottom edge even if the description could wrap multiple lines.

Toolbar

<Page.Toolbar> is a slim bar for page-level actions, placed directly after <Page.Header>. Like the header it has a .bfc-base-2-bg background (can be removed with noBackground), .bf-border-bottom (can be removed with noBorder) and content constrained to the page width, but with less vertical padding.

When a toolbar or tabs follow the header, the header's bottom padding shrinks by 12px (but never below 12px), so the two sit closer together.

The <Inline> component can be useful to lay out the buttons.

Toolbar also works with an illustrated header.

Tabs

<Page.Tabs> renders page-level navigation tabs between <Page.Header> and <Page.Content>. It uses the same styling as Tabs, and overflowing tabs become horizontally scrollable.

Children are plain links (or router links, such as <Link> from your router). Mark the current tab with the active class. <Page.Tabs> only handles presentation and navigation, so render the content of the active tab inside <Page.Content> yourself, for example one route per tab.

Tabs also work with an illustrated header.

Toolbar and tabs

<Page.Toolbar> and <Page.Tabs> can be combined. Place the toolbar first, then the tabs.

<Page.Footer> sticks to the bottom of the viewport when page content is shorter than the viewport, and gets pushed down as normal flow content once the page content grows taller than the viewport.

Unlike <Page.Header> and <Page.Content>, which can be used on their own, <Page.Footer> only works when nested inside <Page>. Once a page uses a footer, place <Page.Header> and <Page.Content> inside that same <Page> too — the sticky behavior is applied to <Page> as a whole, so mixing footer inside <Page> with header/content loose outside of it will break the layout.

With a footer, <Page> becomes a flex column. Place inline elements (like a bare <img>) inside a sub-component rather than directly in <Page>.

To add a status message to a page with a footer, place it inside <Page>, so it's included in the sticky-footer height calculation:

The sticky calculation only accounts for the fixed top nav bar height, so <Page> assumes it can fill the rest of the viewport on its own. Placing the message — or anything else of unknown height — outside <Page> instead makes the page taller than the viewport, so the footer won't stick to the bottom.

Inner elements

Each sub-component wraps its children in an inner .bf-page-inner element that is centered and constrained to the page width. Target it when you need to style the constrained area, for instance to make it a flex or grid container:

CSS
.my-header > .bf-page-inner {
  display: flex;
  gap: 16px;
}

Global width

The --bf-page-width CSS variable holds the page max-width. It defaults to 1200px, and accepts any length, percentage, or none for full width.

The variable is inherited, so set it on :root (or any other ancestor) to change the default for every <Page> inside it. The <Page width> prop sets the variable on that page only, and takes precedence.

CSS
:root {
  --bf-page-width: 1000px;
  /* or full width: */
  /* --bf-page-width: none; */
}

--bf-page-width also works outside <Page>, so other layouts can line up with page content:

CSS
.my-banner-content {
  max-width: var(--bf-page-width);
  margin-inline: auto;
}