Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter BoxShadow overlapping siblings

I'm trying to create a Row of containers that all have a BoxShadow. The shadows are quite large and therefore span into space that's outside of the parent, so I'm using clipBehavior: Clip.none on the parent.

The problem with this is that for each Container within the row it's shadow overlaps into the previous container. I've set some bold colors below to emphasize the issue. As you can see the right-hand side of the previous Container gets the shadow from the next.

BoxShadow overlapping

Here's my code

return SingleChildScrollView(
    clipBehavior: Clip.none,
    scrollDirection: Axis.horizontal,
    child: Row(
      children: [
        _ShadowedBox(),
        _ShadowedBox(),
        _ShadowedBox(),
      ],
    ),
  );


class _ShadowedBox extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 144,
      child: Column(
        children: [
          SizedBox(
            width: 144,
            height: 144,
            child: Container(
                decoration: BoxDecoration(
                              color: Colors.grey,
                              shape: BoxShape.rectangle,
                              borderRadius: BorderRadius.circular(cardRadius),
                              boxShadow: [
                                BoxShadow(
                                  offset: const Offset(0.0, 6.0),
                                  blurRadius: 38.0,
                                  spreadRadius: 0.0,
                                  color: Colors.red,
                                ),
                                BoxShadow(
                                  offset: const Offset(0.0, 6.0),
                                  blurRadius: 46.0,
                                  spreadRadius: 0.0,
                                  color: Colors.green,
                                ),
                                BoxShadow(
                                  offset: const Offset(0.0, 6.0),
                                  blurRadius: 10.0,
                                  spreadRadius: 0.0,
                                  color: Colors.blue,
                                ),
                              ]
                          ),
                child: ClipRRect(
                    borderRadius: BorderRadius.circular(cardRadius),
                    child: Image.network("https://via.placeholder.com/400x400.png?text=Coming%20soon", fit: BoxFit.contain)
            ),
          ),
        ],
      ),
    );
  }
}

Can anyone suggest how to stop the shadow bleeding into the other containers while still being able to show the shadows not being clipped by the parent?

like image 245
Andrew Avatar asked Jul 10 '26 09:07

Andrew


1 Answers

Okay I've tested 2 approaches to fix your issue. As Wapazz said, each of your Container is drawn separately with its own shadow so they will overlap.

Solution #1

A solution could be to apply the shadow effect to your Row widget instead of the _ShadowedBox but the shadow effect wouldn't be as precise:

Code

SingleChildScrollView(
  clipBehavior: Clip.none,
  scrollDirection: Axis.horizontal,
  child: UnconstrainedBox(
    child: Container(
      decoration: BoxDecoration(
        boxShadow: [
          BoxShadow(
            offset: const Offset(0.0, 6.0),
            blurRadius: 38.0,
            spreadRadius: 0.0,
            color: Colors.red,
          ),
          BoxShadow(
            offset: const Offset(0.0, 6.0),
            blurRadius: 46.0,
            spreadRadius: 0.0,
            color: Colors.green,
          ),
          BoxShadow(
            offset: const Offset(0.0, 6.0),
            blurRadius: 10.0,
            spreadRadius: 0.0,
            color: Colors.blue,
          ),
        ],
      ),
      child: Row(
        children: List<Widget>.generate(10, (_) => _ShadowedBox()),
      ),
    ),
  ),
),

Result

enter image description here

Solution #2

The other solution I've found would be to use a Stack widget with all the shadows rendered in a separate Row, so the resulting shadows have the correct shape. The issue with this method being that you need a fixed width and height for your widget:

Code

SingleChildScrollView(
  clipBehavior: Clip.none,
  scrollDirection: Axis.horizontal,
  child: Stack(
    children: [
      Row(
        children: List<Widget>.generate(
          10,
          (_) => Container(
            margin: const EdgeInsets.symmetric(horizontal: 4),
            width: 144,
            height: 144,
            decoration: BoxDecoration(
              shape: BoxShape.rectangle,
              borderRadius: BorderRadius.circular(cardRadius),
              boxShadow: [
                BoxShadow(
                  offset: const Offset(0.0, 6.0),
                  blurRadius: 38.0,
                  spreadRadius: 0.0,
                  color: Colors.red,
                ),
                BoxShadow(
                  offset: const Offset(0.0, 6.0),
                  blurRadius: 46.0,
                  spreadRadius: 0.0,
                  color: Colors.green,
                ),
                BoxShadow(
                  offset: const Offset(0.0, 6.0),
                  blurRadius: 10.0,
                  spreadRadius: 0.0,
                  color: Colors.blue,
                ),
              ],
            ),
          ),
        ),
      ),
      Row(
        children: List<Widget>.generate(10, (_) => _ShadowedBox()),
      ),
    ],
  ),
)

Result

enter image description here

You can try my full test code on DartPad

like image 164
Guillaume Roux Avatar answered Jul 13 '26 14:07

Guillaume Roux