Coding Liquids videos show how changing begin, end, and stops reshapes the same surface.
Place gradients in decorations and shaders
BoxDecoration.gradient paints widget backgrounds, while ShaderMask or Paint.shader applies colour inside text, icons, and canvas paths. A gradient needs finite bounds to create its shader coordinate system.
Putting a gradient in foregroundDecoration can cover child content unexpectedly.
Control LinearGradient direction and stops
LinearGradient interpolates colours along begin to end alignments, with optional stops positioning each colour. Keep stops ordered from zero to one and provide one stop per colour.
Crowded stops create visible bands, especially across large flat surfaces.
Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
stops: [0.0, 0.55, 1.0],
colors: [Color(0xFF2563EB), Color(0xFF06B6D4), Color(0xFF22D3EE)],
),
),
child: ShaderMask(
shaderCallback: (bounds) => const LinearGradient(
colors: [Colors.white, Colors.yellow],
).createShader(bounds),
child: const Text('Gradient', style: TextStyle(color: Colors.white, fontSize: 40)),
),
)
Instagram gradient studies compare bounds, stops, focal points, contrast, and direction on real components.
Focus colour with RadialGradient
RadialGradient expands from center through radius and can use focal for an off-centre highlight. Use it for glows and spotlight depth while checking edge contrast behind text.
A tiny radius repeated across a large box can look like a hard circle rather than light.

Build production-ready Gradients features
The Complete Flutter Guide turns gradients into maintainable app architecture, polished UI, and testable production code.
Enrol nowWrap colour around SweepGradient
SweepGradient rotates colours around a center between startAngle and endAngle. It suits dials, progress rings, and colour wheels when clipped to the intended shape.
The seam between last and first colours is visible unless the endpoints blend.
DecoratedBox(
decoration: BoxDecoration(
gradient: const LinearGradient(colors: [Colors.indigo, Colors.cyan]),
borderRadius: BorderRadius.circular(14),
),
child: Material(
color: Colors.transparent,
child: InkWell(
borderRadius: BorderRadius.circular(14),
onTap: submit,
child: const Padding(
padding: EdgeInsets.symmetric(horizontal: 24, vertical: 14),
child: Text('Continue', style: TextStyle(color: Colors.white)),
),
),
),
)
Clip gradient colour to text or icons
ShaderMask calls shaderCallback with actual child bounds and blends the shader through the child pixels. Render the child in an opaque base colour and choose a blend mode appropriate to the mask.
Applying one screen-sized shader to several labels makes each label use an unpredictable slice.
import 'dart:math' as math;
const radial = RadialGradient(
center: Alignment(-0.35, -0.45),
radius: 1.1,
colors: [Color(0xFF67E8F9), Color(0xFF2563EB), Color(0xFF1E1B4B)],
stops: [0, .55, 1],
);
const sweep = SweepGradient(
startAngle: 0,
endAngle: math.pi * 2,
colors: [Colors.purple, Colors.cyan, Colors.purple],
);
A LinkedIn visual-design post examines shader cost and accessible content over changing colour fields.

The Complete Flutter Guide: Build Android, iOS and Web apps
Go from scratch to building industry-standard apps with Riverpod, Firebase, animations, REST APIs, and more.
Enrol nowBuild an accessible gradient button
Decorate a constrained container with LinearGradient and place a transparent Material and InkWell above it for semantics and ripple. Choose foreground text that meets contrast across every point in the gradient.
A decorated GestureDetector alone lacks button semantics, keyboard focus, and Material ink feedback.
Design the shader for its actual bounds
A gradient is resolved against the rectangle of the widget or paint operation using it. The same alignment values therefore produce different physical transitions in a compact button and a full-screen panel. Give the decorated box stable constraints and test responsive sizes before tuning stops. For a custom shader, document whether coordinates are local, absolute, or transformed so a resize does not move the highlight unexpectedly.
Stops must be ordered and paired with the colour list. Closely packed stops create a hard edge, while broad spacing produces a gradual blend. A transparent colour can interpolate through unintended dark channel values depending on the chosen endpoints, so inspect the middle of the transition rather than only its edges. Use opacity variants of the intended colour when a fade needs to retain its hue.
Text and controls need adequate contrast at every position they may occupy, not just against an average sampled colour. Test the lightest and darkest region, focus rings, disabled labels, and selected states. A scrim or solid content surface often makes a photographic or animated gradient safer. Do not encode status solely through colour; error, success, and selection still require labels, icons, or other perceivable cues.
Large animated gradients can repaint many pixels every frame and may reveal banding on real displays. Constrain animation to the meaningful area, use a repaint boundary when it isolates genuine work, and profile a release build before increasing colour count or blur. Subtle noise can hide banding in artwork, but it also adds assets and raster cost. Golden tests across sizes can lock the intended direction and stops, while device checks should cover wide-gamut differences, dark mode, high contrast, and reduced motion. The gradient should support hierarchy; if removing it makes the interface clearer, the solid surface is the stronger design.
Animating stop positions or colours should interpolate values with matching list lengths and valid ordering throughout the transition. If the design changes topology, cross-fading two decorated layers may be safer than forcing incompatible gradients through one tween. Use the same rounded clip for the shader and its surface to prevent colour leaking beyond corners. For screenshots or exported canvases, render with the final target size because a shader tied to widget bounds will not necessarily match a scaled preview. Document the intended angle and focal point in design tokens so future edits preserve meaning rather than approximating coordinates by eye.
Design tokens can store the semantic gradient, but the widget still owns its geometry. Keep colour and stop choices reusable while supplying direction from the component’s layout context. This avoids a global “brand gradient” whose highlight points the wrong way in half the interface. For right-to-left layouts, decide whether direction follows reading order or represents fixed lighting, then encode that choice rather than mirroring accidentally.
Data visualisation gradients need a declared scale. Associate stops with meaningful numeric thresholds, clamp values outside the domain, and provide a legend that remains understandable without colour. A red-to-green scale can be inaccessible and culturally ambiguous, so combine colour with labels, shape, or position. When values are discrete categories, a set of distinct semantic colours is often more honest than a continuous blend.
Theme changes can supply different endpoints while preserving the gradient’s role and direction. Test the composed surface under light, dark, high-contrast, and disabled states, including any translucent scrim placed above it. For animation, keep stop order valid at every frame and cross-fade when the two gradients have incompatible structures. Exported canvases should create the shader at final bounds, not scale a small preview. If banding appears, first examine colour distance, surface size, and device output before adding texture that increases assets and paint work. A gradient earns its complexity when it communicates focus or hierarchy that a solid role cannot.
Common mistakes
- Place gradients in decorations and shaders: In Flutter gradients, putting a gradient in foregroundDecoration can cover child content unexpectedly; inspect this Flutter gradients cause before changing another Flutter gradients widget.
- Control LinearGradient direction and stops: In Flutter gradients, crowded stops create visible bands, especially across large flat surfaces; inspect this Flutter gradients cause before changing another Flutter gradients widget.
- Focus colour with RadialGradient: In Flutter gradients, a tiny radius repeated across a large box can look like a hard circle rather than light; inspect this Flutter gradients cause before changing another Flutter gradients widget.
- Wrap colour around SweepGradient: In Flutter gradients, the seam between last and first colours is visible unless the endpoints blend; inspect this Flutter gradients cause before changing another Flutter gradients widget.
- Clip gradient colour to text or icons: In Flutter gradients, applying one screen-sized shader to several labels makes each label use an unpredictable slice; inspect this Flutter gradients cause before changing another Flutter gradients widget.
- Build an accessible gradient button: In Flutter gradients, a decorated GestureDetector alone lacks button semantics, keyboard focus, and Material ink feedback; inspect this Flutter gradients cause before changing another Flutter gradients widget.
Frequently asked questions
How does place gradients in decorations and shaders work in Flutter gradients?
For Flutter gradients, the starting rule is that boxDecoration.gradient paints widget backgrounds, while ShaderMask or Paint.shader applies colour inside text, icons, and canvas paths. Apply this Flutter gradients rule first because place gradients in decorations and shaders determines whether the Flutter gradients pattern fits.
Why does focus colour with RadialGradient matter for Flutter gradients?
In Flutter gradients, use it for glows and spotlight depth while checking edge contrast behind text. Keeping focus colour with RadialGradient at the Flutter gradients call site exposes the Flutter gradients return value directly.
What failure should I test first in Flutter gradients?
First reproduce the Flutter gradients case where applying one screen-sized shader to several labels makes each label use an unpredictable slice. The corrected shader uses the bounds of each label or icon, giving every instance the intended complete colour transition.
How can I verify Flutter gradients before release?
Exercise build an accessible gradient button with real Flutter gradients inputs on every shipped platform. Inspect the final Flutter gradients callback or output; a successful Flutter gradients button tap alone is not proof.
Further reads
Connect Flutter gradients to the surrounding Flutter stack through these published tutorials:
- Flutter Development Guide 2026
- Flutter ThemeData: App-Wide Colours and Typography
- Flutter CustomPaint and Canvas: Draw Custom Graphics
- Flutter BoxShadow and Elevation: Depth Done Right
- Flutter AnimatedContainer: Animate Without Controllers
Sources: Flutter framework and Dart API documentation; Flutter gradients examples verified against current stable Flutter.