This chapters provides deeper and more detailed information and explanations on included topics. It will receive updates and new deep dives as needed in future updates based on questions user of FlexColorScheme have.
This chapter may contain images and animations from older versions of FlexColorScheme. They are used when the principles presented are still the same and the actual images matter less. Future version of this chapter may update the images to current version of FlexColorScheme, if it is needed to improve the explanations.
Examples 3,4 and 5 in this package use comfortable adaptive platform visual
FlexColorScheme.comfortablePlatformDensity, instead of the
default counter application's
This is an alternative visual density design that on desktop applications
results in the Flutter
comfortable visual density being used, instead of
compact. On devices, they both result in the default large
visual density that is suitable for small touch devices.
This helper function was added to provide an easy option for using a bit larger UI elements on desktop and web apps, while keeping the correct size for devices.
If the desktop and web versions of the app is used on computers with touch
comfortable density provides a nice balance. It still looks
compact enough to be desktop like, while providing a bit more touch friendly
space, without looking like an overblown small device UI on a desktop.
FlexColorScheme can also use the
If you prefer it, just replace the line with it. If you do not specify any
visual density, the Flutter default density
standard is used on
all platforms. This creates widgets with a lot of white space around and
inside them. It may not be what you want on web/desktop applications, but is
the correct choice for small touch devices. The visual density feature in
Flutter was created to address this difference in design requirement.
The Flutter SDK built-in function
was added to adapt the density according to used platform. The
FlexColorScheme.comfortablePlatformDensity does the same, but with a bit
more white space on desktops. Use the one you like and works best for
your use case.
One feature on the
HomePage of examples 1 to 4 is the
It is the UI Widget used for the 3-way theme mode switch used in these
examples to change the active theme mode.
Using the switch is simple, give it the currently selected and active theme
mode, the current
FlexSchemeData scheme, so it can color its buttons correctly.
Then use the
onThemeModeChanged callback for changes to its mode, and change
themeMode property in the
MaterialApp accordingly, to actually change
the used theme mode.
FlexThemeModeSwitch( themeMode: themeMode, onThemeModeChanged: onThemeModeChanged, flexSchemeData: flexSchemeData, ),
FlexThemeModeSwitch 3-way theme mode switch is optional and not
required to use
FlexColorScheme based themes. It is just a custom theme mode
switch design and was included as a bonus feature in the
FlexColorScheme package. It was added based on a request after it
had been observed in the wild in the Flexfold demo app.
In the Flexfold demo app the switch was originally a fairly fixed design.
FlexThemeModeSwitch has many properties that allow you to customize
it extensively. You can find its API
reference here and its companion, the
FlexThemeModeOptionButton API reference here.
With the API you can customize the look of the
here are some examples:
FlexThemeModeOptionButton is typically used by the
but it can also be used as a part of other theme related indicator widgets.
Like for example the scrolling horizontal list used in example 5, where it is
used as a theme indicator and selector in a horizontally scrolling list.
Example 5 allows us to toggle the dark mode, from using its hand tuned predefined dark scheme colors, to the dark scheme colors computed from the light scheme colors. Let's use it to compare some examples.
When using the Deep blue sea scheme, the computed dark theme colors ones are a bit more dull and muted in this example, the computed dark scheme is on the right.
|Designed dark Deep blue see theme (left) versus computed dark theme (right) from its light theme.|
With some other color schemes, like the Aqua blue one, there is only a minor difference, the computed dark scheme is on the right.
|Designed dark Aqua blue theme (left) versus computed dark theme (right) from its light theme.|
The result of the
toDark method varies depending on how saturated the used
light scheme colors are. It is possible to tune the calculated dark scheme by
whiteBlend property it uses to blend in white to make the
dark scheme. The default
whiteBlend is 35%, this is normally a suitable
value. For more saturated light scheme colors try 40%, which is also used in
the Material 2 design guide to convert the default red error color for light
mode, to dark mode. For light scheme color with low saturation, a white
blend of 20...30% often produces nice results.
With the included level slider in the example 5 we can interactively change
whiteBlend level for the computed dark mode scheme colors. Let's select
a color scheme, say the Brand blues one, then go dark.
By default, the built-in predefined hand-picked matching dark scheme colors for the dark theme mode are used. Turn on the "Compute dark theme" mode, the result is pretty close to the predefined one for this dark scheme with the default level of 35%. Then adjust the white level blend to tune how saturated the computed dark scheme colors are compared to their light scheme master. At 0% they are the same as the light scheme, at 100%, well then they are white, not so useful. A range of 10...50% can produce excellent results. What is best depends on how saturated your starting light scheme colors are, and of course what kind of matching dark theme look you like and want.
If you use the even darker dark-mode, true black, you may want to have a different saturation for your dark scheme colors compared to standard dark-mode surface. You could easily implement that adjustment with this feature.
This screen recording compares the computed
toDark theme result, to the
built-in hand-picked one. It does this by toggling the mode a few times, so
you can compare the different results. It also uses the level slider
to adjust the
toDark theme result. A sharp eye might notice that this
recording does not use the
defaultError error color modifier, the changing
dark error color does not look so nice when tuning the computed scheme colors.
The bundled example 5 and live web version of it uses the modifier.
So that you can find the same setup in the new version 5 of the ThemesPlayground,
here is an image of it when using the same
and computing the dark theme from light one at level 35%. You can see the code
in the image too, the key part is this:
darkTheme: FlexThemeData.dark( colors: FlexColor.schemes[FlexScheme.brandBlue]! .light.defaultError.toDark(35, false),
In FlexColorScheme v5 that has container colors for each main color
ColorScheme, a new way to produce the computed dark mode colors was added.
If you in dark mode, swap main and container colors, the colors will usually work
well as they are in dark mode, at least if
you followed the design principle for main color and its container color in light
You can then pass 'true' to the toDark method, indicating you have a "true" M3
light theme mode ColorScheme design. The
toDark computation will swap the
colors from the light mode colors, and use it as a starting point for the
dark theme mode. This also produces a more design correct dark mode,
with respect to the shade tones used on main color and its container color.
You may not even need to add any white blend level to de-saturate the colors.
Below we use 5% to demonstrate that you can.
darkTheme: FlexThemeData.dark( colors: FlexColor.schemes[FlexScheme.brandBlue]! .light.defaultError.toDark(5, true),
If your light theme mode colors follow the M3 design intent, then always use
toDark(level, true) API. If you on the other have colors that are designed
with older M2 design intent, then using
toDark(level) as before, which
toDark(level, false) is usually a better choice.
Let's study what
FlexColorScheme can do with the
AppBarTheme and how you
can match it to your surface blending if you like.
You can easily toggle both dark and light mode AppBars to use differently
themed backgrounds. By default, Material design uses AppBars with
ColorScheme.primary color for light theme mode, and the dark background
color in dark theme mode. Without using a separately defined sub
FlexColorScheme AppBars can use different themed backgrounds based on
an enum value.
AppBar background can use scheme primary color, default Material
plain white/dark background color, primary branded surface, primary branded
background color, or a custom AppBar color.
appBarColor is a separate scheme color that
does not exist in Flutter's standard
ColorScheme, so it does not have to be
any of the colors available in a
The predefined schemes use the color defined in a
tertiary color, as their value for the custom
When you make your own schemes you can do the same or use a totally
ColorScheme related color as the AppBar's custom color option. This
color then becomes one of the FlexColorScheme's easy selectable AppBar theme
color option, via the
appBarStyle property and the
in this case via the
Below you can see some different primary color blend level using background colors used as the themed AppBar background color.
|Using background colored AppBar theme, that includes the primary color blend at different levels in the background|
tabBarStyle property can be used to toggle the theme the
receives. By default, a theme that is designed to make it fit in an
regardless of which style you have selected for it, is used. This is the
FlexTabBarStyle.forAppBar style. The typical usage of a
TabBar is to have
it in an
AppBar, and the default style works for this use case.
Alternatively you can choose a style that makes a
TabBarTheme that fits well
on background colors. Use this option if you intend to use the
TabBar in a
Scaffold body, in Dialogs, Drawers or other surface and
background colored Material. If you do so, you do not have re-theme it, or
style it separately for this purpose.
If you intend to use
TabBar widgets in both AppBars and on surface and
backgrounds, you will have to choose the style that most often fits your
use case. Then theme it separately for the other use case. You would have to do
the same with Flutter standard themes and
TabBarTheme as well when not
using FlexColorScheme, but the first theme your get without effort.
tabBarStyle style and resulting
TabBarTheme actually works best,
depends on the background color. Here we see TabBars used on surfaces and in
AppBar, when the AppBar is using primary color. As can be seen, the tab bar
theme that goes well in an app bar in such a case, does not fit on the surfaces
at all, and wise versa.
If you plan to use only surface or background (also the branded ones) colored AppBars, you can see that both TabBar styles, and their resulting themes, work for both situations. The difference is minor, and it is a matter of opinion which one is preferable. Both style options can be used if you restrict your AppBar color to background and surface colors, or their primary branded variants. In such a use case you can get away with using just one of the built-in style options, even if you use TabBars in both AppBars and on other surfaces.
Dark-mode is cool and with
FlexColorScheme you can go even darker. Go true black with the flick of a
switch. When using the true black option for dark-mode, surface, background and scaffold background are set to
fully black. This can save power on OLED screens as the pixels are turned off, but it can also cause scrolling artefact
issues when pixels turn fully on and off rapidly as you scroll. You can read about this and see an example of it in
the Material design guide
as well. (Scroll back up one heading from the link to get to the mention of it.)
If you use surface blends with true black mode enabled, you will notice that the surface blends have a lower impact, only at higher blend levels does it have a visible effect. This is by design to keep most surfaces totally or very close to black when true black is combined with surface blends. If you really want complete black for all surfaces and backgrounds, then avoid combining true black mode with blended surfaces. On the other hand it still makes a much darker theme than normal dark theme, which can look nice. It may also eliminate the scrolling issue, since all background colored pixels are not fully off in the true black modes when you use higher blend levels.
Here is an example of a branded dark theme with true black OFF (default) and true black ON, when using high surface blend level with the Red red wine color scheme.
|Comparing true black OFF (left) and ON (right), with the Red red wine scheme.|
Here is another difference example with the Deep blue sea scheme, when using mid level blends, and a primary colored AppBar in dark-mode.
|Comparing true black OFF (left) and ON (right), with the Deep blue sea scheme.|