-
Notifications
You must be signed in to change notification settings - Fork 26.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
theme_data largely ignores primarySwatch when brightness is set to dark #19089
Comments
This is something that confused me too. Is that done on purpose? And just for clarification (@InsanityOnABun already said it implicitly): This also applies to |
I ran into this as well. Ideally, one should be able to create reasonable themes using only new ThemeData(brightness: Brightness.light, primarySwatch: Colors.red); // light theme
new ThemeData(brightness: Brightness.dark, primarySwatch: Colors.red); // dark theme |
Any update on this? |
Bumping this issue. Is this really intended? |
This is a really weird issue! Can anyone explain the motivation behind this ? Was stuck on this for hours and was only able to figure this out by going through flutter source. |
For anyone else encountering this issue, I used the above properties to get dark theme with correct colors for my app (calculations are taken from the flutter source). |
Reproducible on latest master Minimal reproducible sample
flutter doctor -v
|
any progress? this makes implementing a properly looking dark mode much harder |
I'm getting the same issue:
I expect the color will be orange but it's tea instead. |
Due to Our users select a theme color, such as red, but when in dark mode it switches to teal. The current behavior is very difficult to reason with. I see nothing in material spec that says the only color allowed in dark mode is teal. @willlarche In another thread #26323 (comment) it was said that this can't be changed because of downstream goldens. I would argue that this is not a valid reason to keep this behavior since the solution for people with broken goldens would be to make their dark theme primarySwatch teal. The friction to fix goldens is much lower than the friction to build new apps with the current behavior. @HansMuller Net benefit is strongly in favor of fixing this behavior to ensure that dark mode color matches the theme color. |
PrimarySwatch is a vestigial api from earlier versions of this library before Material Theming had a proper spec. It was a great way to get a headstart on theming but it now operates only as it was written many years ago and there is no requirements document to update it to. @HansMuller can we consider deprecating this API? |
I think it makes sense to provide an easy way to change the main color of an app. Even the current default counter app advertises |
@willlarche color is an area of Material that I feel like I could spend months trying to unravel. I'd love to connect with you offline to try to better understand how to align the Flutter APIs to material spec as I think they are missing the mark at the moment. It's almost impossible to figure out what widgets use which part of ThemeData and a lot of widgets are applying their own colors. We have multiple ways to get color systems and none of them are complete, and all of them have weird behaviors like the one covered by this issue. Right now we can specify a primary swatch and broad-brush theme an app to a specific brand color. It works pretty well. Without that, I'm not sure what's left for simple theming? I'd love to get your ideas for a new Is this the goal? from https://material.io/design/color/the-color-system.html I believe this is covered by Color primary
Color primaryVariant
Color secondary
Color secondaryVariant
Color surface
Color background
Color error
Color onPrimary
Color onSecondary
Color onSurface
Color onBackground
Color onError
Brightness brightness |
@lukepighetti Material Theming is indeed not perfect (in spec or any platform) and we hope to continue improving it in the future at the requirements level. In regards to Flutter's implementation, yes, @HansMuller was just reminding me that we have debt for completing the integration of ColorScheme throughout the system and we're going to look into what that entails. He's done a great job getting it in some of the hardest places and we'll see about the rest of it. For this particular issue, I agree that Teal is not ideal. We could help come up with another solution but it would not be based on official Material Theming spec. I still think it's worth figuring out how to remove PrimarySwatch (and @miDeb removing it from code examples as well) but I totally defer to @HansMuller . Hans, what you thinking? |
This comment has been minimized.
This comment has been minimized.
Our long term plan for cleaning up the use of color is documented in: https://flutter.dev/go/material-theme-system-updates And tracked in #91772. We have made a lot of progress migrating components to use For Material 3 we have added the ability to generate a full ColorScheme (either light or dark) from a single seed color, which will hopefully help replace the primarySwatch. In addition, as we have been migrating components to Material 3, they will all use ColorScheme colors by default. You can track this work in #91605. As this is being addressed in the mentioned issues, I am going to close this issue. |
I believe that a new user should be able to get a reasonable dark mode experience with: ThemeData(
brightness: Brightness.dark,
primarySwatch: Colors.red,
), Let's compare this with light mode and dark mode on current master branch As you can see, dark mode is using an unexpected teal color. It has been this way since the beginning, and continues to be this way. The expected result is for the red color to be used. This issue is not resolved and I would urge you to reopen it until it is cc @darrenaustin |
One possible solution is to deprecate ThemeData(
brightness: Brightness.dark,
colorSchemeSeed: Colors.red,
), Current master branch |
Roads to ThemeDataYeah this is a bit tricky, I agree @lukepighetti. I have been a proponent for simpler ways for users to get a It will get a bit better, once all of this #91772, is ready and lands, plus all the new M3 theming ways, but even all the new ways to make Any method that is You have to either create the Below a few comparisons to highlight the issues. ThemeData(colorSchemeSeed)Making ThemeData from a seed color like you did above is nice, if you go for the M3 style. However, this particular method that you used, even if very new, is also a bit flawed, not only for your mentioned reason. title: '7) TD colorSchemeSeed',
theme: ThemeData(
brightness: Brightness.light,
colorSchemeSeed: Colors.red,
),
darkTheme: ThemeData(
brightness: Brightness.dark,
colorSchemeSeed: Colors.red,
), But also because it assigns the M3 seed generated outline color directly to And yes, at least in stable you still have that teal color on ThemeData.fromYou can get a much better looking theme if you create it with the title: '9) TD.from fromSeed',
theme: ThemeData.from(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.red,
brightness: Brightness.light,
),
),
darkTheme: ThemeData.from(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.red,
brightness: Brightness.dark,
),
), We then get this: No problem with the In dark mode, things are worse though, the teal color is still there on Some might correctly point out that we have the deprecation of ThemeData(colorScheme: ColorScheme.fromSeed)Let's then try title: '8) TD scheme.fromSeed',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.red,
brightness: Brightness.light,
),
),
darkTheme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.red,
brightness: Brightness.dark,
),
), But the above gets you a worse theme in dark mode that is more grey (pre M2 dark mode) and with none of the critical surface, card, canvas, background, sacffoldBackground and error colors from the Only conclusion can be, don't do this! Study of Roads to ThemeDataI did a ThemeData study, as general guidance in the docs for the FlexColorScheme package. It is more of an investigation of current state of different ways to make a I used different colors than here, but these were the different ways to make
The numbers I used on the screenshots above, use the same numbers as above list, and in the study. What to do and use?Setting it up with the same used red example as above, we could do eg something like further below to get a To start we need to define a This works well as long as its needed onColor, is same as the one computed final ColorScheme redSchemeLight = ColorScheme.fromSeed(
brightness: Brightness.light,
seedColor: Colors.red,
primary: Colors.red[600],
secondary: Colors.red[900],
);
final ColorScheme redSchemeDark = ColorScheme.fromSeed(
brightness: Brightness.dark,
seedColor: Colors.red,
primary: Colors.red[200],
secondary: Colors.red[100],
); For locking down the The If you want to use a color for This is the case with
This is what the "light" generated And here is the dark one: The ToneXX above refers to which tone each color in the ColorScheme was assigned a color from, using the "Core Palettes" tonal palettes produced by the
You should always use same color as input to your light and dark theme mode Fixed ThemeDataSorry got a bit side tracked, seeded ColorSchemes can be fascinating, back to making the We could then use the title: 'Fixed ThemeData',
theme: ThemeData(
colorScheme: redSchemeLight,
primaryColor: redSchemeLight.primary,
primaryColorLight: Color.alphaBlend(
Colors.white.withAlpha(0x66), redSchemeLight.primary),
primaryColorDark: Color.alphaBlend(
Colors.black.withAlpha(0x66), redSchemeLight.primary),
secondaryHeaderColor: Color.alphaBlend(
Colors.white.withAlpha(0xCC), redSchemeLight.primary),
toggleableActiveColor: redSchemeLight.secondary,
scaffoldBackgroundColor: redSchemeLight.background,
canvasColor: redSchemeLight.background,
backgroundColor: redSchemeLight.background,
cardColor: redSchemeLight.surface,
bottomAppBarColor: redSchemeLight.surface,
dialogBackgroundColor: redSchemeLight.surface,
indicatorColor: redSchemeLight.onPrimary,
dividerColor: redSchemeLight.onSurface.withOpacity(0.12),
errorColor: redSchemeLight.error,
applyElevationOverlayColor: false,
),
darkTheme: ThemeData(
colorScheme: redSchemeDark,
primaryColor: redSchemeDark.primary,
primaryColorLight: Color.alphaBlend(
Colors.white.withAlpha(0x59), redSchemeDark.primary),
primaryColorDark: Color.alphaBlend(
Colors.black.withAlpha(0x72), redSchemeDark.primary),
secondaryHeaderColor: Color.alphaBlend(
Colors.black.withAlpha(0x99), redSchemeDark.primary),
toggleableActiveColor: redSchemeDark.secondary,
scaffoldBackgroundColor: redSchemeDark.background,
canvasColor: redSchemeDark.background,
backgroundColor: redSchemeDark.background,
cardColor: redSchemeDark.surface,
bottomAppBarColor: redSchemeDark.surface,
dialogBackgroundColor: redSchemeDark.surface,
indicatorColor: redSchemeDark.primary,
dividerColor: redSchemeDark.onSurface.withOpacity(0.12),
errorColor: redSchemeDark.error,
applyElevationOverlayColor: true,
), Above we could of course also use colors from the The resulting theme colors then looks like this: Which no longer contains any surprises and we spliced in some locked down "brand" red colors into the frey of colors If using seed colors for all extra colors are not a desired thing, then making the ColorSchemes above with plain Well this is my take on this situation and solution approach with just plain I've kind of given up on trying to convince anybody that it should be more consistent, more like this out of the box. Arguing that it is confusing to new comers and even us Flutter old timers in its current state, seems a bit futile. It will likely remain confusing going forward too. As shown one can fix it, make the theme work as desired, but it takes a bit of an effort and knowing what you need to do to get a I know writing all of this here is seen by very few, but perhaps it helps somebody, plus I might use it in a blog later too 😄 |
Well, that was incredible. And I hope you don't mind me saying that if the question of color in dark theme inspires a post of that magnitude, it means someone probably needs to take a serious look at how things are architected in the world of color in ThemeData |
Thanks, being "quite" familiar with all nuances of Colors in Flutter themes, I don't really notice any problems with it for my own needs. However, looking at it from the perspective of somebody new to Flutter, trying to get a grip of all the ways to make a color correct Lot's of similar issues posted here about it. I also frequently see apps and Flutter code that defines the theme for their apps in ways that end up producing poor dark theme and missing a color here and there in light mode too, and the eternal teal color of course. Then they instead end up adjusting colors on widget level, outside of their theme, just to get the job done and can't figure out why they did not get "red", like above, if that was asked for. I know you grok all this too @lukepighetti, but it has to be a pain if you are new to Flutter. Why the colors are the way they are is a lot of legacy stuff. One can of course just read all code of ThemeData and ColorScheme and it becomes obvious at least then why the colors in them get the colors they do using the different methods to create your ThemeData object. This of course still does not give you any clue or insights into which component and element will end up using what color by default, since there is no documentation of that anywhere to be found. Best option is, fork/clone the repo and search for a theme color of interest in the entire repo and find all places it is referenced :) Full M3 ColorScheme's that actually follow the M3 Color System, will likely confuse many even more, add seeded versions with brand overrides to the mix and it's a party. And I did not even mention using dynamic theme from A12 where you then adjust/tune your custom colors to fit better with the colors in the dynamic theme, which is quite interesting of course. Many will just be "I want my theme red", and get confused when it it is not, when they think they defined that in their theme. iOS world is quite a bit simpler, there is pretty much only "primary" color, and AppBar is often just white in light mode too, so you just go "blue" and buttons, selected items, small topic headings , etc are "blue" and that's it. Well OK there are the classic iOS green switches, but at least they are so because they are speced that they should be so, it is not a surprise, it is actually expected. |
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of |
This is just a small selection of examples of the dark theme having values set to greyscale or teal (why in the world teal?) values, ignoring the primarySwatch. This caused a lot of theming confusion for me at first, especially with some colors inexplicably being set to teal.
Expected behavior would be for theme_data to properly use the selected primarySwatch, regardless of light or dark brightness.
The text was updated successfully, but these errors were encountered: