Layout & Structure

Page layouts, cards, tabs, and structural components.

Structure your pages with Card for content grouping, Page for application layouts with sidebar navigation, Tabs for tabbed interfaces, and Accordion/Collapsible for expandable sections. All layout components handle responsive behavior and dark mode.

This guide is part of the UI Components documentation.

Layout components organize content structure and visual hierarchy, providing consistent spacing, borders, and responsive behavior across the application.

Card

Container component for grouping related content.

import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter, CardAction } from '@kit/ui/card';
<Card>
<CardHeader>
<CardTitle>Card Title</CardTitle>
<CardDescription>Card description text</CardDescription>
</CardHeader>
<CardContent>
Card content goes here
</CardContent>
<CardFooter>
<Button>Action</Button>
</CardFooter>
</Card>

With Action Button

<Card>
<CardHeader>
<CardTitle>Settings</CardTitle>
<CardDescription>Manage your preferences</CardDescription>
<CardAction>
<Button variant="ghost" size="icon">
<Settings className="h-4 w-4" />
</Button>
</CardAction>
</CardHeader>
<CardContent>
Content here
</CardContent>
</Card>

Small Size

<Card size="sm">
<CardContent>Compact card</CardContent>
</Card>

Page

Application page layout with header, navigation, and body sections.

import { Page, PageHeader, PageTitle, PageDescription, PageBody, PageNavigation, PageMobileNavigation, PageHeaderActions } from '@kit/ui/page';
<Page>
<PageNavigation>
<Sidebar />
</PageNavigation>
<PageMobileNavigation>
<MobileNav />
</PageMobileNavigation>
<PageBody>
<PageHeader>
<div>
<PageTitle>Dashboard</PageTitle>
<PageDescription>Overview of your account</PageDescription>
</div>
<PageHeaderActions>
<Button>New Item</Button>
</PageHeaderActions>
</PageHeader>
{/* Page content */}
</PageBody>
</Page>

Collapsible sidebar navigation.

import { Sidebar, SidebarContent, SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarMenuItem, SidebarMenuButton, SidebarTrigger } from '@kit/ui/sidebar';
<Sidebar>
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>Navigation</SidebarGroupLabel>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton render={<Link href="/dashboard" />}>
<Home className="h-4 w-4" />
Dashboard
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroup>
</SidebarContent>
</Sidebar>

Tabs

Tabbed content interface.

import { Tabs, TabsList, TabsTrigger, TabsContent } from '@kit/ui/tabs';
<Tabs defaultValue="tab1">
<TabsList>
<TabsTrigger value="tab1">Tab 1</TabsTrigger>
<TabsTrigger value="tab2">Tab 2</TabsTrigger>
<TabsTrigger value="tab3">Tab 3</TabsTrigger>
</TabsList>
<TabsContent value="tab1">Content for tab 1</TabsContent>
<TabsContent value="tab2">Content for tab 2</TabsContent>
<TabsContent value="tab3">Content for tab 3</TabsContent>
</Tabs>

Line Variant

<Tabs defaultValue="tab1">
<TabsList variant="line">
<TabsTrigger value="tab1">Overview</TabsTrigger>
<TabsTrigger value="tab2">Settings</TabsTrigger>
</TabsList>
<TabsContent value="tab1">Overview content</TabsContent>
<TabsContent value="tab2">Settings content</TabsContent>
</Tabs>

Vertical Orientation

<Tabs defaultValue="tab1" orientation="vertical">
<TabsList>
<TabsTrigger value="tab1">Profile</TabsTrigger>
<TabsTrigger value="tab2">Account</TabsTrigger>
</TabsList>
<TabsContent value="tab1">Profile settings</TabsContent>
<TabsContent value="tab2">Account settings</TabsContent>
</Tabs>

Accordion

Collapsible content sections.

import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@kit/ui/accordion';
<Accordion type="single" collapsible>
<AccordionItem value="item-1">
<AccordionTrigger>Section 1</AccordionTrigger>
<AccordionContent>
Content for section 1
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-2">
<AccordionTrigger>Section 2</AccordionTrigger>
<AccordionContent>
Content for section 2
</AccordionContent>
</AccordionItem>
</Accordion>

Multiple Open

<Accordion type="multiple">
{/* Multiple items can be open simultaneously */}
</Accordion>

Collapsible

Toggle visibility of content.

import { Collapsible, CollapsibleTrigger, CollapsibleContent } from '@kit/ui/collapsible';
<Collapsible>
<CollapsibleTrigger>
<Button variant="ghost">
Toggle Content
<ChevronDown className="h-4 w-4" />
</Button>
</CollapsibleTrigger>
<CollapsibleContent>
Hidden content revealed on toggle
</CollapsibleContent>
</Collapsible>

Scroll Area

Custom scrollbar container.

import { ScrollArea } from '@kit/ui/scroll-area';
<ScrollArea className="h-72 w-48">
<div className="p-4">
{/* Long content that needs scrolling */}
</div>
</ScrollArea>

Aspect Ratio

Maintain aspect ratio for content.

import { AspectRatio } from '@kit/ui/aspect-ratio';
<AspectRatio ratio={16 / 9}>
<img
src="/image.jpg"
alt="Image"
className="h-full w-full object-cover"
/>
</AspectRatio>

Common Pitfalls

  • Tabs without default value: Always set defaultValue on Tabs, or use controlled value prop. Missing defaults cause hydration mismatches.
  • Accordion value type mismatch: Single mode uses string, multiple mode uses string[]. Match your state type accordingly.
  • Page layout without sidebar width: Sidebar needs explicit width via className or the layout shifts unexpectedly.
  • Card nested incorrectly: CardHeader, CardContent, CardFooter must be direct children of Card for proper spacing.
  • ScrollArea height: ScrollArea needs a fixed height to enable scrolling. Without className="h-72" or similar, it expands to fit content.

Frequently Asked Questions

How do I make tabs work with URL routing?
Use controlled value prop synced with URL params. Read the param on mount, update URL in onValueChange handler.
Can I nest Cards inside Cards?
Yes, but consider using Card with size='sm' for nested cards to maintain visual hierarchy without too much padding.
How do I make Accordion items open by default?
Pass the item's value to defaultValue prop: defaultValue='item-1'. For multiple, use defaultValue={['item-1', 'item-2']}.
What's the difference between Accordion and Collapsible?
Accordion manages multiple items with mutual exclusivity (single mode). Collapsible is for a single expandable section.
How do I add actions to Card header?
Use CardAction component inside CardHeader: <CardHeader><CardTitle>...</CardTitle><CardAction><Button /></CardAction></CardHeader>

Next: Navigation →