Page
Consistent page layout with header, content and footer
import Page from "@intility/bifrost-react/Page";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 withnoPadding) - centers and constrains children to
max-width: 1200pxby default
The max-width can be customized with <Page width> prop, here set to 400px:
Header
The <Page.Header> component renders a <header> element with the same padding
and max-width as <Page.Content>, plus:
- A background color
.bfc-base-2-bg(can be removed withnoBackground) - Bottom border
.bf-border-bottom(can be removed withnoBorder)
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.
Footer
<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:
.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.
: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:
.my-banner-content {
max-width: var(--bf-page-width);
margin-inline: auto;
}