Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ShadowBox inset attribute? Inner shadow #18636

Open
macher91 opened this issue Jun 20, 2018 · 47 comments
Open

ShadowBox inset attribute? Inner shadow #18636

macher91 opened this issue Jun 20, 2018 · 47 comments
Labels
c: new feature Nothing broken; request for a new capability framework flutter/packages/flutter repository. See also f: labels. P3 Issues that are less important to the Flutter project team-framework Owned by Framework team triaged-framework Triaged by Framework team

Comments

@macher91
Copy link

I didn't find any trace of inner shadow for box.
Like in CSS using box-shadow: inset there is a option to achieve the same effect?

@zoechi zoechi added c: new feature Nothing broken; request for a new capability framework flutter/packages/flutter repository. See also f: labels. labels Jun 20, 2018
@zoechi
Copy link
Contributor

zoechi commented Jun 20, 2018

cc @HansMuller

@HansMuller
Copy link
Contributor

The Material widget has an elevation (and a shape!). It's rendered with a shadow that's based on the elevation.

@zoechi
Copy link
Contributor

zoechi commented Jun 20, 2018

@HansMuller I think he is looking for an inside shadow like https://css-tricks.com/snippets/css/css-box-shadow/#article-header-id-2

@macher91
Copy link
Author

@zoechi provided example what I want achieve

@HansMuller
Copy link
Contributor

@zoechi I see. We don't have explicit support for "inward" shadows however that seems like a reasonable thing to add.

@thenexus00
Copy link

You can add paralax to an image, lets say a header image for a listing, but then also adding an inner shadow so it looks set back would give a great 3d effect people would want to be able to do.

@zoechi zoechi added this to the Stretch Goals milestone Jan 28, 2019
@sean-krail
Copy link

I'm looking for this feature in order to add inner shadow to the background widget of dismissible widgets. That way it would appear as though my list tiles are elevated above it.

@zurie
Copy link

zurie commented Apr 13, 2019

Its important to add that this should be transparent, or support transparency. The same effect can be created with no transparency by stacking boxShadow's but you are left with the top boxShadow's color. What would be nice is to be able to put this "over" another item, in a stack and this shadow effect shows through to the stack below.

@marcoms
Copy link
Contributor

marcoms commented May 7, 2019

I wanted to use this feature to add an inset shadow on my map widget, so that it could look embedded in the page. Unfortunately I can't find a workaround for this.

@mrinc
Copy link

mrinc commented Dec 26, 2019

Any further work on this?

@AndreHaueisen
Copy link

Do we have an update on this feature?

@Hixie Hixie modified the milestones: Stretch Goals, New Stretch Goals Jan 7, 2020
@Kontra21
Copy link

Kontra21 commented Jan 8, 2020

Also looking for this feature

@Kontra21
Copy link

Kontra21 commented Jan 8, 2020

To add on to this, a lot of people are looking for this to work on "neumorphism UI" elements to their applications

@benthillerkus
Copy link

I'd also love to see inset shadows for text.

@jeaanlucas
Copy link

Any news about this?

@AirborneEagle
Copy link

AirborneEagle commented Jan 25, 2020

I am actually surprised.

Seeing as animation and 'Beautiful UI' is one of the main selling points for flutter, I would have imagined this feature would be taken more seriously. Instead it is on the back burner "Stretch goals".
@filiph, or @zoechi , Who is the one that would decides if this is to be worked on?

I would offer to help with it, but sadly I am far from experienced with the inner workings Flutter.

@5hanth
Copy link

5hanth commented Feb 4, 2020

Hey guys how is your day?

@JAMBAARDEV
Copy link

May be this can help >> https://www.youtube.com/watch?v=oTYDD3nZ-ZA

@AirborneEagle
Copy link

AirborneEagle commented Feb 13, 2020

I found this approach. and it is what I am using.
took some fiddling, but it works really well :) .
it is not just a linear gradient like moist other workarounds I have tried
https://twitter.com/luigirosso/status/1208286460610113541

@bhaskar-nair2
Copy link

bhaskar-nair2 commented Feb 14, 2020

If you are here because you wish to make a neumorphic button, you really don't need a inner shadow, try the following code for a circular container over a Color.fromRGBO(231, 232, 234, 1) background

 boxShadow: _selected
              ? [
                  BoxShadow(
                    color: Colors.black26,
                    blurRadius: 20,
                    spreadRadius: 2,
                    offset: Offset(12, 12),
                  ),
                  BoxShadow(
                    color: Colors.white70,
                    blurRadius: 20,
                    spreadRadius: 2,
                    offset: Offset(-12, -12),
                  ),
                ]
              : [
                  BoxShadow(
                    color: Colors.black26,
                    blurRadius: 30,
                    spreadRadius: 2,
                    offset: Offset(-12, -12),
                  ),
                  BoxShadow(
                    color: Colors.white60,
                    blurRadius: 20,
                    spreadRadius: 2,
                    offset: Offset(12, 12),
                  ),
                ]

Play with this and you have the desired effect..

P.S. Lighter color has to be after the darker one when defining boxShadows.

The full code for the same is here- https://gist.github.com/bhaskar-nair2/88bdb05f3d776b6a94c430fbd048e67f

@benthillerkus
Copy link

And (as far as I've seen) there seems to be no good hacked together solution for text anyways

@rfitz123
Copy link

Where is this? I can't believe a modern framework doesn't have such a basic UI element.

@Skquark
Copy link

Skquark commented Mar 14, 2020

I think what most of us are looking for is an Inner Box Bevel with similar parameters as Photoshop Blending Options, but the way to hack that in CSS is using an inset shadow. It would be nice if BoxShadow has an option to make inset: true, or to allow blurRadius & spreadRadius be a negative value. It would also be amazing to have a boxDecoration component like boxBevel: BoxBevel(depth: 22, size: 7, soften: 2, angle: -39, altitude: 26, highlightColor: Colors.white54, shadowColor: Colors.black54, highlightBlendMode: BlendMode.screen, shadowBlendMode: BlendMode.multiply, style: BoxBevelStyle.smooth), and to do the same for TextBevel..
While I'm dreaming as a designer/programmer, have Emboss, Chisel Hard, Chisel Soft, Contour, Inner Glow, Satin, Stroke, Pattern Overlay, and all that good stuff built into the Flutter framework. There are some nice addons out there that come close at least, along with some complex CustomPainter or ShaderMask tricks, but we all love easy. We'll just have to do it in Adobe software exported as png to get the look we wanted to do in the code, but I don't want to sound ungrateful.. I think UI in our apps would evolve nicely with those extra design tools in our arsenal, as long as we don't abuse them...

@dxlimited
Copy link

I vote for this too, been hacking at this for days now.

@kf6gpe kf6gpe added the P3 Issues that are less important to the Flutter project label May 29, 2020
@Hixie Hixie removed this from the [DEPRECATED] Stretch Goals milestone Jun 16, 2020
@comyuno
Copy link

comyuno commented Jul 27, 2020

Inner Shadow property would be very useful for (rounded) TextFields. Maybe the trend is already outdated when this is introduced ;)

@Hixie Hixie removed this from the - milestone Aug 17, 2020
@MaximRyabovol
Copy link

This source was useful for me. Base on this source I built a circle with transparent background and the same time the circle has an inner shadows. In short, need to use RadialGradient in an Container's BoxDecoration.

`Container(
                      decoration: BoxDecoration(
                        shape: BoxShape.circle,
                        gradient: RadialGradient(
                          colors: [
                            Colors.black.withOpacity(0.0),
                            Colors.black.withOpacity(0.2),
                          ],
                          center: AlignmentDirectional(0.0, 0.0),
                          focal: AlignmentDirectional(0.0, 0.0),
                          radius: 0.60,
                          focalRadius: 0.001,
                          stops: [0.75, 1.0],
                        ),
                      ),
                    ),`


@Josip-Muzic
Copy link

@MaximRyabovol thank you so much for your comment, that is EXACTLY what I needed!

@pncosta
Copy link

pncosta commented Apr 5, 2021

any hope this will ever be added?

now that web is officially supported I would expect that such a basic task would be easy to achieve, specially if flutter wants to conquer developers that are already used to how easy things like this are in CSS

@reiko-dev
Copy link

I vote for this implementation.

@olksij
Copy link

olksij commented Jun 29, 2021

I had an idea about inner shadow implementation and creating neumorphism effect in Flutter. How about creating the parent container (with Clip.hardEdge), which has drop shadows (regular ones), and a child container with other two shadows, which, after clipping, looks like inner ones.

InnerShadow
(Preview of the result)

Have a look at code here :)

I hope i have helped at least someone 😄

@deepak-penaganti
Copy link
Contributor

Please refer to #88697

@abhaysood
Copy link

abhaysood commented Oct 6, 2021

@deepak-penaganti @Piinks @dnfield
I was testing the new BlurStyle.inner as a way to add an inner shadow. I was expecting results similar to CSS box-shadow: inset. But these don't seem to be same effects as #88697 claims.

I'm providing an example with CSS and Flutter below to make this clear. You can even try this on Figma.

Inner Shadow Specification

Blur: 10
Shadow Color: #FF000000
Offset: (0, 2)
Spread: 0

CSS Example

CSS Sample Code
<!DOCTYPE html>
<html>
<head>
<style> 
#example1 {
  padding: 10px;
  box-shadow: inset 0px 2px 10px rgba(0, 0, 0, 1);
}
</style>
</head>
<body>

<h2>box-shadow</h2>
<div id="example1">
  <p>A div element with a shadow. The first value is the horizontal offset and the second value is the vertical offset. The shadow color will be inherited from the text color.</p>
</div>


</body>
</html>

image

Flutter Example

Flutter Sample Code
class Demo extends StatelessWidget {
  const Demo({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Center(
        child: SizedBox(
          width: 200,
          height: 200,
          child: Container(
            decoration: BoxDecoration(
              boxShadow: [
                BoxShadow(
                  blurStyle: BlurStyle.inner,
                  color: Color(0xFF000000),
                  offset: Offset(0, 2),
                  blurRadius: 4,
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

136161020-aaffec97-57a8-4ea2-ac12-5a534cc12436

Issue

On Flutter the color is getting applied to the entire container. While what was expected was a inner shadow with a blur of 10 & offest of (0, 2) as seen in the CSS sample. Hence, what happens with BlurStyle.inner is not equivalent to an inner shadow. It simply adds a blur effect to the inside edge of the container.

@TronIsHere
Copy link

any update on this?

@AlexanderFarkas
Copy link

It's been 4 years, and it's still open. Is there any easy way to achieve the same behavior CSS has?

@TronIsHere
Copy link

TronIsHere commented Jan 26, 2022

found a simple solution for now! you can use Stack and LinearGradient together so you can mimic the inset shadow similar to CSS... example :

Stack(
                    children: [
                      Container(
                        width: MediaQuery.of(context).size.width,
                        height: 210,
                        decoration: BoxDecoration(
                            image: DecorationImage(
                                image: NetworkImage(
                                    'https://images.unsplash.com/photo-1559305616-3f99cd43e353?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=735&q=80'),
                                fit: BoxFit.cover)
                        ),
                      ),
                      Container(
                        height: 210,
                        decoration: BoxDecoration(
                          gradient: LinearGradient(
                              begin: Alignment.bottomCenter,
                              end: Alignment.topCenter,
                              colors:[
                                Colors.black,
                                Colors.transparent,
                                Colors.transparent,
                              ]
                          ),
                        ),
                      ),
                    ],
                  ),

try playing with the colors in LinearGradient to get the result you want

@HansMuller
Copy link
Contributor

@flar - this request has been simmering for a long (long) time. Do you think it would be possible to add support for inner shadows like this example #18636 (comment) ?

@jttuboi
Copy link

jttuboi commented Mar 2, 2022

Hi, I found a workaround solution in https://github.com/happyharis/neumorphic
I haven't used BlurStyle.inner. It didn't work.

image

Container(
  decoration: BoxDecoration(
    boxShadow: [
      //CSS: inset 0px 4px 6px rgba(8, 56, 73, 0.5)
      BoxShadow(
        color: const Color.fromRGBO(8, 56, 73, 0.5), // shadow color
      ),
      const BoxShadow(
        offset: Offset(0, 4),
        blurRadius: 6,
        color: Color(0xFFF9F8F9), // background color
      ),
    ],
    borderRadius: BorderRadius.circular(25),
  ),
  child: TextField(...),
),

I hope this helps someone.

@wcandillon
Copy link

React Native developer here 🙋🏼‍♂️

We implemented inner shadows using the following combination of Skia image filters:

const f1 = ImageFilter.MakeColorFilter(
  ColorFilter.MakeBlend(cl, BlendMode.SrcOut),
  null
);
const f2 = ImageFilter.MakeOffset(dx, dy, f1);
const f3 = ImageFilter.MakeBlur(blur, blur, TileMode.Decal, f2);
const f4 = ImageFilter.MakeBlend(BlendMode.SrcIn, sourceAlpha, f3);
if (shadowOnly) {
  return f4;
}
return ImageFilter.MakeCompose(
  input,
  ImageFilter.MakeBlend(BlendMode.SrcOver, sourceGraphic, f4)
);

Does the recipe look correct? As far as we tested it, it seems to work nicely. I'm curious why this is not an available part of Skia (drop shadow is) and why this is not part of Flutter either. Are there some challenges with this implementation that we may be overlooking?

@ghost
Copy link

ghost commented Mar 17, 2022

Hello everyone! 😄

We have just published this package: https://pub.dev/packages/flutter_inset_box_shadow.

It adds an inset property to BoxShadow, and provides an alternative to BoxDecoration capable of painting these shadows.

The algorithm used is the same as the one used by Blink, the Chromium renderer: we draw a rectangle hollowed by another rounded rectangle, then we blur this hollowed rectangle.

It is possible that there are still bugs in some cases, do not hesitate to inform us by creating an issue.

I hope it will be useful to some!

@wcandillon
Copy link

@johynpapin congrats! I wanted to check blink's source code for this but struggled to find the relevant file, you could point it to me?

@ghost
Copy link

ghost commented Mar 17, 2022

Thank you! 🙏 Here is the link to the main function that handles this: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/paint/box_painter_base.cc;l=254;drc=98cdb728ae59ac1151f4406d426233f86498eedd;bpv=1;bpt=1

EDIT: I can create a pull request to Flutter if the method is good.

@abhaysood
Copy link

This is the most efficient implementation I've seen so far. I tried a few cases with Figma and it looks the same to naked eye.

I had resorted to a work around which was also based on a similar approach but we had to use saveLayer with a srcOut blend mode to diff between the two rectangles.

TIL drawDRRect which calls the native Canvas_drawDRRect and will surely be efficient compared to saveLayer.

Thanks for sharing, looking forward for this to be implemented along with BoxDecoration.

@wcandillon
Copy link

@johynpapin Thank you for sharing your implementation 🙌🏼 We will use it for boxes as well since it is much faster. For anything else like path or text inner shadows, the implementation in my last comment is the way to go.

@vasilich6107

This comment was marked as duplicate.

@flutter-triage-bot flutter-triage-bot bot added team-framework Owned by Framework team triaged-framework Triaged by Framework team labels Jul 8, 2023
@Andreigr0
Copy link

Maybe we could apply some shaders to reach the desired effects without performance drop (in https://pub.dev/packages/flutter_inset_box_shadow package)?

@YuryMorozov2001

This comment was marked as duplicate.

@goerlitz
Copy link

Any update on this 6 year old feature request?

I came here, because I want to have top and bottom inner shadow for a SingleChildScrollView, but the solution given in #24567 does not work at all.

It is hard to believe that flutter does not support such a common feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c: new feature Nothing broken; request for a new capability framework flutter/packages/flutter repository. See also f: labels. P3 Issues that are less important to the Flutter project team-framework Owned by Framework team triaged-framework Triaged by Framework team
Projects
None yet
Development

No branches or pull requests