PageLayout

Use the page layout component to define the header, main, pane, and footer areas of a page.
  • Alpha
  • Reviewed for accessibility
import {PageLayout} from '@primer/react'

Examples

See storybook for fullscreen examples.

Default

With dividers

With connected dividers

With pane on left

With pane hidden on narrow viewports

With condensed spacing

With a sticky pane

With a custom sticky header

Add offsetHeader prop to specify the height of the custom sticky header along with sticky prop

With NavList

PageLayout.Pane by itself does not specify or provide landmark roles. Using components that define their own landmark roles, such as NavList, will provide clear structure to the page that is not present by default in PageLayout.Pane.

It's important to note that multiple landmark roles, such as multiple <nav> elements, should be uniquely labelled in order to clarify what the navigation container is used for.

With aria-label

Using aria-label along with PageLayout.Header, PageLayout.Content, or PageLayout.Footer creates a unique label for that landmark role that can make it easier to navigate between sections of content on a page.

With aria-labelledby

Using aria-labelledby along with PageLayout.Header, PageLayout.Content, or PageLayout.Footer creates a unique label for each landmark role by using the given id to associate the landmark with the content with the corresponding id. This is helpful when you have a visible item that visually communicates the type of content which you would like to associate to the landmark itself.

With resizable pane

Accessibility

The PageLayout component uses landmark roles for PageLayout.Header, PageLayout.Content, and PageLayout.Footer in order to make it easier for screen reader users to navigate between sections of the page.

ComponentLandmark role
PageLayout.Headerbanner
PageLayout.Contentmain
PageLayout.Footercontentinfo

Each component may be labeled through either aria-label or aria-labelledby in order to provide a unique label for the landmark. This can be helpful when there are multiple landmarks of the same type on the page.

PageLayout.Pane

The PageLayout.Pane component does not provide a default landmark role as the content of this component may have different roles. When using this component, consider the type of content being rendered inside of PageLayout.Pane and if it requires a landmark role. Common landmark roles include:

Some components, such as NavList may already include a landmark role. In these situation, these components use an appropriate landmark role and no further action is needed when using PageLayout.Pane.

Screen readers

Most screen readers provide a mechanism through which you can navigate between landmarks on the page. Typically, this is done through a specific keyboard shortcut or through an option in a rotor.

JAWS

JAWS supports landmark regions and the details in which it presents them depends on the Web Verbosity Level setting. You can navigate to the next landmark on the page by pressing R and the previous landmark by pressing Shift-R.

NVDA

NVDA supports landmark regions and you can navigate to the next landmark by using pressing D and to the previous landmark by pressing Shift-D. You may also list out the landmarks by pressing Insert-F7.

VoiceOver

VoiceOver supports assigning landmark roles to areas of a page. In order to navigate between landmarks, you can use the rotor.

On macOS, you can open the VoiceOver rotor by pressing VO-U. You can navigate between lists to find the Landmarks list by using the Right Arrow or Left Arrow key. From that list, you can use the Down Arrow and Up Arrow keys to navigate between landmarks identified on the page.

Props

PageLayout

NameTypeDefaultDescription
containerWidth
| 'full' | 'medium' | 'large' | 'xlarge'
'xlarge'

The maximum width of the page container.

padding
| 'none' | 'condensed' | 'normal'
'normal'

The spacing between the outer edges of the page container and the viewport

columnGap
| 'none' | 'condensed' | 'normal'
'normal'
rowGap
| 'none' | 'condensed' | 'normal'
'normal'
sx
SystemStyleObject

PageLayout.Header

NameTypeDefaultDescription
aria-label
string | undefined

A unique label for the rendered banner landmark

aria-labelledby
string | undefined

An id to an element which uniquely labels the rendered banner landmark

padding
| 'none' | 'condensed' | 'normal'
'none'

The amount of padding inside the header.

divider
| 'none' | 'line' | { narrow?: | 'none' | 'line' | 'filled' regular?: | 'none' | 'line' wide?: | 'none' | 'line' }
'none'
dividerWhenNarrow Deprecated
| 'inherit' | 'none' | 'line' | 'filled'
'inherit'

Use the divider prop with a responsive value instead.

hidden
| boolean | { narrow?: boolean regular?: boolean wide?: boolean }
false

Whether the header is hidden.

sx
SystemStyleObject

PageLayout.Content

NameTypeDefaultDescription
aria-label
string | undefined

A unique label for the rendered main landmark

aria-labelledby
string | undefined

An id to an element which uniquely labels the rendered main landmark

width
| 'full' | 'medium' | 'large' | 'xlarge'
'full'

The maximum width of the content region.

padding
| 'none' | 'condensed' | 'normal'
'none'

The amount of padding inside the content.

hidden
| boolean | { narrow?: boolean regular?: boolean wide?: boolean }
false

Whether the content is hidden.

sx
SystemStyleObject

PageLayout.Pane

NameTypeDefaultDescription
aria-label
string | undefined

Label for the pane. Required if the pane overflows and doesn't have aria-labelledby.

aria-labelledby
string | undefined

Id of an element that acts as a label for the pane. Required if the pane overflows and doesn't have aria-label.

position Deprecated
| 'start' | 'end' | { narrow?: | 'start' | 'end' regular?: | 'start' | 'end' wide?: | 'start' | 'end' }
'end'

Use source order instead of relying on the position prop

positionWhenNarrow Deprecated
| 'inherit' | 'start' | 'end'
'inherit'

Use the position prop with a responsive value instead.

width
| 'small' | 'medium' | 'large' | { min: string max: string default: string }
'medium'

The width of the pane. If using custom widths, provide an object with keys 'min', 'max' and 'default'.

minWidth
number
256

The minimum width of the pane.

resizable
boolean
false

When true, the pane may be resized by the user.

widthStorageKey
string
'paneWidth'

Provide a key used by localStorage to persist the size of the pane on the client.

sticky
boolean
false

Whether the pane should stick to the top of the screen while the content scrolls.

offsetHeader
number | string
0

Use offsetHeader along with the sticky prop to push the sticky pane down to make room for a sticky header if necessary. Use the type string to specify the height with a unit i.e. 5rem; otherwise the type number will be taken as px.

padding
| 'none' | 'condensed' | 'normal'
'none'

The amount of padding inside the pane.

divider
| 'none' | 'line' | { narrow?: | 'none' | 'line' | 'filled' regular?: | 'none' | 'line' wide?: | 'none' | 'line' }
'none'
dividerWhenNarrow Deprecated
| 'inherit' | 'none' | 'line' | 'filled'
'inherit'

Use the divider prop with a responsive value instead.

hidden
| boolean | { narrow?: boolean regular?: boolean wide?: boolean }
false

Whether the pane is hidden.

sx
SystemStyleObject
ref
React.RefObject<HTMLDivElement>

A ref to the element rendered by this component.

PageLayout.Footer

NameTypeDefaultDescription
aria-label
string | undefined

A unique label for the rendered contentinfo landmark

aria-labelledby
string | undefined

An id to an element which uniquely labels the rendered contentinfo landmark

padding
| 'none' | 'condensed' | 'normal'
'none'

The amount of padding inside the footer.

divider
| 'none' | 'line' | { narrow?: | 'none' | 'line' | 'filled' regular?: | 'none' | 'line' wide?: | 'none' | 'line' }
'none'
dividerWhenNarrow Deprecated
| 'inherit' | 'none' | 'line' | 'filled'
'inherit'

Use the divider prop with a responsive value instead.

hidden
| boolean | { narrow?: boolean regular?: boolean wide?: boolean }
false

Whether the footer is hidden.

sx
SystemStyleObject

Status

Alpha

  • Component props and basic example usage of the component are documented on primer.style/react.
  • Component does not have any unnecessary third-party dependencies.
  • Component can adapt to different themes.
  • Component can adapt to different screen sizes.
  • Component has robust unit test coverage (100% where achievable).
  • Component has visual regression coverage of its default and interactive states.
  • Component does not introduce any axe violations.
  • Component has been manually reviewed by the accessibility team and any resulting issues have been addressed.

Beta

  • Component is used in a production application.
  • Common usage examples are documented on primer.style/react.
  • Common usage examples are documented in storybook stories.
  • Component has been reviewed by a systems designer and any resulting issues have been addressed.
  • Component does not introduce any performance regressions.

Stable

  • Component API has been stable with no breaking changes for at least one month.
  • Feedback on API usability has been sought from developers using the component and any resulting issues have been addressed.
  • Component has corresponding design guidelines documented in the interface guidelines.
  • Component has corresponding Figma component in the Primer Web library.
  • Tooling (such as linters, codemods, etc.) exists to prevent further use of alternatives.