Ivy Walobwa Ivy is a Flutter developer and technical writer who is interested in creating awesome developer experiences. She is currently a Program Assistant for the Google Africa Developer Scholarship (GADS), where she helps facilitate the learning of students across Africa.

Enhance your mobile apps with Flutter BoxShadow

5 min read 1659

Flutter Logo

Google’s Material Design guidelines have become the signature look for many modern websites and apps. Material Design supports experiences that mimic real-world objects, so light and shadows are important aspects of any app development process that follows these guidelines.

An object can reflect light or, if it obscures the light source, it can cast a shadow. Shadows can indicate depth, the direction of movement, and surface edges.

Adding shadows to elements in an app can aid with user identification of the elements, communicate interactivity, and help elements stand out and be easier to locate.

In this tutorial, we’ll demonstrate how to apply shadows to Flutter apps using the BoxShadow class. We’ll also look at a couple of special use cases: applying a shadow to only one side of a box and applying an inner shadow.

Applying the Flutter BoxShadow class

The Flutter BoxShadow class is used to create and style a shadow cast by a box. The box could be a frame around an image or message, or it could be a button or modal. The BoxShadow class must be implemented inside a BoxDecoration widget.

The shadow implies its elevation relative to other surfaces and the direction of light hitting the surface. The shadow also takes on the shape of the box. BoxShadow takes several properties, including:

  • color: adds color to the shadow; the default is black
  • spreadRadius; establishes how large of a span the BoxShadow widget should inflate the box
  • blurRadius: adds blur to the shadow
  • blurStyle: defines style to use on the blur; the default is BlurStyle.normal
  • offset: creates x and y offsets

Now, let’s take a look at how to implement these properties to cast shadows to an element in a demo app.

For this tutorial, we’ll add a BoxShadow to the app below. The app consists of a centered Container widget with an Icon widget.

Default Box Without Shadow
Default box without any shadow.

The BoxDecoration widget has a boxShadow property which expects a list of BoxShadow.

...
Scaffold(
  backgroundColor: Colors.grey.shade300,
  body: Center(
    child: Container(
      height: 100,
      width: 150,
      child: const Icon(Icons.downhill_skiing),
      decoration: BoxDecoration(
        color: Colors.grey.shade300,
        boxShadow: [],
      ),
    ),
  ),
)

Adding color

First let’s add a BoxShadow to our list:

We made a custom demo for .
No really. Click here to check it out.

 BoxDecoration(
  color: Colors.grey.shade300, // this is the container's color
  boxShadow: [
    BoxShadow(), // no shadow color set, defaults to black
  ]
)
Default Box Shadow Color
Box with default box shadow color.

The BoxShadow is added below the Container. To illustrate this, we’ll give our Container a transparent color. In this example, the shadow is painted in the default color (black) in the shape of our box as shown:

 BoxDecoration(
  color: Colors.transparent,
  boxShadow: [
    BoxShadow(), // no shadow color set, defaults to black
  ]
)
Transparent Box Default Shadow Color
Transparent box with default shadow color.

To add a color to the shadow, we’ll make use of the color property. We’ll add a grey shadow to our app.

color: Colors.grey.shade600

Adding a spread radius

The default spreadRadius is zero. Positive values increase the size of the shadow while negative values decrease the size.

We’ll give our Container a spreadRadius of one, as shown below:

boxShadow: [
  BoxShadow(
    color: Colors.grey.shade600,
    spreadRadius: 1,
  )
]
Box Spread With Radius of One
Box with a spread radius of one.

Adding a blur radius

The default blurRadius is zero which creates a sharp shadow. It only takes positive values. The higher the radius value, the more blurred the shadow will be, and the further out the shadow will spread.

We’ll give our Container a blurRadius of 15.

boxShadow: [
  BoxShadow(
    color: Colors.grey.shade600,
    spreadRadius: 1,
    blurRadius: 15
  )
]
Box Blur Radius of 15
Box with blur radius of 15.

Adding a blur style

To change the style of the blur, we update the blurStyle property. The property takes in a BlurStyle enum which paints shadows based on the selected value.

The available styles include:

  • BlurStyle.normal: paints a blur that appears hazy on both the inside and the outside; this is the default BlurStyle
Box Normal Blur Style
Box with normal blur style.
  • BlurStyle.solid: paints a solid blur on the inside and a hazy blur on the outside:

    Box Solid Blur Style
    Box with solid blur style.
  • BlurStyle.outer: paints a hazy blur on the outside and nothing on the inside:

    Box Outer Blur Style
    Box with outer blur style.
  • BlurStyle.inner: paints a hazy blur on the inside and nothing on the outside:

    Box Inner Blur Style
    Box with inner blur style.

In this tutorial, we’ll use the default blur style, BlurStyle.normal.

Adding an offset

To add an offset, we use the Offset class which takes in x and y values: Offset(dx, dy). It accepts both negative and positive values. The default offset is Offset.zero.

To offset the shadow horizontally, the dx value is changed. A positive offset moves the shadow to the right of the box, while a negative offset moves the shadow to the left of the box.

To offset the shadow vertically, the dy value is changed. A negative offset moves the shadow above the box, while a positive offset moves the shadow below the box.

If both the dx and dy offset values are set to zero, the shadow is centered behind the box.

Offset Illustration
Offset illustration.

We’ll give our container a dx offset of zero and a dy offset of 15. This will move our shadow down.

boxShadow: [
  BoxShadow(
    color: Colors.grey.shade600,
    spreadRadius: 1,
    blurRadius: 15,
    offset: const Offset(0, 15)
  )
]
Box Vertical Offset of 15
Box with a vertical offset of 15.

To scale a shadow, we can use the scale method. This method returns a new box shadow with its offset, blurRadius, and spreadRadius scaled by the given factor.

boxShadow: [
  BoxShadow(
    color: Colors.grey.shade600,
    spreadRadius: 1,
    blurRadius: 15,
    offset: const Offset(0, 15),
  ).scale(4)
]

Now that we understand how to use the various BoxShadow properties, we can enhance the styling of our Flutter app elements.

Applying BoxShadow to one side of a container

The BoxDecoration’s boxShadow property takes a list of shadows. This list can be used to shift shadows to the desired sides of a box.

To apply a shadow to only one side of a box, we need to shift or hide the shadows on all the remaining sides. This can be accomplished by adding a list of shadows with varying offsets.

We can add a box shadow to the bottom of our Container using the following steps:

Step 1: Hide the top shadow

To hide the top shadow, we need to set our dy offset value to a positive number greater than our blur radius. This moves the shadow down, hiding it behind the Container.

boxShadow: [
  BoxShadow(
    color: Colors.grey.shade600,
    spreadRadius: 1,
    blurRadius: 5,
    offset: const Offset(0, 5),
  )
]
Box Top Shadow Hidden
Box with top shadow hidden.

Step 2: Hide the left shadow

If we add a new BoxShadow to our list, we can use its offset to hide the left shadow. This new shadow will need to have the same color as our Container.

In addition, we’ll need to set the dx value to a negative value greater than or equal to the blur radius of the first shadow. This moves the new shadow to the left, hiding the initial left shadow.

boxShadow: [
  BoxShadow(
    color: Colors.grey.shade600,
    spreadRadius: 1,
    blurRadius: 5,
    offset: const Offset(0, 5),
  ),
  BoxShadow(
    color: Colors.grey.shade300,
    offset: const Offset(-5,0),
  )
]
Box Top Left Shadow Hidden
Box with top and left shadow hidden.

Step 3: Hide the right shadow

If we add a new BoxShadow to our list, we can use its offset to hide the right shadow. Just like the process from Step 2, this new shadow needs to have the same color as our Container.

We’ll need to set the dx value to a positive value greater than or equal to the blur radius of the first shadow. This moves the new shadow to the right, hiding the initial right shadow.

boxShadow: [
  BoxShadow(
    color: Colors.grey.shade600,
    spreadRadius: 1,
    blurRadius: 5,
    offset: const Offset(0, 5),
  ),
  BoxShadow(
    color: Colors.grey.shade300,
    offset: const Offset(-5,0),
  ),
  BoxShadow(
    color: Colors.grey.shade300,
    offset: const Offset(5,0),
  )
] 
Box Bottom Shadow Only
Box with bottom shadow only.

With these three steps, we have managed to visually show the shadow on the bottom of our Container.

Applying BoxShadow for an inner shadow effect

We can apply inner shadows to a Container by tweaking the shadows and adding a linear gradient.

This is a two-step process.

Step 1: Add two shadows of different colors

For this example, we’ll add two shadows, one white and one grey, and offset them opposite to each other:

boxShadow: [
  BoxShadow(
    color: Colors.grey.shade600,
    spreadRadius: 1,
    blurRadius: 15,
    offset: const Offset(5, 5),
  ),
  const BoxShadow(
    color: Colors.white,
    offset: Offset(-5,-5),
    blurRadius: 15,
    spreadRadius: 1
  ) ,
],

Step 2: Add a linear gradient

We’ll use the BoxDecoration‘s gradient property to create a linear gradient:

BoxDecoration(
...
  boxShadow: [
    BoxShadow(
      color: Colors.grey.shade600,
      spreadRadius: 1,
      blurRadius: 15,
      offset: const Offset(5, 5),
    ),
    const BoxShadow(
      color: Colors.white,
      offset: Offset(-5,-5),
      blurRadius: 15,
      spreadRadius: 1
    ) ,
  ],
  gradient: LinearGradient(
    begin: Alignment.topLeft,
    end: Alignment.bottomRight,
    colors: [
      Colors.grey.shade200,
      Colors.grey.shade300,
      Colors.grey.shade400,
      Colors.grey.shade500,
    ],
  ),
)
Rectangular Box Inner Shadow
Rectangular box with inner shadow effect.

The shadow takes the shape of the Container when its shape is changed.

Circular Box Inner Shadow
Circular box with inner shadow effect.

Conclusion

In this tutorial, we covered how to apply box shadows to a container in a Flutter app. We showed how to adjust the color, spread radius, blur radius, blur style and offset of the shadow. We also demonstrated how to add shadows to just one side of a container and how to create an inner shadow effect.

All the code in this article is available on GitHub. I hope you enjoyed this tutorial!

: Full visibility into your web apps

LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.

.
Ivy Walobwa Ivy is a Flutter developer and technical writer who is interested in creating awesome developer experiences. She is currently a Program Assistant for the Google Africa Developer Scholarship (GADS), where she helps facilitate the learning of students across Africa.

Leave a Reply