skills/flutter/flutter-build-responsive-layout/SKILL.md
Build adaptive layouts using LayoutBuilder, MediaQuery, or Expanded/Flexible widgets to ensure the UI looks elegant across all mobile, tablet, and desktop form factors.
npx skillsauth add dhruvanbhalara/skills flutter-build-responsive-layoutInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
To ensure that layouts adapt fluidly to the app window (which is especially important on platforms with resizable windows or multi-window multitasking), determine available space using these principles:
MediaQuery.sizeOf(context): Instead of accessing the full MediaQuery.of(context) (which triggers rebuilds for any MediaQuery property change), use the modern and efficient MediaQuery.sizeOf(context) to retrieve the dimensions of the application window.LayoutBuilder: Place layout decisions inside a LayoutBuilder when you want a component to adapt based on the size allocated to it by its parent widget rather than the global screen dimensions. Use constraints.maxWidth to choose the appropriate widget subtree to render.OrientationBuilder or MediaQuery.orientationOf) near the top of the widget tree to switch main layouts. The device orientation does not always reflect the actual available layout space, particularly in multi-window or foldable multitasking modes.In Flutter, layouts are built using a negotiation process: Constraints go down, sizes go up, and the parent sets the position. Apply these rules to manage widget dimensions elegantly:
Expanded and Flexible inside Row, Column, or Flex layouts to share available space proportionally among siblings.
Expanded to force a child to consume all remaining available space along the main axis.Flexible to allow a child to size itself up to a specific limit, and use the flex factor to define how remaining space is shared.ConstrainedBox or a Container with a maximum width restriction and keep them centered using a Center widget.ListView.builder or GridView.builder when displaying lists or grids with a large or dynamic number of items to ensure off-screen widgets are lazily built and memory consumption remains low.A truly responsive and professional application adapts to dynamic form factors and multiple input methods seamlessly:
Display API to retrieve physical screen dimensions instead of MediaQuery, which may return incorrect dimensions in compatibility or legacy scaling modes.Follow this checklist to build and verify responsive layouts:
LayoutBuilder widget.constraints.maxWidth in the builder callback.maxWidth > 600: Return the multi-pane or split-screen layout (e.g., placing navigation sidebars beside content).maxWidth <= 600: Return the single-column or mobile-optimized layout.Follow this checklist to optimize readability on large screens:
ConstrainedBox widget.BoxConstraints(maxWidth: 800.0)).ConstrainedBox in a Center widget to keep the layout balanced on wide monitors.This example shows how to switch between a mobile-optimized layout and a larger screen split-pane layout depending on available space.
import 'package:flutter/material.dart';
class AdaptiveHomeLayout extends StatelessWidget {
const AdaptiveHomeLayout({super.key});
static const double tabletBreakpoint = 600.0;
@override
Widget build(BuildContext context) {
return Scaffold(
body: LayoutBuilder(
builder: (context, constraints) {
if (constraints.maxWidth > tabletBreakpoint) {
return _buildTabletLayout();
}
return _buildMobileLayout();
},
),
);
}
Widget _buildTabletLayout() {
return Row(
children: [
const SizedBox(
width: 240,
child: NavigationSidebar(),
),
const VerticalDivider(width: 1),
Expanded(
child: const MainContentArea(),
),
],
);
}
Widget _buildMobileLayout() {
return const MainContentArea();
}
}
class NavigationSidebar extends StatelessWidget {
const NavigationSidebar({super.key});
@override
Widget build(BuildContext context) {
return ListView(
padding: const EdgeInsets.symmetric(vertical: 16),
children: const [
ListTile(
leading: Icon(Icons.dashboard),
title: Text('Dashboard'),
),
ListTile(
leading: Icon(Icons.settings),
title: Text('Settings'),
),
],
);
}
}
class MainContentArea extends StatelessWidget {
const MainContentArea({super.key});
@override
Widget build(BuildContext context) {
return const Center(
child: Text('Main Content Area'),
);
}
}
This example prevents a profile or settings form from stretching awkwardly across wide desktop screens.
import 'package:flutter/material.dart';
class ConstrainedProfileForm extends StatelessWidget {
const ConstrainedProfileForm({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Edit Profile'),
),
body: Center(
child: ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 600.0,
),
child: ListView(
padding: const EdgeInsets.all(24.0),
children: [
const TextFormField(
decoration: InputDecoration(
labelText: 'Full Name',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
const TextFormField(
decoration: InputDecoration(
labelText: 'Email Address',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 24),
ElevatedButton(
onPressed: () {},
child: const Text('Save Changes'),
),
],
),
),
),
);
}
}
development
Perform REST API networking operations (GET, POST, PUT, DELETE) using the lightweight and robust standard `http` package, including platform configurations and background parsing models.
development
Configure internationalization and localization support using Flutter's built-in l10n system, App Resource Bundle (ARB) files, and ICU formatting syntax.
development
Create model classes with fromJson/toJson using dart:convert and Dart 3 pattern matching. Use when manually mapping JSON to classes, parsing HTTP responses, or choosing between manual and code-generated serialization.
data-ai
Diagnose and fix Flutter layout constraint violations (RenderFlex overflow, unbounded height/width, ParentData misuse). Use when encountering layout exceptions, yellow-black overflow stripes, or red error screens.