Skip to content

Material 3 Selectable Chips change size when clicked #111038

@Xiphoseer

Description

@Xiphoseer

Steps to Reproduce

  • Set ThemeData(useMaterial3: true)
  • Create a stateful widget
  • Add a Wrap
  • Add multiple FilterChips with showCheckmark: false
  • Use the widget state to make the chips act like radio buttons

Expected Result
When clicking a chip, the color and outline look differently

Actual Result
The chip jumps to a different position under some circumstances, specifically when the right edge of the window
is very close to the right edge of the last chip in a row and when the last chip in that row is changed by the selection
update.

Context

I updated my flutter version to 3.3 today, which includes the new material 3 chips. I believe this is a bug and I think it's caused by:

BorderSide? get side => !isSelected
? isEnabled
? ${border('$tokenGroup$variant.unselected.outline')}
: ${border('$tokenGroup$variant.disabled.unselected.outline')}
: null;

which effectively sets the width of the border to 1.0 only when !isSelected and 0.0 otherwise. So a selected button is smaller because it doesn't have an outline. Note that:

  • Chips with showCheckmark: true and avatar: null jump around anyway because they must change width
  • This also causes a little bit of vertical misalignment for the label text.
  • This is easier to come across with variable sized windows (i.e. desktop embedders)

Workaround

If I pass

side: selected
    ? const BorderSide(color: Colors.transparent)
    : BorderSide(color: Theme.of(context).colorScheme.outline)

to the constructor, the problem goes away.

Screenshots

image
image

Details

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

class TestScreen extends StatefulWidget {
  const TestScreen({Key? key}) : super(key: key);

  @override
  State<TestScreen> createState() => _TestScreenState();
}

class _TestScreenState extends State<TestScreen> {
  int s = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Wrap(
            children: List.generate(
                10,
                (i) => FilterChip(
                    label: Text("Chip $i"),
                    showCheckmark: false,
                    selected: s == i,
                    onSelected: (v) {
                      if (v) setState(() => s = i);
                    }))));
  }
}
Output of `flutter doctor`
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.3.0, on Microsoft Windows [Version 10.0.22000.918], locale de-DE)
[✓] Android toolchain - develop for Android devices (Android SDK version 32.0.0)
[✓] Chrome - develop for the web
[✓] Visual Studio - develop for Windows (Visual Studio Community 2022 17.3.3)
[✓] Android Studio (version 2021.2)
[✓] IntelliJ IDEA Community Edition (version 2022.2)
[✓] VS Code (version 1.71.0)
[✓] Connected device (3 available)
[✓] HTTP Host Availability

Metadata

Metadata

Assignees

Labels

f: material designflutter/packages/flutter/material repository.found in release: 3.3Found to occur in 3.3found in release: 3.4Found to occur in 3.4frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onr: fixedIssue is closed as already fixed in a newer version

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions