Getting Started
A CSS/JS theme library that applies Material Design 3 design system to Ionic applications.
DEMO is here: https://ionic-theme-md3.rdlabo.dev/
Designed for compatibility with @rdlabo/ionic-theme-ios26, so one markup tree can style both Ionic modes.
Installation
In an existing Ionic project:
npm install @rdlabo/ionic-theme-md3
Note: If you use @ionic/core@ < 8.8.0, use @rdlabo/ionic-theme-md3@1.0.2.
And import the theme in your project's main CSS file (e.g., src/styles.scss).
@import '@rdlabo/ionic-theme-md3/dist/css/default-variables.css';
@import '@rdlabo/ionic-theme-md3/dist/css/ionic-theme-md3.css';
Configure animations
If you installed only the MD3 theme, configure its animation as follows.
import { isPlatform } from '@ionic/core'; // or @ionic/angular (Ionic 9), @ionic/angular/standalone (Ionic 8), @ionic/react, @ionic/vue
import { mdTransitionAnimation } from '@rdlabo/ionic-theme-md3';
// Angular
provideIonicAngular({
...
navAnimation: isPlatform('ios') ? undefined: mdTransitionAnimation,
});
// React
setupIonicReact({
...
navAnimation: isPlatform('ios') ? undefined: mdTransitionAnimation,
});
// Vue
createApp(App)
.use(IonicVue, {
...
navAnimation: isPlatform('ios') ? undefined: mdTransitionAnimation,
})
Check the theme
Test on Android. When previewing on desktop, set Ionic mode to md in your existing framework initialization config (for example mode: 'md').
Use this markup to preview the inset grouped list look. For the list structure the theme expects, see Using ion-item-group.
<ion-list mode="md" inset="true">
<ion-item-group>
<ion-item><ion-label>Notifications</ion-label></ion-item>
<ion-item><ion-label>Appearance</ion-label></ion-item>
</ion-item-group>
</ion-list>
Optional: use the MD3 and iOS 26 themes together
Install the iOS 26 theme to style both Ionic modes from the same application.
The current releases of both themes require @ionic/core 8.8.1 or later. Upgrade Ionic before using this setup if your application is on 8.8.0 or earlier.
npm install @rdlabo/ionic-theme-ios26
When your global stylesheet uses Sass, initialize the themes in this order:
@use '@rdlabo/ionic-theme-ios26/src/styles/default-variables.scss' as ios26-vars;
@use '@rdlabo/ionic-theme-ios26/src/styles/ionic-theme-ios26.scss';
@use '@rdlabo/ionic-theme-ios26/src/styles/ionic-theme-ios26-dark-class.scss';
@use '@rdlabo/ionic-theme-ios26/src/styles/md-remove-ios-class-effect.scss';
@use '@rdlabo/ionic-theme-md3/dist/css/default-variables.css' as md3-vars;
@use '@rdlabo/ionic-theme-md3/dist/css/ionic-theme-md3.css';
The example uses Ionic's class-based dark mode. Your global stylesheet must also load Ionic's matching dark palette, such as @ionic/angular/css/palettes/dark.class.css for Angular. When using dark-system or dark-always, select the same variant for both Ionic's palette and the iOS 26 theme. See Ionic's Dark Mode documentation. The explicit ios26-vars and md3-vars namespaces prevent the two variable modules from using the same default namespace.
Configure both transition implementations when both themes are installed:
import { isPlatform } from '@ionic/core'; // or @ionic/angular (Ionic 9), @ionic/angular/standalone (Ionic 8), @ionic/react, @ionic/vue
import { iosTransitionAnimation, popoverEnterAnimation, popoverLeaveAnimation } from '@rdlabo/ionic-theme-ios26';
import { mdTransitionAnimation } from '@rdlabo/ionic-theme-md3';
// Angular
provideIonicAngular({
...
navAnimation: isPlatform('ios') ? iosTransitionAnimation : mdTransitionAnimation,
popoverEnter: isPlatform('ios') ? popoverEnterAnimation : undefined,
popoverLeave: isPlatform('ios') ? popoverLeaveAnimation : undefined,
});
// React
setupIonicReact({
...
navAnimation: isPlatform('ios') ? iosTransitionAnimation : mdTransitionAnimation,
popoverEnter: isPlatform('ios') ? popoverEnterAnimation : undefined,
popoverLeave: isPlatform('ios') ? popoverLeaveAnimation : undefined,
});
// Vue
createApp(App)
.use(IonicVue, {
...
navAnimation: isPlatform('ios') ? iosTransitionAnimation : mdTransitionAnimation,
popoverEnter: isPlatform('ios') ? popoverEnterAnimation : undefined,
popoverLeave: isPlatform('ios') ? popoverLeaveAnimation : undefined,
});
Documentation
- Using ion-item-group — shared inset-list markup for iOS 26 and MD3.
- Special markup — opt-in component combinations used by the demo.
- ESLint — check list structure with ESLint rules.
- Migration — changes required when updating theme markup.
Related Projects
If you need a more comprehensive Material Design 3 implementation, you may also be interested in:
- md3-for-ionic by danielkleebinder
Note: This theme is purpose-built for compatibility with Ionic's design approach and
@rdlabo/ionic-theme-ios26; it is not intended as a strict, full MD3 recreation.