Behind the feature: shedding light on shadow spread | Figma Blog (opens in new tab)
Figma’s shadow spread feature appeared simple but required solving difficult geometry and rendering problems. Shadow spread must expand or contract a shape uniformly in every direction, which cannot be achieved reliably by merely scaling complex geometry. The feature ultimately illustrates how seemingly small product requests demand careful algorithmic and product tradeoffs. ## What Shadow Spread Does - Figma added support for adjusting shadow spread on: - Rectangles - Ellipses - Frame backgrounds - Component backgrounds - The feature mirrors CSS `box-shadow` behavior. - Users had requested the capability for more than two years. ## Why Shadow Rendering Is Complicated - A standard drop shadow is created by: - Copying an object’s geometry - Filling it with a single color - Applying a blur - Rendering it beneath the original object - Simply scaling the geometry works for basic rectangles but fails for complex shapes. - For shapes with holes, such as the Figma logo, spread must expand or contract every boundary independently rather than scale the entire object. - Correct behavior requires preserving the shape’s internal structure while offsetting its edges uniformly. ## Algorithmic and Rendering Constraints - Several algorithms could produce the desired geometry, but they did not fit cleanly into Figma’s existing rendering architecture. - Using strokes as a shortcut was also unsuitable because: - Stroke handling treats certain vertex angles differently from shadow spread. - The prototype renderer lacked stroke-generation code. - Implementing the feature robustly risked adding complicated geometry logic to two separate rendering codebases. ## Lessons from the Implementation - The project began as a small Maker Week experiment but grew into a weeks-long engineering effort. - The work involved exploring geometry algorithms, studying relevant W3C specifications, and making product-prioritization decisions. - The feature demonstrates that visual effects which appear basic in a user interface can require substantial low-level rendering infrastructure. Figma’s approach was to balance visual correctness, implementation complexity, and compatibility with its existing renderers rather than pursue an idealized solution at any cost.