Apple shipped Liquid Glass in iOS 26 and Flutter's Cupertino package has not caught up yet. The tracking issue (flutter/flutter#170310) is one of the most-watched tickets in the Flutter repo in April 2026, but until the official redesign lands you have to build it yourself. This is the guide for doing that properly, with copy-paste widgets, Android fallbacks, and a migration plan for when the native version ships.
Short version: Liquid Glass is three ingredients. A heavy backdrop blur, a saturation boost on the blurred content, and a tinted overlay with a subtle refraction highlight. You can assemble all three in Flutter today with BackdropFilter, ImageFilter.blur, and aShaderBuilder for the highlight. The result is indistinguishable from native iOS 26 on A17 Pro and newer devices, and degrades cleanly to flat Material on Android and older iOS.
What Liquid Glass actually is
Apple's 2026 design language replaces the opaque Cupertino surfaces with semi-translucent layers that pick up color and light from whatever is behind them. Navigation bars, modal sheets, tab bars, and widget cards all use it. The effect relies on four perceptual cues, and if you miss any one of them the result feels like a 2018 glassmorphism component, not Liquid Glass.
- Heavy blur with a soft edge. Apple uses approximately a 30 to 40 logical-pixel Gaussian blur on the background layer, with a radial falloff at the widget's edges.
- Saturation and brightness boost on the blurred content. Around 140 to 160 percent saturation, 105 percent brightness. This is the part most implementations skip.
- A tinted overlay with material thickness. Usually white at 8 to 14 percent opacity for light mode, black at 20 to 28 percent for dark mode, with a faint specular highlight along the top edge.
- A thin inner border that catches light. One logical pixel, white at 20 percent for light mode, white at 8 percent for dark mode. Makes the edge feel like cut glass.
Why the Flutter Cupertino package is not there yet
The Flutter team tracks iOS design parity in a single issue (flutter/flutter#170310) which has over 200 comments as of April 2026. The official plan, per the 2026 roadmap, is to split Cupertino into a standalone package and rebuild core widgets (NavigationBar, TabBar, Sheet, Dialog, ContextMenu) against the Liquid Glass spec. Realistic ship window is late 2026. Until then, Cupertino widgets in Flutter look iOS 17.
This gap matters because every indie Flutter app that targets iOS 26 looks dated against its native SwiftUI counterparts. The fix is not hard, but it does require doing the work yourself or picking up a boilerplate that already did.
The LiquidGlassCard widget, step by step
Here is the minimum viable Liquid Glass card. It composes three layers: a clipped blur, a saturation filter, and a tinted overlay with a highlight stroke.
// lib/widgets/liquid_glass_card.dart
import 'dart:ui';
import 'package:flutter/material.dart';
class LiquidGlassCard extends StatelessWidget {
const LiquidGlassCard({
super.key,
required this.child,
this.borderRadius = 24,
this.blurSigma = 32,
this.saturation = 1.5,
});
final Widget child;
final double borderRadius;
final double blurSigma;
final double saturation;
@override
Widget build(BuildContext context) {
final isDark = Theme.of(context).brightness == Brightness.dark;
final overlay = isDark
? Colors.black.withOpacity(0.24)
: Colors.white.withOpacity(0.12);
final stroke = isDark
? Colors.white.withOpacity(0.08)
: Colors.white.withOpacity(0.22);
return ClipRRect(
borderRadius: BorderRadius.circular(borderRadius),
child: BackdropFilter(
filter: ImageFilter.compose(
outer: ColorFilter.matrix(_saturate(saturation)),
inner: ImageFilter.blur(sigmaX: blurSigma, sigmaY: blurSigma),
),
child: DecoratedBox(
decoration: BoxDecoration(
color: overlay,
border: Border.all(color: stroke, width: 1),
borderRadius: BorderRadius.circular(borderRadius),
),
child: child,
),
),
);
}
}
List<double> _saturate(double s) {
final r = 0.213 * (1 - s);
final g = 0.715 * (1 - s);
final b = 0.072 * (1 - s);
return [
r + s, g, b, 0, 0,
r, g + s, b, 0, 0,
r, g, b + s, 0, 0,
0, 0, 0, 1, 0,
];
}A few things to notice. The saturation matrix is the key ingredient that lifts this above plain glassmorphism. ImageFilter.compose layers the saturation on top of the blur so both operate on the same backdrop pixels. The overlay color and stroke color shift with the theme so the card looks right in dark mode without a second component.
Building the LiquidGlassNavigationBar
A Liquid Glass navigation bar is the same card idea with three additions: a safe-area-aware height, a thicker backdrop blur (40 to 48 sigma), and a subtle top-edge highlight rendered as a gradient stroke. The gradient runs from 25 percent white at the top-left to 5 percent white at the bottom-right for the specular effect.
| Variant | Blur sigma | Overlay opacity (light / dark) | Use when |
|---|---|---|---|
| Thin material | 16 to 20 | 6 percent / 12 percent | Inline cards, tooltips |
| Regular material | 28 to 34 | 12 percent / 24 percent | Cards, sheets, dialogs |
| Thick material | 40 to 48 | 18 percent / 32 percent | Navigation bars, tab bars |
| Ultra-thick material | 60 to 70 | 26 percent / 42 percent | Modal overlays, blur-to-hide |
Apple's internal naming convention maps to the Material thickness scale above. If you want to nerd out further, their UIVisualEffectView presets correspond to exactly these four tiers.
Android fallback: when to skip Liquid Glass entirely
Liquid Glass is an iOS idiom. On Android, Material 3 is the expected design language. Shipping Liquid Glass on Android looks out of place and regresses performance on low-end devices becauseBackdropFilter is expensive on the rasterizer. The correct fallback is to render a solid Material 3 surface with the same shape and spacing.
Widget adaptiveCard({required Widget child}) {
return defaultTargetPlatform == TargetPlatform.iOS
? LiquidGlassCard(child: child)
: Card(
elevation: 0,
color: Theme.of(context).colorScheme.surfaceContainerHighest,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)),
child: child,
);
}This one-liner gate is the cleanest pattern. Do not try to ship Liquid Glass everywhere and hope it looks native on Android. It does not.
Accessibility and reduced-motion rules
Liquid Glass has accessibility implications the raw material does not. Two user preferences turn it off or dampen it, and your widget must respect both.
- Reduce Transparency. iOS setting. When enabled, Apple renders Liquid Glass as a solid surface. Check
MediaQuery.of(context).accessibleNavigationplus a platform channel read ofUIAccessibilityIsReduceTransparencyEnabled. Fall back to the opaque overlay color. - Reduce Motion. Disables the subtle parallax and dynamic refraction. Check
MediaQuery.of(context).disableAnimationsand skip any animated shimmer or gradient sweep you attached to the highlight. - Minimum contrast. The tinted overlay plus blur can drop text contrast below WCAG AA on busy backgrounds. Set a rule: if the card contains text, push overlay opacity to 22 percent minimum in light mode.
Performance on Impeller
BackdropFilter on Impeller in 2026 is fast, but not free. A full-screen Liquid Glass sheet costs about 1.2 ms of GPU time on iPhone 15 Pro at 60 Hz, and roughly 2.4 ms at 120 Hz. Two stacked Liquid Glass layers double that. Three or more and you are burning frame budget.
The optimization rules:
- Only apply blur to the visible region. Use
ClipRectaggressively. - Never nest more than two Liquid Glass surfaces in the same tree.
- On scroll-heavy screens, swap to a static snapshot of the backdrop with
RepaintBoundary. - Use
TickerModeto disable the effect entirely when the widget is off-screen in a PageView.
When the official Cupertino redesign lands: the migration plan
Assume late 2026 for the ship. Apple's own design language will stabilize by then and the Flutter team will ship a standalone package:cupertino replacingpackage:flutter/cupertino. Here is the migration path.
| Custom widget today | Expected replacement | Migration effort |
|---|---|---|
LiquidGlassCard | CupertinoMaterial with thickness: .regular | 1-line change per call site |
LiquidGlassNavigationBar | Rebuilt CupertinoNavigationBar (official) | Replace import + prop rename |
LiquidGlassSheet | CupertinoSheet with material override | Prop-for-prop swap |
| Custom refraction shader | Not needed, built into the package | Delete your ShaderBuilder |
The smart pattern is to wrap your custom widgets behind an interface so you can do a one-line-per-file migration when the package lands. MyAppCard as a thin wrapper around LiquidGlassCard today, swap to the official CupertinoMateriallater.
What The Flutter Kit ships
Every pattern above is pre-built in The Flutter Kit. Six Liquid Glass-ready screens (paywall, settings, onboarding, profile, search, dashboard) ship with the adaptive card pattern, the navigation bar, the modal sheet, and the accessibility guards. Android falls back to Material 3 cleanly. When the official Cupertino redesign lands, the migration is configured to be a single import change in pubspec.yaml.
$69 one-time, unlimited commercial projects. See every integration on the features page or jump to checkout.
Final checklist
- Blur sigma matches Apple's material thickness tier
- Saturation matrix applied, not just blur
- Overlay opacity shifts with light / dark mode
- Edge stroke renders at one logical pixel
- Reduce Transparency and Reduce Motion both respected
- Android falls back to Material 3, not forced Liquid Glass
- No more than two nested blur surfaces per screen
- Wrapper interface in place for future Cupertino migration
Ship with all eight boxes checked and your Flutter app will pass for native iOS 26 on the App Store review ride. Ship without them and the design feels one OS version behind.