---
name: ionic-design
description: Guide to using Ionic Framework components for beautiful native-looking Capacitor apps. Covers component usage, theming, platform-specific styling, and best practices for mobile UI. Use this skill when users need help with Ionic components or mobile UI design.
---
# Ionic Framework Design Guide
Build beautiful, native-looking mobile apps with Ionic Framework and Capacitor.
## When to Use This Skill
- User is using Ionic components
- User wants native-looking UI
- User asks about Ionic theming
- User needs mobile UI patterns
- User wants platform-specific styling
## What is Ionic Framework?
Ionic provides:
- 100+ mobile-optimized UI components
- Automatic iOS/Android platform styling
- Built-in dark mode support
- Accessibility out of the box
- Works with React, Vue, Angular, or vanilla JS
## Getting Started
### Installation
```bash
# For React
bun create vite my-app --template react-ts
cd my-app
bun add @ionic/react @ionic/react-router
# For Vue
bun create vite my-app --template vue-ts
cd my-app
bun add @ionic/vue @ionic/vue-router
# Add Capacitor
bun add @capacitor/core @capacitor/cli
bunx cap init
```
### Setup (React)
```typescript
// main.tsx
import React from 'react';
import { createRoot } from 'react-dom/client';
import { IonApp, setupIonicReact } from '@ionic/react';
import App from './App';
/* Core CSS required for Ionic components to work properly */
import '@ionic/react/css/core.css';
/* Basic CSS for apps built with Ionic */
import '@ionic/react/css/normalize.css';
import '@ionic/react/css/structure.css';
import '@ionic/react/css/typography.css';
/* Optional CSS utils */
import '@ionic/react/css/padding.css';
import '@ionic/react/css/float-elements.css';
import '@ionic/react/css/text-alignment.css';
import '@ionic/react/css/text-transformation.css';
import '@ionic/react/css/flex-utils.css';
import '@ionic/react/css/display.css';
/* Theme */
import './theme/variables.css';
setupIonicReact();
const root = createRoot(document.getElementById('root')!);
root.render(
);
```
## Core Components
### Page Structure
```tsx
import {
IonPage,
IonHeader,
IonToolbar,
IonTitle,
IonContent,
IonButtons,
IonBackButton,
} from '@ionic/react';
function MyPage() {
return (
Page Title
{/* Large title for iOS */}
Page Title
{/* Page content */}
Your content here
);
}
```
### Lists
```tsx
import {
IonList,
IonItem,
IonLabel,
IonNote,
IonAvatar,
IonIcon,
IonItemSliding,
IonItemOptions,
IonItemOption,
} from '@ionic/react';
import { chevronForward, trash, archive } from 'ionicons/icons';
function ContactList() {
return (
{/* Simple item */}
Simple Item
{/* Item with detail */}
Item Title
Item description text
Note
{/* Item with avatar */}
John Doe
john@example.com
{/* Sliding item */}
Swipe me
);
}
```
### Forms
```tsx
import {
IonInput,
IonTextarea,
IonSelect,
IonSelectOption,
IonToggle,
IonCheckbox,
IonRadioGroup,
IonRadio,
IonItem,
IonLabel,
IonButton,
} from '@ionic/react';
function MyForm() {
return (
);
}
```
### Buttons
```tsx
import { IonButton, IonIcon } from '@ionic/react';
import { heart, share, download } from 'ionicons/icons';
function Buttons() {
return (
<>
{/* Fill variants */}
Solid
Outline
Clear
{/* Colors */}
Primary
Secondary
Danger
Success
{/* Sizes */}
Small
Default
Large
{/* With icons */}
Like
{/* Icon only */}
{/* Full width */}
Block Button
Full Width
>
);
}
```
### Cards
```tsx
import {
IonCard,
IonCardHeader,
IonCardTitle,
IonCardSubtitle,
IonCardContent,
IonImg,
IonButton,
} from '@ionic/react';
function Cards() {
return (
Card Subtitle
Card Title
Card content goes here. This is a standard card with
an image, title, subtitle, and content.
Action 1
Action 2
);
}
```
### Modals and Sheets
```tsx
import { IonModal, IonButton, IonContent, IonHeader, IonToolbar, IonTitle } from '@ionic/react';
import { useState, useRef } from 'react';
function ModalExample() {
const [isOpen, setIsOpen] = useState(false);
const modal = useRef(null);
return (
<>
setIsOpen(true)}>Open Modal
{/* Full page modal */}
setIsOpen(false)}>
Modal Title
setIsOpen(false)}>
Close
Modal content
{/* Bottom sheet */}
Sheet Content
Drag to resize
Open Sheet
>
);
}
```
## Navigation
### Tab Navigation
```tsx
import {
IonTabs,
IonTabBar,
IonTabButton,
IonIcon,
IonLabel,
IonRouterOutlet,
} from '@ionic/react';
import { Route, Redirect } from 'react-router-dom';
import { home, search, person } from 'ionicons/icons';
function TabsLayout() {
return (
Home
Search
Profile
);
}
```
### Stack Navigation
```tsx
import { IonReactRouter } from '@ionic/react-router';
import { IonRouterOutlet } from '@ionic/react';
import { Route } from 'react-router-dom';
function App() {
return (
);
}
```
## Theming
### Theme Variables
```css
/* theme/variables.css */
:root {
/* Primary */
--ion-color-primary: #3880ff;
--ion-color-primary-rgb: 56, 128, 255;
--ion-color-primary-contrast: #ffffff;
--ion-color-primary-shade: #3171e0;
--ion-color-primary-tint: #4c8dff;
/* Secondary */
--ion-color-secondary: #3dc2ff;
/* Custom colors */
--ion-color-brand: #ff6b35;
--ion-color-brand-rgb: 255, 107, 53;
--ion-color-brand-contrast: #ffffff;
--ion-color-brand-shade: #e05e2f;
--ion-color-brand-tint: #ff7a49;
}
/* Dark mode */
@media (prefers-color-scheme: dark) {
:root {
--ion-background-color: #121212;
--ion-text-color: #ffffff;
--ion-color-step-50: #1e1e1e;
--ion-color-step-100: #2a2a2a;
}
}
/* iOS specific */
.ios {
--ion-toolbar-background: #f8f8f8;
}
/* Android specific */
.md {
--ion-toolbar-background: #ffffff;
}
```
### Custom Component Styling
```css
/* Global styles */
ion-content {
--background: var(--ion-background-color);
}
ion-card {
--background: #ffffff;
border-radius: 16px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
}
/* Platform-specific */
.ios ion-toolbar {
--border-width: 0;
}
.md ion-toolbar {
--border-width: 0 0 1px 0;
}
```
## Platform-Specific Code
### Detect Platform
```typescript
import { isPlatform } from '@ionic/react';
// Check platform
if (isPlatform('ios')) {
// iOS-specific code
}
if (isPlatform('android')) {
// Android-specific code
}
if (isPlatform('hybrid')) {
// Running in native app
}
if (isPlatform('mobileweb')) {
// Running in mobile browser
}
```
### Conditional Rendering
```tsx
import { isPlatform, IonIcon } from '@ionic/react';
import { chevronBack, arrowBack } from 'ionicons/icons';
function BackButton() {
return (
);
}
```
## Best Practices
### Performance
```tsx
// Use IonVirtualScroll for long lists
import { IonVirtualScroll } from '@ionic/react';
(
{item.name}
)}
/>
// Lazy load images
// Automatically lazy loads
```
### Accessibility
```tsx
// Always provide labels
// Use semantic elements
Clickable item
```
### Safe Area
```tsx
// Content respects safe areas by default
{/* Auto padding for notch/home indicator */}
// Custom safe area handling
Custom header
```
## Resources
- Ionic Documentation: https://ionicframework.com/docs
- Ionic Components: https://ionicframework.com/docs/components
- Ionicons: https://ionic.io/ionicons
- Color Generator: https://ionicframework.com/docs/theming/color-generator