SVG Drop Shadows
SVG Filter Effects: Creating Drop Shadows with
Section titled “SVG Filter Effects: Creating Drop Shadows with ” and Elements
Section titled “ and Elements”All SVG filter effects are defined within a <defs> element. The <defs> (definitions) element is a container for reusable graphical objects that are not rendered directly but can be referenced by other elements.
The <filter> element defines an SVG filter. It requires an id attribute, which provides a unique name for the filter. Graphics can then apply this filter using the filter attribute (e.g., filter="url(#filterId)"). A filter can contain one or more filter primitives, which perform specific graphical operations.
The x, y, width, and height attributes on the <filter> element define the filter effects region. It’s often necessary to make this region larger than the target element to accommodate effects like blurs or offsets that extend beyond the element’s original bounds.
SVG Filter Primitive
Section titled “SVG Filter Primitive”The <feOffset> filter primitive is used to create effects like drop shadows by displacing the input graphic.
Example 1: Basic Offset and Blend
Section titled “Example 1: Basic Offset and Blend”The <feOffset> primitive takes an input graphic (specified by the in attribute, often SourceGraphic for the original element) and shifts it by a specified amount in the x (dx) and y (dy) directions. The result of this operation (specified by the result attribute) can then be used by other filter primitives. In this example, we offset a rectangle and then use <feBlend> to combine the original graphic with its offset version.
Visually, this creates a simple, hard-edged drop shadow where the original yellow rectangle has a slightly offset, identical copy beneath it.
Here is the SVG code:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>SVG feOffset Example 1</title></head><body> <svg width="150" height="150"> <defs> <filter id="f1" x="-20%" y="-20%" width="140%" height="140%"> <feOffset in="SourceGraphic" dx="10" dy="10" result="offOut" /> <feBlend in="SourceGraphic" in2="offOut" mode="normal" /> </filter> </defs> <rect width="90" height="90" x="10" y="10" stroke="green" stroke-width="3" fill="yellow" filter="url(#f1)" /> </svg></body></html>Code Explanation (Example 1):
<filter id="f1" ...>: Defines the filter with ID “f1” and extends the filter region.<feOffset in="SourceGraphic" dx="10" dy="10" result="offOut" />: Takes the original graphic (SourceGraphic), shifts it 10 units down and 10 units right, and names the outputoffOut.<feBlend in="SourceGraphic" in2="offOut" mode="normal" />: Takes the original graphic (SourceGraphic) and the offset graphic (offOut) and blends them.mode="normal"typically means the top layer (SourceGraphicif listed first, or as per default layering of blend inputs) is drawn over the bottom layer.filter="url(#f1)": Applies the filter “f1” to the rectangle.
Example 2: Adding Blur for a Softer Shadow
Section titled “Example 2: Adding Blur for a Softer Shadow”To create a more realistic, softer drop shadow, we can blur the offset image using the <feGaussianBlur> filter primitive before blending.
Visually, this adds a blur to the offset copy, making the shadow appear softer and more diffuse, which is typical for realistic shadows.
Here is the SVG code:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>SVG feOffset Example 2</title></head><body> <svg width="180" height="180"> <defs> <filter id="f2" x="-40%" y="-40%" width="180%" height="180%"> <feOffset in="SourceGraphic" dx="10" dy="10" result="offOut" /> <feGaussianBlur in="offOut" stdDeviation="5" result="blurOut" /> <feMerge> <feMergeNode in="blurOut" /> <feMergeNode in="SourceGraphic" /> </feMerge> </filter> </defs> <rect width="90" height="90" x="20" y="20" stroke="green" stroke-width="3" fill="yellow" filter="url(#f2)" /> </svg></body></html>Code Explanation (Example 2):
<feGaussianBlur in="offOut" stdDeviation="5" result="blurOut" />: Takes the result offeOffset(offOut) and applies a Gaussian blur with a standard deviation of 5. The higher thestdDeviation, the blurrier the result. The output is namedblurOut.<feMerge>: This primitive is used to combine multiple layers.<feMergeNode>specifies each layer. Here, the blurred shadow (blurOut) is drawn first, and then the original graphic (SourceGraphic) is drawn on top. This is a common way to layer elements in filters, an alternative tofeBlendfor simple stacking.
Example 3: Creating a Black Shadow using SourceAlpha
Section titled “Example 3: Creating a Black Shadow using SourceAlpha”Often, you want the shadow to be a specific color (like black or gray) rather than a displaced copy of the original graphic’s colors. To achieve this, you can use SourceAlpha as the input to feOffset. SourceAlpha represents the alpha channel (transparency information) of the original graphic. We then use <feFlood> to create a solid color and <feComposite> to combine it with the alpha mask.
Visually, by using ‘SourceAlpha’, the shadow becomes a solid black (or the color defined by feFlood) silhouette of the shape, blurred and offset, rather than a colored offset of the original.
Here is the SVG code:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>SVG feOffset Example 3</title></head><body> <svg width="180" height="180"> <defs> <filter id="f3" x="-40%" y="-40%" width="180%" height="180%"> <!-- Create a black flood fill --> <feFlood flood-color="black" flood-opacity="0.7" result="flood" /> <!-- Use SourceAlpha and composite with flood to colorize the shadow shape --> <feComposite in="flood" in2="SourceAlpha" operator="in" result="shadowBase"/> <!-- Offset the shadow shape --> <feOffset in="shadowBase" dx="10" dy="10" result="offOut" /> <!-- Blur the offset shadow --> <feGaussianBlur in="offOut" stdDeviation="5" result="blurOut" /> <!-- Merge the shadow and the original graphic --> <feMerge> <feMergeNode in="blurOut" /> <feMergeNode in="SourceGraphic" /> </feMerge> </filter> </defs> <rect width="90" height="90" x="20" y="20" stroke="green" stroke-width="3" fill="yellow" filter="url(#f3)" /> </svg></body></html>Code Explanation (Example 3):
<feFlood flood-color="black" flood-opacity="0.7" result="flood" />: Creates an infinite plane of a single color (black at 70% opacity).<feComposite in="flood" in2="SourceAlpha" operator="in" result="shadowBase"/>: Takes the flood color and the alpha channel of the source graphic. Theoperator="in"means the output is thefloodcolor, but only where it overlaps withSourceAlpha(effectively coloring the shape of the source graphic).- The rest of the filter chain (
feOffset,feGaussianBlur,feMerge) then processes thisshadowBase.
Example 4: Modifying Shadow Color with
Section titled “Example 4: Modifying Shadow Color with ”The <feColorMatrix> filter primitive allows for more complex color manipulations by applying a matrix transformation to the RGBA channels of the input. This can be used to desaturate, tint, or otherwise alter the shadow’s color.
Visually, the color matrix filter allows for fine-grained control over the shadow’s color. In this case, it creates a desaturated, darker version of the original graphic’s colors for the shadow.
Here is the SVG code:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>SVG feOffset Example 4</title></head><body> <svg width="180" height="180"> <defs> <filter id="f4" x="-40%" y="-40%" width="180%" height="180%"> <feOffset in="SourceGraphic" dx="10" dy="10" result="offOut" /> <feColorMatrix in="offOut" type="matrix" values="0.2 0 0 0 0 0 0.2 0 0 0 0 0 0.2 0 0 0 0 0 1 0" result="matrixOut" /> <feGaussianBlur in="matrixOut" stdDeviation="5" result="blurOut" /> <feMerge> <feMergeNode in="blurOut" /> <feMergeNode in="SourceGraphic" /> </feMerge> </filter> </defs> <rect width="90" height="90" x="20" y="20" stroke="green" stroke-width="3" fill="yellow" filter="url(#f4)" /> </svg></body></html>Code Explanation (Example 4):
<feColorMatrix ... values="..." />: This filter takes the offset graphic (offOut) as input. Thevaluesattribute defines a 5x4 matrix for RGBA transformation. The matrix provided here (0.2 0 0 0 0 / 0 0.2 0 0 0 / 0 0 0.2 0 0 / 0 0 0 1 0) effectively scales down the R, G, and B channels to 20% of their original values, making the shadow darker and desaturated, while leaving the alpha channel (A) unchanged.
Learning Tip: SVG filters are incredibly powerful but can be complex. Start with simple primitives like feOffset and feGaussianBlur, and gradually explore more advanced ones. Tools like the SVG Filter Builder can help visualize and construct filter effects.