Skip to content
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

☂️ Bring Material 3 to Flutter #91605

Closed
63 of 70 tasks
rami-a opened this issue Oct 11, 2021 · 136 comments
Closed
63 of 70 tasks

☂️ Bring Material 3 to Flutter #91605

rami-a opened this issue Oct 11, 2021 · 136 comments
Assignees
Labels
c: proposal A detailed proposal for a change to Flutter customer: crowd Affects or could affect many people, though not necessarily a specific customer. f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels. P2 Important issues not at the top of the work list team-design Owned by Design Languages team triaged-design Triaged by Design Languages team

Comments

@rami-a
Copy link
Member

rami-a commented Oct 11, 2021

image

Material 3, also known as "Material You", is the next generation of Material Design. The major changes include:

  • updates to many components (colors, text styles and shapes, etc.)
  • color system improvements
  • typography improvements
  • elevation refinements

This issue has tracked the progress and status of adding Material 3 support to the Flutter material library. That work is now complete.

As of Flutter 3.16, Material3 is the default

Support for Material 2 will continue to be available for at least a year after Material 3 becomes the default. To opt-in to Material 2 use the useMaterial3 ThemeData flag in your app:

  return MaterialApp(
    theme: ThemeData(useMaterial3: false),
    // ...
  );

Note
See the API docs for [useMaterial3] for the comprehensive list of changes.

Updates available in Flutter 3.16:

Check out the updates to components, color, typography, and elevation in the Material 3 sample app.

image

Components

The following components have been updated to Material 3 colors, text styles and shapes generated from the Material 3 token database:

Color

Typography / Iconography

Android features

Documentation / Dev experience

Remaining work

Components

Typography / Iconography

iOS features

Documentation / Dev experience

Accessibility

Motion

@rami-a rami-a added f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels. labels Oct 11, 2021
@TahaTesser
Copy link
Member

TahaTesser commented Oct 18, 2021

@rami-a

Just noticed this, appears like title shifts from larger text to regular text (similar to Cupertino Navigation Bar)
I couldn't find an issue for this, wdyt?

2021-10-19.01-00-04.mp4

@rami-a
Copy link
Member Author

rami-a commented Oct 19, 2021

Hey @TahaTesser, yeah that is one of the variations of app bar now. We should create an issue for it, I can do that

Done: #92093

@Hixie
Copy link
Contributor

Hixie commented Oct 26, 2021

Is the goal to support a seamless upgrade path (flip a switch and you're in Material 3 mode, and your app should work fine), or is this the expectation that upgrading to this library will require effort?

If the latter, maybe it makes more sense to provide this as a separate library?

@Hixie
Copy link
Contributor

Hixie commented Oct 26, 2021

These changes will be provided as an opt-in solution for now and the current Material 2 functionality will remain a part of the framework for a while (at least 1 year+). This will give developers to a lot of time to opt-in and move over their projects.

I don't think that's a lot of time. People maintain projects for a decade or more with minimal investment. We can make minor breaking changes that can be migrated with dart fix or flipping a switch, but something of the scale of a whole new library with a new design language and so on is too high an investment for an application in maintenance mode. For example, concretely, I would not expect to ever migrate my Rainbow Monkey app to material3; I just don't have the time to do that work if it's more than a flag flip.

@rami-a
Copy link
Member Author

rami-a commented Oct 26, 2021

@Hixie the goal is to have a seamless upgrade path (i.e. toggle a flag on ThemeData and all Material widgets adjust appropriately). We're still working through all the details to make this possible.

One problem with offering this as a separate library is that as Material continues to evolve, Flutter's packaged material library will become stale and outdated.

@Hixie
Copy link
Contributor

Hixie commented Oct 26, 2021

It doesn't look like it can be a seamless flag flip, e.g. looking at #89853 it seems the typography sizes don't match, which is a pretty serious breaking change all on its own.

I'm also a bit worried about what this will do to the API complexity and performance. Can we add these new features without making the widgets have more complicated APIs? They're already really complicated and confusing as it is, because of having to support material 1 and 2 features (which we'll have to support forever); if we add material 3 features as well it's going to be really hard to pick up the framework. Performance is also an issue since all these widgets are going to be full of branches to handle all the various options, and that's slower than having a dedicated simple library just for one design language.

Flutter's packaged material library will become stale and outdated.

Is that a problem? We can have people import the material3 library instead of the material library in the templates. The idea is just not to break old apps.

@TahaTesser TahaTesser added the c: proposal A detailed proposal for a change to Flutter label Oct 26, 2021
@rami-a
Copy link
Member Author

rami-a commented Oct 27, 2021

The M3 spec is now live at https://m3.material.io/

@bernaferrari
Copy link
Contributor

I'm also a bit worried about what this will do to the API complexity and performance

The 'issue' I see is that Flutter is extremely coupled with Material (even the iOS slider depends on Material slider). There are some open issues for decoupling Material, but they never moved on. I am 100% in favor of a Flutter material components library that can be instantly updated and break everything (I was the person that caused TextTheme to be updated to Material 2 😛). I don't want to wait 3 years for Material You changes; It could also help in versioning, as someone could still use RaisedButton (without the deprecation warning) if so wanted. Right now there is not much option, people need to update Flutter (like on Apple Silicon) and sometimes it makes it harder for them.

My question is just... how could such a library exist? The imaginary library will probably have ElevatedButton (with some tweaks), but Flutter already has it. Will I as a user suddenly need to figure out which import I want? Or shall Flutter deprecate every material widget and say "please import the material 2 library" (so that then switching to material 3 is easy)? Like, this would be nice, but possibly too radical? Or Flutter will somehow import Material 3 and then we will have to deal with conflicts "you use an unsupported material3 version" (which could also create trouble when Material 4 reaches).

I want this, I hope we get this, but how? Is it possible?

@byblady
Copy link

byblady commented Oct 27, 2021

It is better to update the complete library of material, rather than keep it, since in the long run the components of material 2 will be without maintenance and obsolete, the current version could still be kept and perhaps to use version 3 it is only indicated through of a parameter in the import, that indicates that I want to use version 3 and not 2, or by default in new projects that it is version 3 and be able to use the current version if one wants, but not both at the same time. you see.

@Hixie
Copy link
Contributor

Hixie commented Oct 27, 2021

even the iOS slider depends on Material slider

Actually the cupertino library doesn't depend on material; the dependency is in the other direction.

someone could still use RaisedButton

There's nothing stopping someone today from just copying the material library and putting it into a package if they want to continue using the older widgets, FWIW.

@bernaferrari
Copy link
Contributor

bernaferrari commented Oct 28, 2021

You are right. So the question that remains is: how could we have a material3 library with Flutter's existing material in the same project without conflicts?

  • Convert Flutter's material to material2 library and add a dart fix that adds that import everywhere.
  • Somehow add a material flag to pubspec where when >= 3, hides the visibility for Flutter's default material (at least for IDE suggestions; it would still work, just don't suggest/auto-import them). Or maybe just having material in pubspec would trigger the IDE plugin to not auto-import the older material.

If you are talking about uncoupling things, we could also remove Material Icons from Flutter and put them into a package. This is a frequent request as it is always breaking something/not updating/the script that updates are private and its changes get in the middle of Flutter releases, so people need to wait for the next stable to have the icons.

@Hixie
Copy link
Contributor

Hixie commented Oct 28, 2021

The impression I get is that the delta from the current material library to Material 3 is actually pretty minimal, and it would be simplest to just keep adding to the current library. The main complexity seems to be around the typography changes.

@rami-a
Copy link
Member Author

rami-a commented Oct 28, 2021

@Hixie you're correct that the M2 to M3 delta is pretty minimal.

The typography changes are likely the most disruptive:

  • Renaming all the text styles will require folks to familiarize themselves with them again (though dart fix can help alleviate some of that complexity).
  • The actual changes to the font sizes will be purely opt-in (just like the 2018 font size changes were) using the Typography class and named constructors

@chgibb
Copy link

chgibb commented Oct 28, 2021

As a consumer of Flutter, I'd prefer to see separate package:flutter/material.dart and package:flutter/material_you.dart (or something to that effect).

My use case would be to be able to cleanly opt-in or out of Material3 widgets and styles. I recognize that this might not be very straightforward given ancestor themes.

@MarcusWichelmann
Copy link

MarcusWichelmann commented Oct 28, 2021

This is only a consumer perspective, too, but maybe such a split into a new material3 package could also be a great chance to risk some breaking changes and throw out all the legacy theming APIs?

I found the theming system to be very confusing when I started with Flutter and, after heavily working with it for some time, I think it still is. And the updated M3 color scheme (#89852) will probably not make that situation any better. All these redundancies and complexity could probably only be removed with such a new, fully opt-in package to which developers have to migrate their app code anyway, making the breakage less painful.

In the best case, users of the new material3 package would then find a clean and straight-forwarded theming API without any leftovers from the previous material design revisions, color schemes and theming systems, making it way easier for users to implement theming best practices and understand how things hang together Flutter-internally. Maybe the material library could also be more decoupled along the way, for example by removing all the references to single widgets from the ThemeData class to make things more flexible and extensible. But I'm just dreaming. 😉

The downside is, that many breaking changes would probably steepen the effort needed to migrate existing apps to the new Material 3 design.

@bernaferrari
Copy link
Contributor

bernaferrari commented Oct 28, 2021

The actual changes to the font sizes will be purely opt-in (just like the 2018 font size changes were) using the Typography class and named constructors

2018 style was only implemented in 2020 with bodyText (which is nowhere in the official docs but was authorized) to not break the existing body and it is still not null-safety. Also, 2014 styles are still the default in Flutter. We could say the 2018 migration is not yet complete.

Material3 also revamps how elevation changes (color changes on both dark and light mode, there is a tonalElevation parameter). So now we would have an additional parameter in ThemeData besides ThemeData.applyElevationOverlay (which was also only truly implemented in 2020 #57526).

Finally, I guess there will be the new MaterialColors.green90 which is also going to be a duplicate of Flutter's Colors.green (from Material 1). A lot of duplications, but nothing impossible. This is the issue of Material 3, there will be additional parameters everywhere, it will be so 'opt-in' that most people will never opt-in because it will be too complex, they will forget or something else. Or ThemeData will get even more verbose.

@LasseRosenow
Copy link
Contributor

LasseRosenow commented Oct 29, 2021

I myself also think that decoupling the material and also the cupertino library from the flutter framework would be a major benefit for the whole ecosystem. All the libraries get more and more complex just to support legacy m2 styling.. Also things like the m2 snackbar styling are still opt in because of that.

It currently is quite painful to create a new flutter app, that uses all widgets in its modern styling, as you have to opt into so many things. And also having to fight with all the old m1 properties and major inconsistencies everywhere.

I think having a material library, that is versioned independent from flutter, enabling developers to update the flutter version of old maintenance projects without the need to handle breaking changes in the material library, would be a major benefit for everyone, as it not only would make the life of each maintainer much more easy, as breaking changes do happen over time, but also making the life of everyone else, who wants to have the modern styling so much easier, as the material library package could just have breaking changes following semver etc.

Altogether I would say, especially if we are trying to think long term, the benefits outweigh the costs by far.
So I would very much recommend to fix this rather soon then late, so that we don't have the same conversation again when materail4 arrives :)

@bernaferrari
Copy link
Contributor

MaterialRail is a good example, it was never "correctly" implemented in Flutter. The duration and curve was wrong and stayed wrong for years(?). I think it was fixed a few months ago, but it had "luck" that almost no one uses the Rail, so the behavior change was fine and no one complained. Officially, if it were a more important component, it would have taken 1 year to deprecate with additional parameters and etc. I like that libraries can move faster.

@Hixie
Copy link
Contributor

Hixie commented Oct 29, 2021

FWIW, the main reason to not have material be its own package is that we want the out-of-box experience to be quick. That is, people should be able to download Flutter, and immediately start writing an app with pretty buttons.

I agree with the points that were brought up above, though. It's definitely put us in an awkward situation. I also agree that adding M3 is not going to make it better.

@LasseRosenow
Copy link
Contributor

LasseRosenow commented Oct 29, 2021

FWIW, the main reason to not have material be its own package is that we want the out-of-box experience to be quick. That is, people should be able to download Flutter, and immediately start writing an app with pretty buttons.

This could easily be solved by adding the new material library package to the pubspec.yaml file of the template for new projects

@Hixie
Copy link
Contributor

Hixie commented Oct 29, 2021

That ends up being tricky for various reasons, e.g. we would have to pin the dependency which means now you can't upgrade the package without upgrading Flutter. (We have to pin all our internal dependencies, so we try to minimize how many packages we depend on.)

But yes, that's one approach we've discussed in the past.

@LasseRosenow
Copy link
Contributor

But having material as a dependency in the pubspec template isn't really a flutter dependency. As its only part of a template that is being genrated when a new project is generated just like "cupertino_icons" which is added aswell

Besides that also I still don't see, how

"having an easier start (not needing to add material to pubpec)"

outweighs

"having a very hard time throughout the whole development process by fighting the inconsistent, fragmented and in general weird library that also has a hard time being up to date with modern styling because of backwards compatibility"

@byblady
Copy link

byblady commented Oct 29, 2021

But having material as a dependency in the pubspec template isn't really a flutter dependency. As its only part of a template that is being genrated when a new project is generated just like "cupertino_icons" which is added aswell

Besides that also I still don't see, how

"having an easier start (not needing to add material to pubpec)"

outweighs

"having a very hard time throughout the whole development process by fighting the inconsistent, fragmented and in general weird library that also has a hard time being up to date with modern styling because of backwards compatibility"

And if Flutter were able to use the native libraries, using as a widget and not XML, so the native design libraries would not require any coding to be used in flutter, it is just a dream.

@bernaferrari
Copy link
Contributor

That is, people should be able to download Flutter, and immediately start writing an app with pretty buttons.

Yeah, but Flutter kind of already does that for icons and it works, right? There is uses-material-design: true and cupertino_icons in every app (because of the template) and you don't see people complaining it is hard to add material icons to Flutter because most use the template.

@Hixie
Copy link
Contributor

Hixie commented Oct 30, 2021

I'm not saying it's a blocker, just that it's one of the things we need to keep in mind.

@nidegen
Copy link

nidegen commented Oct 30, 2023

Has progress kinda halted here?

@HansMuller
Copy link
Contributor

@nidegen - not at all. Flutter has been migrated to Material 3 which will be the default in the next stable release. Of course there's still work to do, for example we're still migrating some tests per #127064, but the lion's share of the work to migrate Flutter to Material 3 has been completed. Our focus has shifted a little, towards simplifying the theming system, improving the support for platform-specific adaptation, making the existing components more flexible, paying down technical debt, and of course resolving issues.

@HansMuller
Copy link
Contributor

HansMuller commented Nov 15, 2023

As of Flutter 3.16, we're calling this project done and closing the issue.

@MaxYablochkin

This comment was marked as off-topic.

@MarlonJD
Copy link

As of Flutter 3.16, we're calling this project done and closing the issue.

There are important missing parts #119328, #126069

@iapicca
Copy link
Contributor

iapicca commented Nov 16, 2023

As of Flutter 3.16, we're calling this project done and closing the issue.

it's a bit confusing to me how a project can be called "done" with so many outstanding issues
sounds like pulling a "navigator 2.0"

image

@HansMuller
Copy link
Contributor

@iapicca - you are correct, there's still work to be done (there will always be work to be done). It's no longer useful to have such a broad based umbrella issue now that we've made Material 3 the default. The open subordinate issues will remain open.

@realitymolder
Copy link

@iapicca - you are correct, there's still work to be done (there will always be work to be done). It's no longer useful to have such a broad based umbrella issue now that we've made Material 3 the default. The open subordinate issues will remain open.

But I think that it is fair to say that material 3 is not fully implemented

@HansMuller
Copy link
Contributor

There are Material 3 specification changes (small color diffs for example) rolling out even now, so you could say that the spec isn't fully implemented. This umbrella issue was about the main effort to upgrade all of the components and themes and I think it's fair to close it. We'll continue to track the smaller stuff in separate issues.

@jwinarske
Copy link

Having an umbrella issue (epic) allows easier tracking and provides a single point to check. The alternative is to tag the issues correctly, so one can easily query the current status

@rydmike
Copy link
Contributor

rydmike commented Nov 17, 2023

Thanks @HansMuller for the clarifications.

While it might feel odd to call it done, since there are parts not yet implemented, I agree that it does not make sense to keep this umbrella issue open forever.

The Material3 spec continues to evolve, it has done so a lot during this project. If we look at its original scope and spec when it was published, the original target has even been exceeded in the 3.16 release!

New changes to ColorScheme and surface colors and contrasts have been published, as has a new nice Carousel component. These new features and side sheet, plus many date picker variations are not yet supported. Some motion designs are also not quite there yet, along with many minor details. M3 is a moving target, the implementation in Flutter is ready enough to no longer need this umbrella issue, it has served its purpose well.

Yes there are still issues, there will always be more and new issues, that needs to be tracked and solved. The normal process supports that well.

Thank you all for the work done to bring Material3 to Flutter. It has been interesting to track its progress, test use it and provide feedback during the journey 🙂💙

@MaxYablochkin

This comment was marked as off-topic.

@cbatson
Copy link

cbatson commented Nov 18, 2023

Just updated Flutter and several UI elements in my iiOS app have changed color, shape, etc. Reading this thread, this is apparently expected behavior for this update. Assuming I don't want to blanket disable Material 3 altogether, is there a migration guide that will help me get things back to the way they were with minimal effort? I.e. what UI elements are likely to be different now and what arguments are needed to replicate prior appearance. Thank you.

@rekire
Copy link

rekire commented Nov 18, 2023

You can opt out easily by setting a property in the theme. I cannot search it right now. But you just need to set material 3 to false

@cbatson
Copy link

cbatson commented Nov 18, 2023

You can opt out easily by setting a property in the theme. I cannot search it right now. But you just need to set material 3 to false

Thank you, I am aware, which is why my question included, "Assuming I don't want to blanket disable Material 3 altogether..."

@Levi-Lesches
Copy link
Contributor

Levi-Lesches commented Nov 19, 2023

I do find it odd that making useMaterial3 default to true wasn't considered a breaking change in Flutter. I understand Flutter has different deprecation policies but at the end of the day, a simple upgrade to a new minor version of Flutter completely changed my app's colors and design. Can someone on the Flutter team comment on this, and what the policy for visually breaking changes is in general?

Dart also had a similar story by introducing null safety in 2.12 (which didn't break old dependencies but code still had to be migrated manually before it could be compiled again) and then making 3.0 a non-breaking change, even modifying pub get logic to treat it as such. But that's a different topic for a different crowd.

@HansMuller
Copy link
Contributor

It's true that in most respects making M3 the default was a breaking change. The official rule for breaking changes allows for visual changes that don't break existing customer tests, however this was a big visual change and we apologize for the havoc it may have created.

@rydmike
Copy link
Contributor

rydmike commented Nov 20, 2023

@Levi-Lesches, even if it was very nice of @HansMuller to apologize for the potential "havoc" 😄 it may have caused, I would like to add that as well known, Flutter SDK does not use semantic versioning, the minor stable releases pretty much always contain some breaking changes.

There is always an attempt to list all breaking changes under https://docs.flutter.dev/release/breaking-changes. Sometimes one or two have been missed, it happens, I've certainly been hit by that too. However, in this case the change of defaulting useMaterial to true instead of false, is listed and included as the 2nd breaking change in release 3.16, see https://docs.flutter.dev/release/breaking-changes/material-3-default#migration-guide.

It was even mentioned already in the previous Flutter 3.13 release notes, that in the next stable release after it, Material3 would be made the default, see https://medium.com/flutter/whats-new-in-flutter-3-13-479d9b11df4d

Screenshot 2023-11-20 at 19 46 44

So this change should not be a big surprise for anybody and the fix is a single flag toggle.

Legacy M2 based themes and styles?

What might become a much bigger challenge is when the the flag is deprecated and even later, when the code supporting legacy Material-2 themes and styles are removed. How do we recreate the legacy styles then? This is an interesting question.

You can however make a theme using Material-3 in Flutter's useMaterial3: true mode, that creates an app that looks like it using Material-2, as if is the flag would be set to useMaterial3: true. This also means it is possible to replicate custom styles, as they were when made with M2 after enabling M3, that do not break the app so much. This might interest you @cbatson as well.

In this tweet https://x.com/RydMike/status/1721535442783236259?s=20 I show an example of a theme changing from using M3, to pretty much look like it is using M2 mode and its defaults, while it is actually using M3 mode all the time. It is only being themed to look like it is using M2.

Here is a similar recording demoing it:

Screen.Recording.2023-11-20.at.20.02.33.mov

How much you have to change in the M3 theme depends on your custom M2 theme and styles. It is currently not possible to for all cases get a 100% match, but probably close enough for most custom designs, for the parts that matters anyway.

Sure the above example use my FlexColorScheme package that contains some presets in the Themes Playground config app to set it to an M2 look-alike design in M3 mode with one-click. However, the Themes Playground is just a visual config tool for the FlexColorScheme package API, which in turn is a fancy ThemeData factory. So anything it can do, you can do with just vanilla ThemeData as well.

I might write a blog with some general and in-depth guidance on how to go about doing this. Perhaps something will also be written about it by the Flutter team as well. It is certainly a topic that many will ask and wonder about once the useMaterial3 flag is removed.

A few quick pointers to get from M3 to an M2 look-a-like app in M3 mode:

  • Use a hand-made ColorScheme with legacy style colors. You probably have a custom one for your app already.
  • In light mode set ColorScheme.surfaceTint to Colors.transparent. In dark mode, set it to a neutral grey color that gives a similar dark mode overlay elevation as the one you got in M2 mode, if the dark M2-mode is/was used correctly. Few Flutter apps used M2 dark mode correctly though.
  • Map ColorScheme colors on component themes as they were in M2, yes "some" are different in M3, Buttons, AppBar, FAB etc.
  • Set elevations on components themes with elevations, as they were in M2.
  • Set shadowColor to Colors.black for component themes where it defaults to Colors.transparent. The ColorScheme.shadow color already defaults to Colors.black, but some component themes that used it in M2, now set it to Colors.transparent in M3 mode. By setting it back to black, you can bring shadows back to such components, e.g. AppBar.
  • Set shape border radius on components as they were in M2, typically 4.
  • If the older typography is still around (2014=pre-M2 and 2018=M2) when the flag is removed, switch to the one you used, instead of the M3 default one, or of course keep whatever you use in your custom design.
  • Set AppBar component theme scrolledUnderElevation to the same value as elevation, so there is no elevation change when scrolling.

With these changes in place, you should have no tinted surface colors, no elevation tint and border radius and elevations should be same as before, and you should have a bit lighter grays on elevated surfaces in dark mode. This is needed so they are visible against the background, since the shadow does not really show so sell in dark mode, even if it is there, this is used by M2 as well.

For a custom design you might have other minor things not mentioned here that needs tuning in order to not break it a lot visually when you enable M3.

Copy link

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 flutter doctor -v and a minimal reproduction of the issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Dec 11, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
c: proposal A detailed proposal for a change to Flutter customer: crowd Affects or could affect many people, though not necessarily a specific customer. f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels. P2 Important issues not at the top of the work list team-design Owned by Design Languages team triaged-design Triaged by Design Languages team
Projects
No open projects
Status: Done
Development

No branches or pull requests