Small details that build taste in Flutter.

curated by Kamran BekirovKamran Bekirov

Fade content behind the status bar

On pages with no AppBar, the body runs behind the status bar. Content collides with the clock and battery, and it looks messy.

A progressive fade at the top fixes it. The content dissolves as it slides under the status bar. ShaderMask does this with no extra package:

class ProgressiveFade extends StatelessWidget {
  final Widget child;
  final double height;
  
  const ProgressiveFade({
    super.key,
    required this.child,
    this.height = 120,
  });
  
  @override
  Widget build(BuildContext context) {
    final double end = height / MediaQuery.of(context).size.height;
  
    return ShaderMask(
      shaderCallback: (Rect bounds) {
        return LinearGradient(
          begin: Alignment.topCenter,
          end: Alignment.bottomCenter,
          colors: const [
            Color(0x00FFFFFF),
            Color(0x26FFFFFF),
            Color(0x66FFFFFF),
            Color(0xB3FFFFFF),
            Color(0xFFFFFFFF),
          ],
          stops: [
            0.0,
            end * 0.25,
            end * 0.5,
            end * 0.75,
            end,
          ],
        ).createShader(bounds);
      },
      blendMode: BlendMode.dstIn,
      child: child,
    );
  }
}

Wrap the body of a Scaffold that has no AppBar:

Scaffold(
  body: ProgressiveFade(
    child: ListView(
      children: [
        // ...your content...
      ],
    ),
  ),
)

The several stops are what make it progressive. A two-color gradient gives a hard linear fade. The extra steps ease the content out gradually, so the top edge feels soft instead of cut.

Result:

height is how far down the fade reaches in logical pixels. Raise it for a longer fade, lower it for a tighter one. The mask is alpha-only, so it works the same in light and dark mode.

Kamran Bekirov
Kamran Bekirov

Want this level of care in your Flutter apps?

Work With Me