material_design 0.28.1

SDKflutter
Platformandroidioswindowslinuxmacosweb

The fastest path to consistent Material Design UIs in Flutter. Build beautiful apps aligned with official metrics and guidelines using a powerful set of ready-to-use design tokens and helper widgets.

Material Design 3 for Flutter

pub version license Flutter Version

🎨 A complete Material Design 3 design system implementation for Flutter

A comprehensive design system toolkit that brings Google's Material Design 3 specifications to Flutter through a carefully architected token system.

🚀 Live Demo & Resources

🌟 Interactive Design System Explorer - Explore all tokens with live examples

📚 Material Design 3 Guidelines - Official specification

📦 Installation

dependencies:
  material_design: ^0.28.1

🎯 Three Ways to Use This Library

✅ The Right Way: Material Design 3 Compliant

Use M3 wrapper classes that enforce design system rules while maintaining const performance.

// Best approach - follows M3 specs with const performance
// Motion example - impossible to mismatch
return AnimatedContainer(
  duration: M3Motion.emphasized.duration, // Always correct pairing   (non-const)
  curve: M3Motion.emphasized.curve,       // Follows M3 specs exactly (non-const)
   // M3EdgeInsets enforces token usage + const
  padding: const M3EdgeInsets.all(M3SpacingToken.space16), // (const)

  // M3ShapeDecoration ensures all properties follow M3
  decoration: M3ShapeDecoration(
    shape: M3Shape.medium,                                         // (const)
    boxShadow: M3Elevation.level3.shadows,                         // (non-const)
    color: M3Elevation.level3.surfaceColor(context),               // (non-const)
  ),

  child: const Text(
    'Perfect M3 Implementation',
    style: Theme.of(context).textTheme.headlineMedium,             // (non-const)
  ),
);

Why this is best:

  • ✅ Forces Material Design 3 compliance
  • ✅ Type-safe token usage
  • ✅ Const performance where possible
  • ✅ Impossible to break design system rules

⚠️ The Flexible Way: Trading Compliance for Freedom

Use const tokens directly with Flutter widgets. More flexible but can break M3 guidelines.

// Intermediate approach - flexible but can violate M3
AnimatedContainer(
  duration: M3MotionDuration.long2, // ⚠️ Is this the right duration? (const)
  curve: M3MotionCurve.standard,    // ⚠️ Wrong curve for long2!      (const)
  // Using const tokens but might mix incorrectly
  padding: const EdgeInsets.all(M3Spacings.space16), // (const)

  decoration: ShapeDecoration(
    borderRadius: M3Shape.medium,                    // (const)
    boxShadow: M3ElevationShadows.level3,            // (const)
    color: M3Elevation.level3.surfaceColor(context), // (non-const)
  ),

  child: const Text(
    'Partial M3 Implementation',
    style: M3TextStyle.headlineMedium,               // (const)
  ),
);

Trade-offs:

  • ⚠️ Can mix incompatible tokens
  • ⚠️ May violate M3 specifications
  • ✅ More flexibility for custom designs
  • ✅ Still has const performance

❌ The Wrong Way: Worst of Both Worlds

Using token enums with .value - loses const performance AND design system benefits.

// DON'T DO THIS - no benefits, only drawbacks
Container(
  // ❌ Lost const performance
  padding: EdgeInsets.all(M3SpacingToken.space16.value), // (non-const)

  decoration: BoxDecoration(
    // ❌ Still not const
    borderRadius: BorderRadius.circular(M3CornerToken.medium.value), // (non-const)

    // ❌ Can still break M3 rules
    boxShadow: [
      BoxShadow(
        offset: const Offset(0, 2),  // ❌ Random shadow values
        blurRadius: M3SpacingToken.space4.value,  // ❌ Why use spacing for blur?
      ),
    ],
    color: Colors.purple, // ❌ Missing surface tint. Not M3 surface color! (const)
  ),

  child: Text(
    'Worst Implementation',
    // ❌ Mixing approaches inconsistently
    style: TextStyle(fontSize: 17),
  ),
);

Why this is wrong:

  • ❌ No const performance (using .value)
  • ❌ No design system enforcement
  • ❌ Verbose without benefits
  • ❌ Easy to misuse tokens

📖 How to Use Each Class

✅ 🎯 Design System Classes (Use These First - M3 Compliant)

Typography & Text

ClassPurposeExample
M3TextStyleComplete typography scaleText('Hello', style: M3TextStyle.headlineMedium)
displayLarge, displayMedium, displaySmallDisplay text styles
headlineLarge, headlineMedium, headlineSmallHeadline text styles
titleLarge, titleMedium, titleSmallTitle text styles
bodyLarge, bodyMedium, bodySmallBody text styles
labelLarge, labelMedium, labelSmallLabel text styles

Spacing & Layout

ClassPurposeExample
M3EdgeInsetsType-safe padding/margin with constconst M3EdgeInsets.all(M3SpacingToken.space16)
.all(), .symmetric(), .only()Different padding patterns
.fromLTRB()Custom directional padding
M3PaddingPre-configured padding widgetM3Padding.all(token: M3SpacingToken.space16, child: widget)
.symmetric(), .only()Directional padding widgets
M3GapAuto-directional spacing in FlexColumn(children: [widget1, M3Gap(M3SpacingToken.space16), widget2])
Automatically switches between width/heightBased on parent Row/Column
horizontal4 to horizontal48Horizontal spacers
vertical4 to vertical48Vertical spacers

Shape & Borders

ClassPurposeExample
M3ShapeRoundedRectangleBorder shapesCard(shape: M3Shape.medium)
none, extraSmall, small0dp, 4dp, 8dp corners
medium, large, extraLarge12dp, 16dp, 28dp corners
fullCircular/stadium shape
M3BorderRadiusBorderRadius for containersContainer(decoration: BoxDecoration(borderRadius: M3BorderRadius.medium))
none, extraSmall, small0dp, 4dp, 8dp radius
medium, large, extraLarge12dp, 16dp, 28dp radius
fullCircular radius
M3RadiusIndividual Radius valuesClipRRect(borderRadius: BorderRadius.all(M3Radius.medium))
Same variants as BorderRadiusFor individual corner control
M3BorderSideBorder side configurationsBorder(top: M3BorderSide.thin(color: Colors.grey))
.none(), .thin(), .medium(), .thick()0dp, 1dp, 2dp, 4dp widths
M3BorderComplete border specificationsContainer(decoration: BoxDecoration(border: M3Border.all(color: Colors.grey)))
.all(), .symmetric()Full and partial borders

Decorations

ClassPurposeExample
M3ShapeDecorationShape-based decorationM3ShapeDecoration(shape: M3Shape.medium, color: Colors.blue)
Enforces M3 shape tokensWith elevation and shadows
M3BoxDecorationBox-based decorationM3BoxDecoration(borderRadius: M3BorderRadius.medium, color: Colors.blue)
Enforces M3 border radius tokensWith elevation and shadows

Elevation & Shadows

ClassPurposeExample
M3ElevationComplete elevation systemM3Elevation.level3
.dp propertyAccess elevation dp value
.shadows propertyAccess shadow list
.surfaceColor(context) methodGet tinted surface color
level0 to level50dp, 1dp, 3dp, 6dp, 8dp, 12dp

Motion & Animation

ClassPurposeExample
M3MotionPaired duration + curveAnimatedContainer(duration: M3Motion.emphasized.duration, curve: M3Motion.emphasized.curve)
emphasized500ms with emphasized curve
emphasizedIncoming400ms with decelerate curve
emphasizedOutgoing200ms with accelerate curve
standard300ms with standard curve
standardIncoming250ms with decelerate curve
standardOutgoing200ms with accelerate curve
linear200ms with linear curve

Responsive Layout

ClassPurposeExample
M3ResponsiveBuilderRebuilds on size changeM3ResponsiveBuilder(builder: (context, screenSize) => ...)
M3ResponsiveValue<T>Returns value by sizeM3ResponsiveValue(compact: 2, medium: 3, expanded: 4).get(context)
M3ResponsiveVisibilityShow/hide by screen sizeM3ResponsiveVisibility(visibleOn: [M3ScreenSize.expanded], child: widget)
M3ResponsiveGridAdaptive grid layoutM3ResponsiveGrid(children: widgets, maxCrossAxisExtent: 200)
M3ResponsiveScaffoldAdaptive navigationM3ResponsiveScaffold(destinations: [...], body: widget)
M3ResponsiveGridConfigGrid configurationM3ResponsiveGridConfig.fromScreenSize(screenSize)
M3ResponsiveNavigationNavigation type selectorM3ResponsiveNavigation.getNavigationType(screenSize)

Available Token Enums (Use wrapper classes instead)

EnumWrapper Class AlternativeBest Practice
M3SpacingTokenM3EdgeInsets, M3Padding, M3GapUse wrappers for type safety
M3CornerTokenM3Shape, M3BorderRadius, M3RadiusUse shape classes
M3OpacityTokenDirect M3Opacities valuesUse const values
M3IconSizeTokenDirect M3IconSizes valuesUse const values
M3MarginTokenM3Margins.getMargin(context)Use responsive method
M3BorderWidthTokenM3BorderSide, M3BorderUse border classes
M3StateLayerOpacityTokenDirect M3StateLayerOpacities valuesUse const values
M3BreakpointTokenM3ResponsiveBuilder, M3ScreenSizeUse responsive utilities
M3ZIndexTokenDirect M3ZIndexes valuesUse const values

🔧 Helper Functions & Utilities

UtilityPurposeExample
M3ScreenSizeGet current screen size classificationfinal size = M3ScreenSize.fromContext(context)
M3SurfaceTint.fromElevation()Calculate tinted surface colorcolor: M3SurfaceTint.fromElevation(context, M3ElevationDps.level3)
M3Margins.getMargin()Get responsive marginpadding: EdgeInsets.all(M3Margins.getMargin(context))
Extension methodsVarious Flutter widget extensionsApplied automatically when imported

✅ ⚠️ For Maximum Flexibility: Using const Tokens Directly

Spacing & Layout Tokens

Token ClassValuesUsage
M3Spacingsspace0, space2, space4, space8, space12, space16, space24, space32, space48const EdgeInsets.all(M3Spacings.space16)
M3MarginscompactScreen (16dp), mediumScreen (24dp), expandedScreen (32dp), largeScreen (40dp), extraLargeScreen (48dp)EdgeInsets.symmetric(horizontal: M3Margins.compactScreen)
M3SpacersPre-built spacer widgetsM3Spacers.horizontal16
M3IconSizesextraSmall (18dp), small (20dp), medium (24dp), large (36dp), extraLarge (40dp), huge (48dp)Icon(Icons.star, size: M3IconSizes.medium)
M3VisualDensityminimumDensity (-3), compactDensity (-2), standardDensity (0), comfortableDensity (0)Theme(visualDensity: VisualDensity(horizontal: M3VisualDensity.standardDensity))
M3ZIndexesbehind (-1), base (0), dropdown (10), sticky (100), modal (1000), tooltip (9999)Stack(children: [Positioned(z: M3ZIndexes.modal, child: widget)])

Shape & Border Tokens

Token ClassValuesUsage
M3Cornersnone (0dp), extraSmall (4dp), small (8dp), medium (12dp), large (16dp), extraLarge (28dp), full (circular)Radius.circular(M3Corners.medium)
M3BorderWidthsnone (0dp), thin (1dp), medium (2dp), thick (4dp)Border.all(width: M3BorderWidths.thin)

Motion Tokens

Token ClassValuesUsage
M3MotionDurationshort1-4 (50-200ms), medium1-4 (250-400ms), long1-4 (450-600ms), extraLong1-4 (700-1000ms)AnimatedContainer(duration: M3MotionDuration.medium2)
M3MotionCurveemphasized, emphasizedAccelerate, emphasizedDecelerate, standard, standardAccelerate, standardDecelerate, linearAnimatedContainer(curve: M3MotionCurve.emphasized)

Visual Effect Tokens

Token ClassValuesUsage
M3Opacitiesopacity4 (0.04), opacity8 (0.08), opacity12 (0.12), opacity16 (0.16), opacity38 (0.38), opacity54 (0.54), opacity87 (0.87)Opacity(opacity: M3Opacities.opacity38)
M3StateLayerOpacitieshover (0.08), focus (0.12), pressed (0.12), dragged (0.16)Container(color: color.withOpacity(M3StateLayerOpacities.hover))
M3ElevationDpslevel0 (0dp), level1 (1dp), level2 (3dp), level3 (6dp), level4 (8dp), level5 (12dp)Material(elevation: M3ElevationDps.level3)
M3ElevationShadowslevel0, level1, level2, level3, level4, level5BoxDecoration(boxShadow: M3ElevationShadows.level3)

Responsive Tokens

Token ClassValuesUsage
M3Breakpointscompact (0dp), medium (600dp), expanded (840dp), large (1200dp), extraLarge (1600dp)if (width > M3Breakpoints.medium) ...

⚠️ Token Enums (Avoid Using .value Directly)

❌ Why to Avoid

❌ Don't Do This⚠️ Problem✅ Do This Instead
M3SpacingToken.space16.valueLoses const performanceM3Spacings.space16 or M3EdgeInsets.all(M3SpacingToken.space16)
M3CornerToken.medium.valueNo design system benefitM3Corners.medium or M3Shape.medium
M3OpacityToken.opacity38.valueVerbose without advantageM3Opacities.opacity38
M3IconSizeToken.medium.valueNot constM3IconSizes.medium
M3MarginToken.compactScreen.valueRuntime calculationM3Margins.compactScreen or M3Margins.getMargin(context)
M3BorderWidthToken.thin.valueNo type safetyM3BorderWidths.thin or M3BorderSide.thin()

🎯 Summary

Choose Your Approach

  1. Need Material Design 3 compliance? → Use M3 wrapper classes
  2. Need flexibility with good performance? → Use const tokens directly
  3. Never do this → Don't use .value on token enums

Performance vs Compliance Matrix

ApproachM3 CompliancePerformanceFlexibilityRecommendation
M3 Classes✅ Perfect✅ Const where possible⚠️ LimitedUse this
Const Tokens⚠️ Manual✅ Full const✅ HighUse when needed
Token.value❌ None❌ No const⚠️ MediumAvoid

📊 Complete Token and Utility Reference

Design Tokens

These are constant values that form the foundation of your design system, ensuring consistency across spacing, colors, typography, and more.

🟢 CONST Design Tokens

Use these with const keyword for best performance:

GroupTokenClass (const)PurposeExample ValuesHow to Use
Layout & SpacingSpacingM3Spacings4dp grid system for consistent spacingspace0 (0dp), space2 (2dp), space4 (4dp), space8 (8dp), space12 (12dp), space16 (16dp), space24 (24dp), space32 (32dp), space48 (48dp)const EdgeInsets.all(M3Spacings.space16)
MarginM3MarginsResponsive container marginscompactScreen (16dp), mediumScreen (24dp), expandedScreen (32dp), largeScreen (40dp), extraLargeScreen (48dp)const EdgeInsets.symmetric(horizontal: M3Margins.compactScreen)
SpacerM3SpacersPre-built spacer widgetshorizontal4, horizontal8, horizontal16, vertical4, vertical8, vertical16, etc.M3Spacers.horizontal16
Icon SizeM3IconSizesStandardized icon dimensionsextraSmall (18dp), small (20dp), medium (24dp), large (36dp), extraLarge (40dp), huge (48dp)Icon(Icons.star, size: M3IconSizes.medium)
Visual DensityM3VisualDensityUI density configurationsminimumDensity (-3), compactDensity (-2), standardDensity (0), comfortableDensity (0)VisualDensity(horizontal: M3VisualDensity.standardDensity)
Z-IndexM3ZIndexesValues for layer stacking orderbehind (-1), base (0), dropdown (10), sticky (100), modal (1000), tooltip (9999)Positioned(child: widget, zIndex: M3ZIndexes.modal)
ResponsiveBreakpointM3BreakpointsBreakpoints for responsive designcompact (0dp), medium (600dp), expanded (840dp), large (1200dp), extraLarge (1600dp)if (width > M3Breakpoints.medium) ...
Motion & AnimationMotion DurationM3MotionDurationDuration for animationsshort1 (50ms), short2 (100ms), short3 (150ms), short4 (200ms), medium1 (250ms), medium2 (300ms), medium3 (350ms), medium4 (400ms), long1 (450ms), long2 (500ms), long3 (550ms), long4 (600ms), extraLong1 (700ms), extraLong2 (800ms), extraLong3 (900ms), extraLong4 (1000ms)AnimatedContainer(duration: M3MotionDuration.medium1)
Motion CurveM3MotionCurveEasing curves for animationsemphasized, emphasizedAccelerate, emphasizedDecelerate, standard, standardAccelerate, standardDecelerate, linearAnimatedContainer(curve: M3MotionCurve.emphasized)
MotionM3MotionCombined duration + curve settingsemphasized, emphasizedIncoming, emphasizedOutgoing, standard, standardIncoming, standardOutgoing, linearSee non-const section
Color & OpacityOpacityM3OpacitiesGeneral transparency valuesopacity4 (0.04), opacity8 (0.08), opacity12 (0.12), opacity16 (0.16), opacity38 (0.38), opacity54 (0.54), opacity87 (0.87)Opacity(opacity: M3Opacities.opacity38)
State LayerM3StateLayerOpacitiesOverlays for interactive stateshover (0.08), focus (0.12), pressed (0.12), dragged (0.16)Container(color: color.withOpacity(M3StateLayerOpacities.hover))
Shape & BorderCornerM3CornersIndividual corner valuesnone (0dp), extraSmall (4dp), small (8dp), medium (12dp), large (16dp), extraLarge (28dp), full (circular)Radius.circular(M3Corners.medium)
RadiusM3RadiusIndividual corner radius valuesnone, extraSmall, small, medium, large, extraLarge, circularM3Radius.medium
Border RadiusM3BorderRadiusComplete border radius for containersnone, extraSmall, small, medium, large, extraLarge, fullBoxDecoration(borderRadius: M3BorderRadius.medium)
ShapeM3ShapeBorder shapes for componentsnone, extraSmall, small, medium, large, extraLarge, fullCard(shape: M3Shape.medium)
Border WidthM3BorderWidthsBorder thickness valuesnone (0dp), thin (1dp), medium (2dp), thick (4dp)Border.all(width: M3BorderWidths.thin)
Border SideM3BorderSideIndividual border sidesPre-configured border side configurationsM3BorderSide.thin(color)
BorderM3BorderComplete border specificationsPre-configured bordersM3Border.all(color: Colors.grey)
Elevation & ShadowElevation DPM3ElevationDpsSurface elevation values in dplevel0 (0dp), level1 (1dp), level2 (3dp), level3 (6dp), level4 (8dp), level5 (12dp)Material(elevation: M3ElevationDps.level3)
ShadowM3ElevationShadowsBox shadow configurationslevel0, level1, level2, level3, level4, level5BoxDecoration(boxShadow: M3ElevationShadows.level3)
ElevationM3ElevationComplete elevation (dp + shadows)level0, level1, level2, level3, level4, level5 - each contains both dp value and shadow listM3Elevation.level3 (access .dp and .shadows properties)
TypographyText StyleM3TextStyleComplete typography scaledisplayLarge, displayMedium, displaySmall, headlineLarge, headlineMedium, headlineSmall, titleLarge, titleMedium, titleSmall, bodyLarge, bodyMedium, bodySmall, labelLarge, labelMedium, labelSmallText('Hello', style: M3TextStyle.bodyLarge)

🔵 NON-CONST Tokens (Enums and Functions)

Use these WITHOUT const keyword - values calculated at runtime:

GroupTokenEnum/FunctionWhy it's not constHow to Use
Layout & SpacingSpacingM3SpacingTokenEnum returns value via getterfinal space = M3SpacingToken.space16.value;
MarginM3MarginTokenEnum returns value via getterfinal margin = M3MarginToken.compactScreen.value;
SpacerM3SpacerTokenEnum returns widget via getterM3SpacerToken.horizontal16.spacer
Icon SizeM3IconSizeTokenEnum returns value via getterfinal size = M3IconSizeToken.medium.value;
Z-IndexM3ZIndexTokenEnum returns value via getterfinal zIndex = M3ZIndexToken.modal.value;
ResponsiveBreakpointM3BreakpointTokenEnum returns value via getterfinal breakpoint = M3BreakpointToken.medium.value;
Margin (method)M3Margins.getMargin()Varies with screen sizefinal margin = M3Margins.getMargin(context);
Motion & AnimationMotion M3Motion.x.duration M3Motion.x.curveObject with duration and curve propsfinal motion = M3Motion.emphasized;
duration: motion.duration,
curve: motion.curve,
Color & OpacityOpacityM3OpacityTokenEnum returns value via getterfinal opacity = M3OpacityToken.opacity38.value;
State LayerM3StateLayerOpacityTokenEnum returns value via getterfinal opacity = M3StateLayerOpacityToken.hover.value;
Surface TintM3SurfaceTint.fromElevation()Depends on theme/contextfinal color = M3SurfaceTint.fromElevation(context, M3ElevationDps.level3);
Shape & BorderCornerM3CornerTokenEnum returns value via getterfinal corner = M3CornerToken.medium.value;
Border WidthM3BorderWidthTokenEnum returns value via getterfinal width = M3BorderWidthToken.thin.value;
Elevation & ShadowElevationM3Elevation.x.dp M3Elevation.x.shadows M3Elevation.x.surfaceColor()Enum with multiple gettersfinal elev = M3Elevation.level3.value;
final shadows = M3Elevation.level3.shadows;
final surface = M3Elevation.level3.surfaceColor(context);

Utility & Helper Classes

These are classes that help apply design tokens in a type-safe and responsive way.

GroupUtility / ClassPurposeCommon Use Case
Layout HelpersM3EdgeInsetsType-safe padding/marginEnforces use of spacing tokens
M3PaddingPre-configured padding widgetConsistent padding application
M3GapSpacing between flex children (Row/Column)Row/Column spacing
Decoration HelpersM3BoxDecorationType-safe box decorationEnforces use of all style tokens
M3ShapeDecorationType-safe shape decorationEnforces use of all style tokens
Responsive BuildersM3ResponsiveBuilderResponsive widget builderRebuilds on screen size class change
M3ResponsiveValueResponsive value selectionDefines different values per breakpoint
M3ResponsiveVisibilityConditional visibilityShows/hides based on screen size
M3ResponsiveGridResponsive grid layoutAdaptive columns and spacing
M3ResponsiveScaffoldAdaptive navigation scaffoldBottom nav → Rail → Drawer
Responsive LogicM3ScreenSizeWindow size classificationCompact, Medium, Expanded, etc.
M3ResponsiveGridConfigGrid layout configurationColumns, gutters, margins
M3ResponsiveNavigationNavigation pattern selectionDetermines nav type by size

📚 Further Reading

📄 License

BSD License - see LICENSE file


Building consistent, beautiful Flutter apps with Material Design 3