PluginBench
Skill
Official
Pass
Audit score 90

flutter-build-responsive-layout

flutter/skills

Build Flutter layouts that adapt to any screen size using LayoutBuilder, MediaQuery, and Expanded/Flexible widgets.

What is flutter-build-responsive-layout?

This skill teaches how to create responsive Flutter layouts that work across mobile, tablet, and desktop form factors. Use it when you need your UI to automatically adjust to different window sizes and orientations without locking screen orientation or checking hardware types.

  • Use LayoutBuilder to make layout decisions based on parent widget constraints
  • Apply Expanded and Flexible widgets to distribute space within Row, Column, or Flex layouts
  • Constrain widget width on large screens using ConstrainedBox to prevent unnatural stretching
  • Convert ListView to GridView with SliverGridDelegateWithMaxCrossAxisExtent for responsive grids
  • Support multiple input methods including touch, keyboard, and mouse/trackpad navigation
  • Avoid orientation locking and hardware type checks in favor of window space-based decisions

How to install flutter-build-responsive-layout

npx skills add https://github.com/flutter/skills --skill flutter-build-responsive-layout
Claude Code
Cursor
Windsurf
Cline

How to use flutter-build-responsive-layout

  1. 1.Identify the widget that needs adaptive behavior and wrap it in a LayoutBuilder
  2. 2.Extract constraints.maxWidth from the builder callback to determine available space
  3. 3.Define a breakpoint value (e.g., 600dp for mobile/tablet threshold)
  4. 4.Return different widget trees based on whether maxWidth exceeds the breakpoint
  5. 5.For lists on large screens, convert ListView.builder to GridView.builder with SliverGridDelegateWithMaxCrossAxisExtent
  6. 6.For text or form content, wrap in ConstrainedBox with maxWidth and Center to prevent stretching
  7. 7.Test by resizing the app window and checking layout transitions across breakpoints

Use cases

Good for
  • Creating a sidebar navigation layout that switches to bottom navigation on mobile screens
  • Building a responsive product grid that adjusts column count based on available width
  • Implementing a form or text content area that maintains optimal readability on large displays
  • Adapting a dashboard with multiple panels to work on both phone and tablet screens
  • Supporting foldable devices and multi-window modes without letterboxing issues
Who it's for
  • Flutter developers building cross-platform mobile and desktop applications
  • Teams supporting large-format Android devices and foldable phones
  • Developers creating responsive web-like experiences in Flutter apps
  • Anyone building apps that need to work in resizable windows or picture-in-picture modes

flutter-build-responsive-layout FAQ

Should I use MediaQuery.orientationOf or OrientationBuilder to switch layouts?

No. Device orientation does not accurately reflect available app window space. Use LayoutBuilder with constraints.maxWidth instead, as Flutter apps run in resizable windows, multi-window modes, and picture-in-picture.

Can I lock screen orientation for my app?

Not recommended. Locking orientation causes severe layout issues on foldable devices and results in letterboxing. If business requirements mandate it, use the Display API to retrieve physical screen dimensions instead of MediaQuery.

How do I prevent widgets from stretching too wide on large screens?

Wrap full-width components in a ConstrainedBox with BoxConstraints(maxWidth: value), then wrap that in a Center widget to keep content centered on large displays.

What breakpoint value should I use to distinguish mobile from tablet layouts?

A common breakpoint is 600dp (largeScreenMinWidth = 600.0), but adjust based on your app's content and design requirements.

Should I check for phone vs tablet hardware types?

No. Base all layout decisions strictly on available window space using constraints.maxWidth, not hardware type checks, since Flutter apps run in various window modes.

Full instructions (SKILL.md)

Source of truth, from flutter/skills.


name: flutter-build-responsive-layout description: Use LayoutBuilder, MediaQuery, or Expanded/Flexible to create a layout that adapts to different screen sizes. Use when you need the UI to look good on both mobile and tablet/desktop form factors. metadata: model: models/gemini-3.1-pro-preview last_modified: Tue, 21 Apr 2026 20:17:40 GMT

Implementing Adaptive Layouts

Contents

Space Measurement Guidelines

Determine the available space accurately to ensure layouts adapt to the app window, not just the physical device.

  • Use MediaQuery.sizeOf(context) to get the size of the entire app window.
  • Use LayoutBuilder to make layout decisions based on the parent widget's allocated space. Evaluate constraints.maxWidth to determine the appropriate widget tree to return.
  • Do not use MediaQuery.orientationOf or OrientationBuilder near the top of the widget tree to switch layouts. Device orientation does not accurately reflect the available app window space.
  • Do not check for hardware types (e.g., "phone" vs. "tablet"). Flutter apps run in resizable windows, multi-window modes, and picture-in-picture. Base all layout decisions strictly on available window space.

Widget Sizing and Constraints

Understand and apply Flutter's core layout rule: Constraints go down. Sizes go up. Parent sets position.

  • Distribute Space: Use Expanded and Flexible within Row, Column, or Flex widgets.
    • Use Expanded to force a child to fill all remaining available space (equivalent to Flexible with fit: FlexFit.tight and a flex factor of 1.0).
    • Use Flexible to allow a child to size itself up to a specific limit while still expanding/contracting. Use the flex factor to define the ratio of space consumption among siblings.
  • Constrain Width: Prevent widgets from consuming all horizontal space on large screens. Wrap widgets like GridView or ListView in a ConstrainedBox or Container and define a maxWidth in the BoxConstraints.
  • Lazy Rendering: Always use ListView.builder or GridView.builder when rendering lists with an unknown or large number of items.

Device and Orientation Behaviors

Ensure the app behaves correctly across all device form factors and input methods.

  • Do not lock screen orientation. Locking orientation causes severe layout issues on foldable devices, often resulting in letterboxing (the app centered with black borders). Android large format tiers require both portrait and landscape support.
  • Fallback for Locked Orientation: If business requirements strictly mandate a locked orientation, use the Display API to retrieve physical screen dimensions instead of MediaQuery. MediaQuery fails to receive the larger window size in compatibility modes.
  • Support Multiple Inputs: Implement support for basic mice, trackpads, and keyboard shortcuts. Ensure touch targets are appropriately sized and keyboard navigation is accessible.

Workflow: Constructing an Adaptive Layout

Follow this workflow to implement a layout that adapts to the available BoxConstraints.

Task Progress:

  • Identify the target widget that requires adaptive behavior.
  • Wrap the widget tree in a LayoutBuilder.
  • Extract the constraints.maxWidth from the builder callback.
  • Define an adaptive breakpoint (e.g., largeScreenMinWidth = 600).
  • If maxWidth > largeScreenMinWidth: Return a large-screen layout (e.g., a Row placing a navigation sidebar and content area side-by-side).
  • If maxWidth <= largeScreenMinWidth: Return a small-screen layout (e.g., a Column or standard navigation-style approach).
  • Run validator -> resize the application window -> review layout transitions -> fix overflow errors.

Workflow: Optimizing for Large Screens

Follow this workflow to prevent UI elements from stretching unnaturally on large displays.

Task Progress:

  • Identify full-width components (e.g., ListView, text blocks, forms).
  • If optimizing a list: Convert ListView.builder to GridView.builder using SliverGridDelegateWithMaxCrossAxisExtent to automatically adjust column counts based on window size.
  • If optimizing a form or text block: Wrap the component in a ConstrainedBox.
  • Apply BoxConstraints(maxWidth: [optimal_width]) to the ConstrainedBox.
  • Wrap the ConstrainedBox in a Center widget to keep the constrained content centered on large screens.
  • Run validator -> test on desktop/tablet target -> review horizontal stretching -> adjust maxWidth or grid extents.

Examples

Adaptive Layout using LayoutBuilder

Demonstrates switching between a mobile and desktop layout based on available width.

import 'package:flutter/material.dart';

const double largeScreenMinWidth = 600.0;

class AdaptiveLayout extends StatelessWidget {
  const AdaptiveLayout({super.key});

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        if (constraints.maxWidth > largeScreenMinWidth) {
          return _buildLargeScreenLayout();
        } else {
          return _buildSmallScreenLayout();
        }
      },
    );
  }

  Widget _buildLargeScreenLayout() {
    return Row(
      children: [
        const SizedBox(width: 250, child: Placeholder(color: Colors.blue)),
        const VerticalDivider(width: 1),
        Expanded(child: const Placeholder(color: Colors.green)),
      ],
    );
  }

  Widget _buildSmallScreenLayout() {
    return const Placeholder(color: Colors.green);
  }
}

Constraining Width on Large Screens

Demonstrates preventing a widget from consuming all horizontal space.

import 'package:flutter/material.dart';

class ConstrainedContent extends StatelessWidget {
  const ConstrainedContent({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ConstrainedBox(
          constraints: const BoxConstraints(
            maxWidth: 800.0, // Maximum width for readability
          ),
          child: ListView.builder(
            itemCount: 50,
            itemBuilder: (context, index) {
              return ListTile(
                title: Text('Item $index'),
              );
            },
          ),
        ),
      ),
    );
  }
}