Skip to content

☂️ Bring Material 3 to Flutter #91605

Description

@rami-a

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

Activity

  1. added
    p: material_uimaterial_ui package in flutter/packages
    frameworkflutter/packages/flutter repository. See also f: labels.
    on Oct 11, 2021
  2. TahaTesser commented on Oct 18, 2021

    @TahaTesser
    Contributor

    @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
  3. rami-a commented on Oct 19, 2021

    @rami-a
    ContributorAuthor

    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

  4. Hixie commented on Oct 26, 2021

    @Hixie
    Contributor

    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?

  5. Hixie commented on Oct 26, 2021

    @Hixie
    Contributor

    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.

  6. rami-a commented on Oct 26, 2021

    @rami-a
    ContributorAuthor

    @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.

  7. Hixie commented on Oct 26, 2021

    @Hixie
    Contributor

    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.

  8. rami-a commented on Oct 27, 2021

    @rami-a
    ContributorAuthor

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

  9. bernaferrari commented on Oct 27, 2021

    @bernaferrari
    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?

  10. byblady commented on Oct 27, 2021

    @byblady

    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.

  11. Hixie commented on Oct 27, 2021

    @Hixie
    Contributor

    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.

  12. bernaferrari commented on Oct 28, 2021

    @bernaferrari
    Contributor

    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.

  13. 136 remaining items

  14. iapicca commented on Nov 16, 2023

    @iapicca

    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
  15. HansMuller commented on Nov 16, 2023

    @HansMuller
    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.

  16. realitymolder commented on Nov 16, 2023

    @realitymolder

    @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

  17. HansMuller commented on Nov 16, 2023

    @HansMuller
    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.

  18. jwinarske commented on Nov 16, 2023

    @jwinarske
    Contributor

    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

  19. rydmike commented on Nov 17, 2023

    @rydmike
    Contributor

    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 🙂💙

  20. MaxYablochkin commented on Nov 17, 2023

    @MaxYablochkin
  21. cbatson commented on Nov 18, 2023

    @cbatson

    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.

  22. rekire commented on Nov 18, 2023

    @rekire
    Contributor

    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

  23. cbatson commented on Nov 18, 2023

    @cbatson

    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..."

  24. Levi-Lesches commented on Nov 19, 2023

    @Levi-Lesches
    Contributor

    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.

  25. HansMuller commented on Nov 20, 2023

    @HansMuller
    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.

  26. rydmike commented on Nov 20, 2023

    @rydmike
    Contributor

    @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.

  27. github-actions commented on Dec 11, 2023

    @github-actions

    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.

  28. locked as resolved and limited conversation to collaborators on Dec 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

P2Important issues not at the top of the work listc: proposalA detailed proposal for a change to Fluttercustomer: crowdAffects or could affect many people, though not necessarily a specific customer.frameworkflutter/packages/flutter repository. See also f: labels.p: material_uimaterial_ui package in flutter/packagesteam-designOwned by Design Languages teamtriaged-designTriaged by Design Languages team

Type

No type

Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions