Search code examples
flutterflutter-material

Flutter material3 how are colors calculated?


Recently I started using a theme with the material3 option.` I created a colorscheme using the Figma generator. I noticed components have a slightly different color. Dropdowns, cards and pagetitles are all a different color. What is more interesting, these colors do not occur in my colorscheme. For some reason I need to get the exact color used for dialog backgrounds. How are these colors created or calculated?

EDIT: For example, the background color of my dialogs is E4EDF7, which does not occur in my colour scheme. I did some searching in de source and comments say it uses the elevation and sufaceTint to get the color. Unfortunately I could not found how it is done.

Dropdowns are another color. In my case E9EFF7.

Color scheme:

const ColorScheme lightColorScheme = ColorScheme(
    brightness: Brightness.light,
    primary: Color(0xFF0061A4),
    onPrimary: Color(0xFFFFFFFF),
    primaryContainer: Color(0xFFD1E4FF),
    onPrimaryContainer: Color(0xFF001D36),
    secondary: secondairyLight,
    onSecondary: Color(0xFFFFFFFF),
    secondaryContainer: Color(0xFFD9E2FF),
    onSecondaryContainer: Color(0xFF001945),
    tertiary: Color(0xFF006494),
    onTertiary: Color(0xFFFFFFFF),
    tertiaryContainer: Color(0xFFCBE6FF),
    onTertiaryContainer: Color(0xFF001E30),
    error: Color(0xFFBA1A1A),
    errorContainer: Color(0xFFFFDAD6),
    onError: Color(0xFFFFFFFF),
    onErrorContainer: Color(0xFF410002),
    background: Color(0xFFFDFCFF),
    onBackground: Color(0xFF1A1C1E),
    outline: Color(0xFF73777F),
    onInverseSurface: Color(0xFFF1F0F4),
    inverseSurface: Color(0xFF2F3033),
    inversePrimary: Color(0xFF9ECAFF),
    shadow: Color(0xFF000000),
    surfaceTint: Color(0xFF0061A4),
    outlineVariant: Color.fromARGB(255, 232, 232, 232), //For divider
    scrim: Color(0xFF000000),
    surface: Color(0xFFFAF9FC),
    onSurface: Color(0xFF43474E), //Text (and icons if color from text)
    surfaceVariant: Color(0xFFDFE2EB),
    onSurfaceVariant: Color(0xFF43474E)
);

Solution

  • I have tried answering this question previously as well here https://stackoverflow.com/a/75391246/16569443

    Basically apart from color scheme, material3 works with different opacity of same color based on elevation. Ref. Design doc: https://m3.material.io/styles/elevation/tokens#61fc2883-15c8-439a-bea6-b24bb307146b Implementation map: https://github.com/flutter/flutter/blob/100cf21e27d82a881771fcf4934a3275fcada5f8/packages/flutter/lib/src/material/elevation_overlay.dart#L165

    How does it affects dialogs/dropdown etc? Many of the flutter widgets used a widget internally called 'Material'. This widget is dependent on elevation to provide surface tint. https://github.com/flutter/flutter/blob/fda9ecfef76b57ae459675fdf262342a77c2c6ba/packages/flutter/lib/src/material/material.dart#L502

    Because these colors are generate at runtime for every color scheme, you won't find color references. Again, you might ask if only opacity is changed, why there is different color? As you may see, there is Color.alphaBlend method called, this creates a color which resembles same color with 1 opacity.