Layout
The Elements layout system provides a declarative approach to creating layouts using CSS flexbox and grid. This system enables complex, adaptive layouts with minimal markup and custom CSS.
Installation
The layout system is part of the core Elements styles package:
npm install @nvidia-elements/styles @nvidia-elements/themes
npm install @nvidia-elements/styles @nvidia-elements/themes
/* Import the layout CSS into your project */
@import '@nvidia-elements/styles/dist/layout.css';
/* Import the layout CSS into your project */
@import '@nvidia-elements/styles/dist/layout.css';
The base layout system provides static layouts. For responsive behavior, the team plans extra modules for container and viewport breakpoint-based responsive design.
Layout System Overview
The nve-layout attribute provides a unified API for three layout modes:
Each layout mode supports spacing, alignment, and responsive behavior through a consistent syntax.
<!-- Simple horizontal layout with spacing -->
<div nve-layout="row gap:sm">
<nve-button>Save</nve-button>
<nve-button>Cancel</nve-button>
<nve-button>Delete</nve-button>
</div>
<!-- Centered vertical layout with padding -->
<section nve-layout="column gap:md pad:lg align:center">
<h2>Welcome</h2>
<p>Create beautiful layouts with ease</p>
<nve-button>Get Started</nve-button>
</section>
<!-- Responsive grid layout using semantic HTML -->
<section nve-layout="grid gap:md span-items:3 pad:xl">
<nve-card>Feature 1</nve-card>
<nve-card>Feature 2</nve-card>
<nve-card>Feature 3</nve-card>
</section>
<!-- Simple horizontal layout with spacing -->
<div nve-layout="row gap:sm">
<nve-button>Save</nve-button>
<nve-button>Cancel</nve-button>
<nve-button>Delete</nve-button>
</div>
<!-- Centered vertical layout with padding -->
<section nve-layout="column gap:md pad:lg align:center">
<h2>Welcome</h2>
<p>Create beautiful layouts with ease</p>
<nve-button>Get Started</nve-button>
</section>
<!-- Responsive grid layout using semantic HTML -->
<section nve-layout="grid gap:md span-items:3 pad:xl">
<nve-card>Feature 1</nve-card>
<nve-card>Feature 2</nve-card>
<nve-card>Feature 3</nve-card>
</section>
Apply Layout to Native HTML Elements
Elements components use Web Components with Shadow DOM encapsulation. Many components manage their own internal layout, for example: nve-card components have built-in layout for nve-card-header, nve-card-content, and nve-card-footer. Applying nve-layout directly to these components may not work as expected due to Shadow DOM boundaries.
Apply the nve-layout attribute to native HTML elements rather than Elements components. Use semantic HTML elements like <section>, <main>, <nav>, <aside>, or generic containers like <div> as your layout containers. Similarly, form components have built-in layout capabilities.
For more details, see the documentation on the internal-host pattern and slots which the library uses in development, as well as MDN docs on the Shadow DOM.
<!-- ✓ Correct: Apply to native HTML elements -->
<section nve-layout="row gap:md">
<nve-card>Card 1</nve-card>
<nve-card>Card 2</nve-card>
</section>
<!-- ✗ Incorrect: Don't apply directly to Elements components -->
<nve-card nve-layout="row gap:md">
Content...
</nve-card>
<!-- ✓ Correct: Apply to native HTML elements -->
<section nve-layout="row gap:md">
<nve-card>Card 1</nve-card>
<nve-card>Card 2</nve-card>
</section>
<!-- ✗ Incorrect: Don't apply directly to Elements components -->
<nve-card nve-layout="row gap:md">
Content...
</nve-card>
When to Use Each Layout Type
Use Horizontal Layout (row) when:
- Arranging items side-by-side (navigation bars, button groups, toolbars)
- Creating inline forms or control groups
- Building card layouts that flow horizontally
- Aligning items along a single horizontal axis
Use Vertical Layout (column) when:
- Stacking content vertically (forms, card content, sidebars)
- Creating centered hero sections or landing pages
- Building mobile-first layouts that stack naturally
- Organizing content in a top-to-bottom flow
Use Grid Layout (grid) when:
- Creating multi-column layouts (dashboards, galleries)
- Building complex page structures with precise control
- Implementing magazine-style layouts
- Needing both row and column control simultaneously
Core Features
The layout system provides consistent features across all layout types:
Gap Spacing
Control the space between elements using t-shirt sizing values that maintain visual consistency:
gap:none gap:xxs gap:xs gap:sm gap:md gap:lg gap:xl gap:xxl
Gap xxs
<section nve-layout="row gap:xxs">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
<section nve-layout="row gap:xxs">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
Gap xs
<section nve-layout="row gap:xs">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
<section nve-layout="row gap:xs">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
Gap sm
<section nve-layout="row gap:sm">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
<section nve-layout="row gap:sm">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
Gap md
<section nve-layout="row gap:md">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
<section nve-layout="row gap:md">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
Gap lg
<section nve-layout="row gap:lg">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
<section nve-layout="row gap:lg">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
Gap xl
<section nve-layout="row gap:xl">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
<section nve-layout="row gap:xl">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
Gap xxl
<section nve-layout="row gap:xxl">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
<section nve-layout="row gap:xxl">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
No Gap
<section nve-layout="row gap:none">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
<section nve-layout="row gap:none">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
Padding
Add internal spacing to containers using the same t-shirt sizing system:
pad:none pad:xxs pad:xs pad:sm pad:md pad:lg pad:xl pad:xxl
By default padding applies to all 4 sides of container, to specify padding on a single side use:
pad-top:md pad-right:md pad-bottom:md pad-left:md
Or use the short hand to just pad the x and y axes.
<section nve-layout="row pad-left:md">
<section nve-layout="row pad-left:md">
Padding Top
<section nve-layout="row gap:sm align:stretch pad-top:xxl">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
<section nve-layout="row gap:sm align:stretch pad-top:xxl">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
Padding Left
<section nve-layout="row gap:sm align:stretch pad-left:xxl">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
<section nve-layout="row gap:sm align:stretch pad-left:xxl">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
Padding Right
<section nve-layout="row gap:sm align:stretch pad-right:xxl">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
<section nve-layout="row gap:sm align:stretch pad-right:xxl">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
Padding Bottom
<section nve-layout="row gap:sm align:stretch pad-bottom:xxl">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
<section nve-layout="row gap:sm align:stretch pad-bottom:xxl">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
Padding X
<section nve-layout="row gap:sm align:stretch pad-x:xxl">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
<section nve-layout="row gap:sm align:stretch pad-x:xxl">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
Padding Y
<section nve-layout="row gap:sm align:stretch pad-y:xxl">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
<section nve-layout="row gap:sm align:stretch pad-y:xxl">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
Padding xxs
<section nve-layout="row gap:sm align:stretch pad:xxs">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
<section nve-layout="row gap:sm align:stretch pad:xxs">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
Padding xs
<section nve-layout="row gap:sm align:stretch pad:xs">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
<section nve-layout="row gap:sm align:stretch pad:xs">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
Padding sm
<section nve-layout="row gap:sm align:stretch pad:sm">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
<section nve-layout="row gap:sm align:stretch pad:sm">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
Padding md
<section nve-layout="row gap:sm align:stretch pad:md">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
<section nve-layout="row gap:sm align:stretch pad:md">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
Padding lg
<section nve-layout="row gap:sm align:stretch pad:lg">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
<section nve-layout="row gap:sm align:stretch pad:lg">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
Padding xl
<section nve-layout="row gap:sm align:stretch pad:xl">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
<section nve-layout="row gap:sm align:stretch pad:xl">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
Padding xxl
<section nve-layout="row gap:sm align:stretch pad:xxl">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
<section nve-layout="row gap:sm align:stretch pad:xxl">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
No Padding
<section nve-layout="row gap:sm align:stretch pad:none">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
<section nve-layout="row gap:sm align:stretch pad:none">
<nve-card></nve-card><nve-card></nve-card><nve-card></nve-card>
</section>
Gap affects space between child elements, while padding affects space inside the container. Use gap for consistent spacing between items and padding for breathing room around content.
Full width/height on container
For convenience you can set a full option to give the container 100% width & height. This is often useful for giving the root element of a page full height.
<section nve-layout="full">
<section nve-layout="full">
<section nve-layout="full">
<nve-card></nve-card>
</section>
<section nve-layout="full">
<nve-card></nve-card>
</section>
Layout Composition
You can compose layout attributes to create sophisticated designs:
<!-- Centered hero section with vertical layout -->
<section nve-layout="column gap:lg pad:xxl align:center full">
<nve-logo size="xl"></nve-logo>
<h1 nve-text="heading xl">Build Faster</h1>
<p nve-text="lg muted">Create stunning layouts without writing CSS</p>
<div nve-layout="row gap:sm">
<nve-button variant="primary">Start Building</nve-button>
<nve-button>Learn More</nve-button>
</div>
</section>
<!-- Complex dashboard layout using semantic HTML -->
<div nve-layout="row gap:md pad:lg align:horizontal-stretch full">
<aside style="width: 250px">
<nve-panel expanded>
<nve-panel-header>
<div slot="title">Navigation menu</div>
</nve-panel-header>
<nve-panel-content>
User profile
</nve-panel-content>
</nve-panel>
</aside>
<main nve-layout="column gap:lg pad:xl">
<header nve-layout="row gap:md align:vertical-center align:space-between">
<h1>Dashboard</h1>
<nve-button>Settings</nve-button>
</header>
<section nve-layout="grid gap:md span-items:3">
<nve-card>Metric 1</nve-card>
<nve-card>Metric 2</nve-card>
<nve-card>Metric 3</nve-card>
</section>
</main>
</div>
<!-- Centered hero section with vertical layout -->
<section nve-layout="column gap:lg pad:xxl align:center full">
<nve-logo size="xl"></nve-logo>
<h1 nve-text="heading xl">Build Faster</h1>
<p nve-text="lg muted">Create stunning layouts without writing CSS</p>
<div nve-layout="row gap:sm">
<nve-button variant="primary">Start Building</nve-button>
<nve-button>Learn More</nve-button>
</div>
</section>
<!-- Complex dashboard layout using semantic HTML -->
<div nve-layout="row gap:md pad:lg align:horizontal-stretch full">
<aside style="width: 250px">
<nve-panel expanded>
<nve-panel-header>
<div slot="title">Navigation menu</div>
</nve-panel-header>
<nve-panel-content>
User profile
</nve-panel-content>
</nve-panel>
</aside>
<main nve-layout="column gap:lg pad:xl">
<header nve-layout="row gap:md align:vertical-center align:space-between">
<h1>Dashboard</h1>
<nve-button>Settings</nve-button>
</header>
<section nve-layout="grid gap:md span-items:3">
<nve-card>Metric 1</nve-card>
<nve-card>Metric 2</nve-card>
<nve-card>Metric 3</nve-card>
</section>
</main>
</div>
Best Practices
- Apply to native HTML: Use
nve-layout on HTML elements, not Elements components - Start with semantic HTML: Use appropriate elements (
<nav>, <main>, <aside>) with layout attributes - Mobile-first approach: Design for narrow screens first, then enhance for larger displays
- Consistent spacing: Use the t-shirt sizing system rather than custom values
- Combine thoughtfully: Layer layout attributes to achieve complex designs
- Test responsively: Ensure layouts work across all device sizes
While the layout system is highly optimized, avoid deeply nested layouts when simpler structures suffice. Modern browsers handle flexbox and grid efficiently, but excessive nesting can impact performance on lower-end devices.
Next Steps