flutter / flutter/flutter

Need a way to clip within a rounded rect that has a border

Open
#149,631 3 comments 1 reaction 0 assignees View on GitHub
found in release: 3.22 found in release: 3.23 framework has reproducible steps P2 team-framework triaged-framework
Dominant language
Dart
Stars
179k
Forks
31.1k
PR merge metrics
PR metrics pending

Description

### Steps to reproduce

A `Container` with a `BoxDecoration` should have an option to automatically clip its contents to the inner part of the `BoxDecoration`, which also needs to take into account any `border` of the `BoxDecoration`.

I have the following Dart code for clipping a filled round rectangle, divided into regions with darker and lighter backgrounds, within a rounded rect that has a stroked border. I scaled up the line thickness and radius so that you can see the issue:

```dart
const color = Colors.blue;
return Container(
margin: const EdgeInsets.only(bottom: 12),
decoration: BoxDecoration(
border: Border.all(
color: color.shade300,
width: 10,
),
borderRadius: BorderRadius.circular(30),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(30),
child: Column(
children: [
Container(
color: color.shade300,
width: double.infinity,
child: const Padding(
padding: EdgeInsets.all(6),
child: Center(
child: Text(
'Annual subscription',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
),
),
Container(
width: double.infinity,
color: color.shade50,
child: const Padding(
padding: EdgeInsets.all(6),
child: Center(
child: Text(
'\$269/year (save 25%)',
style: TextStyle(
fontSize: 18,
),
textAlign: TextAlign.center,
),
),
),
),
],
),
),
);
```

Here is how this renders:

![image](https://github.com/flutter/flutter/assets/811305/b70adacd-3855-4896-9b2f-23d3f5e602cc)

The issues are:

(1) the rounding radius is too large for the inner container (I would expect the inner and outer container to have the same center of curvature, but actually the stroke on the outer container reduces the size of the inner container).

(2) There is a fine gap between the fill of the outer container and the fill of the inner container, which you can see as a thin white line near the top.

So for problem (1), the convention of not including the stroke in the inner dimension is fine, but the fix to that should be to reduce the inner rounding radius by the stroke width:

```dart
decoration: BoxDecoration(
border: Border.all(
color: color.shade300,
width: 10,
),
borderRadius: BorderRadius.circular(30),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
```

This is kind of a pain to have to calculate manually, but it is doable. However, it still leaves a fine white line between the outer box outline stroke and the contents:

![image](https://github.com/flutter/flutter/assets/811305/1fd58d38-58b7-48e9-9958-2c3342a3aeb1)

If I remove the `ClipRRect` wrapping of the contents of the inner container, then the contents are not clipped at all, and they end up overwriting the `border`:

![image](https://github.com/flutter/flutter/assets/811305/4f5ee9ba-4b9c-4e91-830a-c306f96abbe4)

What I would love would be a parameter to `BoxDecoration` such as `clip: true` or similar that would clip to the *inside* (not including the border) of the `BoxDecoration`.

Adding `clipBehavior: Clip.antiAlias` to the outer `Container` does not solve the problem, and I don't see any other clipping parameter.

Finally, the border of the `Container` should be drawn after its contents, so that the border always overwrites whatever is inside the `Container`.

### Expected results

There should be an easy way to limit drawing to the inside of a rounded-rect `Container`, meaning specifically within any `border` that is added to the container.

### Actual results

I tried a lot of different combinations of ways of achieving this, and I don't see a way using the current API. Also, there is currently a fine line between the `border` and any `RRect`-clipped contents of a `Container`.

### Code sample

Code sample

See above

### Screenshots or Video

See above

### Logs

N/A

### Flutter Doctor output

Doctor output

```console
$ flutter doctor -v
[✓] Flutter (Channel master, 3.23.0-13.0.pre.80, on Fedora Linux 40 (Workstation Edition) 6.8.10-300.fc40.x86_64, locale en_US.utf8)
• Flutter version 3.23.0-13.0.pre.80 on channel master at /opt/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 5e448f4ce5 (5 hours ago), 2024-06-03 12:44:39 -0700
• Engine revision ea72558be7
• Dart version 3.5.0 (build 3.5.0-214.0.dev)
• DevTools version 2.36.0

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
• Android SDK at /home/luke/Android/Sdk
• Platform android-34, build-tools 34.0.0
• Java binary at: /opt/android-studio/jbr/bin/java
• Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11572160)
• All Android licenses accepted.

[✓] Chrome - develop for the web
• Chrome at google-chrome

[✓] Linux toolchain - develop for Linux desktop
• clang version 18.1.6 (Fedora 18.1.6-3.fc40)
• cmake version 3.28.2
• ninja version 1.11.1
• pkg-config version 2.1.0

[✓] Android Studio (version 2023.3)
• Android Studio at /opt/android-studio
• Flutter plugin version 79.0.2
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11572160)

[✓] VS Code (version 1.89.1)
• VS Code at /usr/share/code
• Flutter extension version 3.91.20240529

[✓] VS Code (version 1.90.0-insider)
• VS Code at /usr/share/code-insiders
• Flutter extension version 3.89.20240501

[✓] Connected device (3 available)
• sdk gphone64 x86 64 (mobile) • emulator-5554 • android-x64 • Android 14 (API 34) (emulator)
• Linux (desktop) • linux • linux-x64 • Fedora Linux 40 (Workstation Edition) 6.8.10-300.fc40.x86_64
• Chrome (web) • chrome • web-javascript • Google Chrome 125.0.6422.112
! Device 99121FFAZ005NP is not authorized.
You might need to check your device for an authorization dialog.

[✓] Network resources
• All expected network resources are available.

• No issues found!
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.