Skip to content

Compact Visual Density is wrongfully applied to Checkboxes with MaterialTapTargetSize.padded on desktop platforms according to Material 3 Guidelines #156408

Closed

Description

@r-durao-pvotal

Steps to reproduce

Create a simple widget tree with a checkbox that has a materialTapTargetSize: MaterialTapTargetSize.padded.
Run it on web.
Inspect its size.

Expected results

According to M3 guidelines, even if visual density is compact:

It’s important to keep accessibility in mind when you’re applying density to your UI. No matter the density, all touch targets should be at least `48px` in size.

https://m3.material.io/blog/material-density-web

So a Checkbox should always have a 48x48 touch target. Which does not happen if we use the default VisualDensity for desktop platforms.

Actual results

Because for desktop platforms there's a compact Visual Density being applied by default, it's shrinking components' touch targets like the Checkbox to sizes that are not accessible according to M3 (from 48 to 40 for example)

Additionally, this compact visual density that is applied by default is assuming that all UI on a desktop app (or desktop web app) are going to be very visually dense, when it's not always the case.

Is this an implementation mistake by the Flutter team? Are the M3 docs outdated?

Code sample

Code sample
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Checkbox(
          materialTapTargetSize: MaterialTapTargetSize.padded,
          value: true,
          onChanged: (_) {},
        ),
      ),
    );
  }
}

Screenshots or Video

Checkbox size without overriding default Visual Density (which is VisualDensity.compact):
image

Checkbox size by overriding default Visual Density with VisualDensity.standard:
image

Logs

No response

Flutter Doctor output

Doctor output
~/repositories/checkbox_visual_density$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[!] Flutter (Channel [user-branch], 3.22.0, on macOS 14.6.1 23G93 darwin-arm64, locale en-PT)
    ! Flutter version 3.22.0 on channel [user-branch] at /opt/homebrew/Caskroom/flutter/3.0.4/flutter
      Currently on an unknown channel. Run `flutter channel` to switch to an official channel.
      If that doesn't fix the issue, reinstall Flutter by following instructions at https://flutter.dev/docs/get-started/install.
    ! Upstream repository unknown source is not a standard remote.
      Set environment variable "FLUTTER_GIT_URL" to unknown source to dismiss this error.
[!] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.
[!] Xcode - develop for iOS and macOS (Xcode 16.0)
    ! iOS 18.0 Simulator not installed; this may be necessary for iOS and macOS development.
      To download and install the platform, open Xcode, select Xcode > Settings > Platforms,
      and click the GET button for the required platform.

      For more information, please visit:
        https://developer.apple.com/documentation/xcode/installing-additional-simulator-runtimes
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.2)
[✓] IntelliJ IDEA Ultimate Edition (version 2022.1.3)
[✓] VS Code (version 1.92.2)
[✓] Connected device (5 available)
[✓] Network resources

! Doctor found issues in 3 categories.

Activity

  1. added
    in triagePresently being triaged by the triage team
    on Oct 9, 2024
  2. huycozy commented on Oct 9, 2024

    @huycozy
    Member

    I checked this on macOS app target and see Checkbox's size is 40.0 from Devtools inspector as well. Reproduced this issue on the latest Flutter stable and master versions.

    flutter doctor (stable and master)
    [✓] Flutter (Channel stable, 3.24.3, on macOS 15.0 24A335 darwin-x64, locale en-VN)
        • Flutter version 3.24.3 on channel stable at /Users/huynq/Documents/GitHub/flutter
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision 2663184aa7 (3 weeks ago), 2024-09-11 16:27:48 -0500
        • Engine revision 36335019a8
        • Dart version 3.5.3
        • DevTools version 2.37.3
    [!] Flutter (Channel master, 3.26.0-1.0.pre.414, on macOS 15.0 24A335 darwin-x64, locale en-VN)
        • Flutter version 3.26.0-1.0.pre.414 on channel master at /Users/huynq/Documents/GitHub/flutter_master
        ! Warning: `flutter` on your path resolves to /Users/huynq/Documents/GitHub/flutter/bin/flutter, which is not inside your current Flutter SDK checkout at /Users/huynq/Documents/GitHub/flutter_master. Consider adding /Users/huynq/Documents/GitHub/flutter_master/bin to the front of your path.
        ! Warning: `dart` on your path resolves to /Users/huynq/Documents/GitHub/flutter/bin/dart, which is not inside your current Flutter SDK checkout at /Users/huynq/Documents/GitHub/flutter_master. Consider adding /Users/huynq/Documents/GitHub/flutter_master/bin to the front of your path.
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision c077b8c61a (3 hours ago), 2024-10-08 19:51:19 -0400
        • Engine revision 0e7344ae24
        • Dart version 3.6.0 (build 3.6.0-332.0.dev)
        • DevTools version 2.40.0
        • If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades.

    Looks like I found the cause of this:

    Per MaterialTapTargetSize.padded, the minimum tap target size should be 48x48 px:

    enum MaterialTapTargetSize {
    /// Expands the minimum tap target size to 48px by 48px.
    ///
    /// This is the default value of [ThemeData.materialTapTargetSize] and the
    /// recommended size to conform to Android accessibility scanner
    /// recommendations.
    padded,

    The passed value MaterialTapTargetSize.padded to Checkbox.materialTapTargetSize is correct here:

    final MaterialTapTargetSize effectiveMaterialTapTargetSize = widget.materialTapTargetSize
    ?? checkboxTheme.materialTapTargetSize
    ?? defaults.materialTapTargetSize!;
    final VisualDensity effectiveVisualDensity = widget.visualDensity
    ?? checkboxTheme.visualDensity
    ?? defaults.visualDensity!;
    Size size = switch (effectiveMaterialTapTargetSize) {
    MaterialTapTargetSize.padded => const Size(kMinInteractiveDimension, kMinInteractiveDimension),
    MaterialTapTargetSize.shrinkWrap => const Size(kMinInteractiveDimension - 8.0, kMinInteractiveDimension - 8.0),
    };

    But the next line seems to cause the issue:

    size += effectiveVisualDensity.baseSizeAdjustment;

    The visualDensity default value is compact with VisualDensity(horizontal: -2.0, vertical: -2.0). When it's multiplied with baseSizeAdjustment , it returns a new Offset(horizontal, vertical) * interval (interval is 4.0) = Offset(-8.0, -8.0).

    This causes Checkbox size down to (40.0, 40.0) as observed.

  3. added
    frameworkflutter/packages/flutter repository. See also f: labels.
    p: material_uimaterial_ui package in flutter/packages
    has reproducible stepsThe issue has been confirmed reproducible and is ready to work on
    team-designOwned by Design Languages team
    and removed
    in triagePresently being triaged by the triage team
    on Oct 9, 2024
  4. r-durao-pvotal commented on Oct 9, 2024

    @r-durao-pvotal
    Author

    @huycozy What is the ideal fix here? Should we add a check after adding the baseSizeAdjustment and reverting the sum if it breaks the 48 touch target rule?

  5. huycozy commented on Oct 10, 2024

    @huycozy
    Member

    I'm not sure of the proper fix for this now but I see we can work around this by overriding the Checkbox.visualDensity with VisualDensity.standard in the meantime until having design team's opinion, then Checkbox size should be (48.0, 48.0) as desired.

  6. added
    triaged-designTriaged by Design Languages team
    P2Important issues not at the top of the work list
    on Oct 10, 2024
  7. self-assigned this
    on Nov 18, 2024
  8. moved this from To do to In progress in Nevercodeon Nov 18, 2024
  9. moved this from In progress to PR submitted in Nevercodeon Dec 10, 2024
  10. moved this from PR submitted to Done (PR merged) in Nevercodeon Jan 30, 2025
  11. added
    r: fixedIssue is closed as already fixed in a newer version
    on Jan 30, 2025
  12. github-actions commented on Feb 13, 2025

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

  13. locked as resolved and limited conversation to collaborators on Feb 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

P2Important issues not at the top of the work lista: desktopRunning on desktopfound in release: 3.24Found to occur in 3.24found in release: 3.26Found to occur in 3.26frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onp: material_uimaterial_ui package in flutter/packagesr: fixedIssue is closed as already fixed in a newer versionteam-designOwned by Design Languages teamtriaged-designTriaged by Design Languages team

Type

No type

Projects

  • Status
    Done (PR merged)

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions