flutter-build-responsive-layout
Build adaptive layouts using LayoutBuilder, MediaQuery, or Expanded/Flexible widgets to ensure the UI looks elegant across all mobile, tablet, and desktop form factors.
What this skill does
## Contents
- [Space Measurement Guidelines](#space-measurement-guidelines)
- [Widget Sizing and Constraints](#widget-sizing-and-constraints)
- [Device and Orientation Behaviors](#device-and-orientation-behaviors)
- [Workflow: Constructing an Adaptive Layout](#workflow-constructing-an-adaptive-layout)
- [Workflow: Optimizing for Large Screens](#workflow-optimizing-for-large-screens)
- [Examples](#examples)
## Space Measurement Guidelines
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:
- **Use `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.
- **Use `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.
- **Avoid global orientation builders**: Do not rely on device orientation builders (`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.
- **Do not check for physical hardware type**: Do not check whether the current hardware is a "phone", "tablet", or "desktop" to determine layout rules. Layouts must adapt to window constraints, not physical hardware types, since resizable windows, picture-in-picture, and screen splits are standard on modern platforms.
## Widget Sizing and Constraints
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:
- **Distribute Space with Flex**: Use `Expanded` and `Flexible` inside `Row`, `Column`, or `Flex` layouts to share available space proportionally among siblings.
- Use `Expanded` to force a child to consume all remaining available space along the main axis.
- Use `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.
- **Limit Max Width**: Avoid letting content stretch infinitely across wide displays. Wrap list views, grids, and form blocks in a `ConstrainedBox` or a `Container` with a maximum width restriction and keep them centered using a `Center` widget.
- **Lazy Render lists**: Always use `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.
## Device and Orientation Behaviors
A truly responsive and professional application adapts to dynamic form factors and multiple input methods seamlessly:
- **Avoid locking screen orientation**: Locking the application to a single orientation is highly discouraged. It breaks the user experience on foldable devices and large-format form factors, resulting in awkward letterboxing.
- **Provide safe fallbacks**: If orientation locking is unavoidable due to strict business mandates, utilize the `Display API` to retrieve physical screen dimensions instead of `MediaQuery`, which may return incorrect dimensions in compatibility or legacy scaling modes.
- **Support diverse inputs**: Ensure all interactive widgets have minimum touch target sizes of 48x48 logical pixels. Optimize layout components to respond to mouse hovers, trackpad gestures, and keyboard navigation.
## Workflow: Constructing an Adaptive Layout
Follow this checklist to build and verify responsive layouts:
- [ ] **Identify the target layout**: Select the page or section that requires custom responsive behavior.
- [ ] **Implement LayoutBuilder**: Wrap the subtree in a `LayoutBuilder` widget.
- [ ] **Extract constraint width**: Read `constraints.maxWidth` in the builder callback.
- [ ] **Define clear breakpoints**: Use established breakpoints (e.g., 600 logical pixels for tablet/large-screen layouts).
- [ ] **Define subtrees**:
- [ ] If `maxWidth > 600`: Return the multi-pane or split-screen layout (e.g., placing navigation sidebars beside content).
- [ ] If `maxWidth <= 600`: Return the single-column or mobile-optimized layout.
- [ ] **Inspect and verify**: Run the app, resize the window dynamically or rotate the simulator, and verify that there are no layout overflows or jank during transitions.
## Workflow: Optimizing for Large Screens
Follow this checklist to optimize readability on large screens:
- [ ] **Identify stretched components**: Find full-screen text blocks, input forms, or list items that span the entire screen width.
- [ ] **Apply constraints**: Wrap the stretched content in a `ConstrainedBox` widget.
- [ ] **Define maximum limits**: Set a maximum readable width (e.g., `BoxConstraints(maxWidth: 800.0)`).
- [ ] **Center the content**: Wrap the `ConstrainedBox` in a `Center` widget to keep the layout balanced on wide monitors.
- [ ] **Inspect and verify**: Test the layout on a desktop build or tablet simulator to ensure readability remains excellent and content does not stretch.
## Examples
### Adaptive Layout with Breakpoints
This example shows how to switch between a mobile-optimized layout and a larger screen split-pane layout depending on available space.
```dart
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'),
);
}
}
```
### Constraining Width on Wide Screens
This example prevents a profile or settings form from stretching awkwardly across wide desktop screens.
```dart
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(
Related in Design
contribute
IncludedLocal-only OSS contribution command center. Auto-refreshes the user's in-flight PR and issue state on invoke so conversations start with full context — no need to brief Claude on what's in flight. Helps the user find issues to contribute to on GitHub, builds per-repo dossiers of what each upstream expects (CLA, DCO, branch convention, AI policy, draft-first, review bots, issue templates), runs deterministic gates before any external action so AI-assisted contributions don't reach maintainers as slop. State is markdown-only: candidate files at ~/.contribute-system/candidates/, repo dossiers at ~/.contribute-system/research/, append-only event log at ~/.contribute-system/log.jsonl. No database, no cloud calls. Use when the user asks about their PRs / issues / contributions, wants to find new work to take on, claim an issue, build/refresh a repo's dossier, or draft a Design Issue or PR. Trigger with "/contribute", "what's my PR status", "find a contribution", "claim issue X", "draft a Design Issue for Y", "refresh dossier for Z".
architectural-analysis
IncludedUser-triggered deep architectural analysis of a codebase or scoped subtree across eight modes — information architecture, data flow, integration points, UI surfaces, interaction patterns, data model, control flow, and failure modes. This skill should be used when the user asks to "diagram this codebase," "map the architecture," "show the data flow," "give me an ERD," "trace control flow," "find the integration points," "verify the layout pattern," "audit the UX architecture," or any similar request whose primary deliverable is mermaid diagrams plus cited reports under docs/architecture/. Dispatches haiku/sonnet sub-agents in parallel for per-mode exploration, then verifies every citation mechanically before any node lands in a diagram. Not for one-off prose explanations of code (use code-explanation) or for high-level system design from scratch (use system-design).
mcp
IncludedModel Context Protocol (MCP) server development and tool management. Languages: Python, TypeScript. Capabilities: build MCP servers, integrate external APIs, discover/execute MCP tools, manage multi-server configs, design agent-centric tools. Actions: create, build, integrate, discover, execute, configure MCP servers/tools. Keywords: MCP, Model Context Protocol, MCP server, MCP tool, stdio transport, SSE transport, tool discovery, resource provider, prompt template, external API integration, Gemini CLI MCP, Claude MCP, agent tools, tool execution, server config. Use when: building MCP servers, integrating external APIs as MCP tools, discovering available MCP tools, executing MCP capabilities, configuring multi-server setups, designing tools for AI agents.
react-native-skia
IncludedDesign, build, debug, and optimise high-polish animated graphics in React Native or Expo using @shopify/react-native-skia, Reanimated, and Gesture Handler. Use when the user wants canvas-driven UI, shaders, paths, rich text, image filters, sprite fields, Skottie, video frames, snapshots, web CanvasKit setup, or performance tuning for custom motion-heavy elements such as loaders, hero art, cards, charts, progress indicators, particle systems, or gesture-driven surfaces. Also use when the user asks for fluid, glow, glass, blob, parallax, 60fps/120fps, or GPU-friendly animated effects in React Native, even if they do not explicitly say "Skia". Do not use for ordinary form/layout work with standard views.
plaid
IncludedProduct Led AI Development — guides founders from idea to launched product. Six capabilities: Idea (discover a product idea), Validate (pressure-test the idea against fatal flaws, problem reality, competition, and 2-week MVP feasibility), Plan (vision intake + document generation), Design (translate image references into a design.md spec), Launch (go-to-market strategy), and Build (roadmap execution). Use when someone says "PLAID", "plaid idea", "help me find an idea", "product idea", "idea from my business", "idea from my expertise", "plaid validate", "validate my idea", "pressure-test", "is this idea good", "find fatal flaws", "validate the problem", "plan a product", "define my vision", "generate a PRD", "product strategy", "plaid design", "design from image", "translate image to design", "create design.md", "extract design tokens", "plaid launch", "go-to-market", "launch plan", "GTM strategy", "launch playbook", "plaid build", "build the app", "start building", or "execute the roadmap".
nextjs-framer-motion-animations
IncludedAdds production-safe Motion for React or Framer Motion animations to Next.js apps, including reveal, hover and tap micro-interactions, whileInView, stagger, AnimatePresence, layout and layoutId transitions, reorder, scroll-linked UI, and lightweight route-content transitions. Use when the user asks to add, refactor, or debug Motion or Framer Motion in App Router or Pages Router codebases, especially around server/client boundaries, reduced motion, LazyMotion, bundle size, hydration, or route transitions. Avoid for GSAP-style timelines, WebGL or 3D scenes, heavy scroll storytelling, or CSS-only effects unless Motion is explicitly requested.