8. Advanced Topics: Clipping, Masking, and Filters
This chapter introduces some of the most visually impactful and powerful features of SVG: clipping, masking, and filters. These techniques allow you to create complex shapes, intricate transparency effects, and stunning pixel-like visual effects directly within your vector graphics. Like gradients and patterns, these elements are typically defined within a <defs> section.
8.1 Clipping Paths: <clipPath>
A clipping path defines a region where part of an SVG element is “clipped” or cut out. Only the parts of the element that fall inside the clipping path’s region are visible. Anything outside is transparent.
Key Elements and Attributes:
<clipPath>: The container for the clipping path definition.id: A unique identifier to reference the clipping path.clipPathUnits: Defines the coordinate system for the shapes inside theclipPath.userSpaceOnUse(default): Coordinates are absolute to the SVG viewport.objectBoundingBox: Coordinates are relative (0 to 1) to the bounding box of the element to which the clip path is applied.
- Any SVG shapes inside
<clipPath>: These define the clipping region. The fill, stroke, and opacity of these shapes are ignored; only their outline matters. The union of all shapes within aclipPathforms the clipping region. clip-pathattribute: Applied to an SVG element, it references a<clipPath>by itsid.
Example:
<svg width="300" height="200" viewBox="0 0 300 200">
<defs>
<!-- Define a clipping path: a circle and a rectangle -->
<clipPath id="myClip">
<circle cx="100" cy="100" r="70" />
<rect x="120" y="20" width="100" height="100" />
</clipPath>
</defs>
<!-- Rectangle with a gradient fill -->
<rect
x="0"
y="0"
width="300"
height="200"
fill="lightblue"
clip-path="url(#myClip)"
/>
<!-- Text that will be clipped -->
<text
x="50"
y="100"
font-family="Arial"
font-size="40"
fill="darkblue"
clip-path="url(#myClip)"
>
Clipped Text
</text>
</svg>
Explanation: The blue rectangle and “Clipped Text” are only visible where they overlap with the combined area of the circle and rectangle defined in myClip.
8.2 Masks: <mask>
Masks provide a more versatile way to control the transparency of SVG elements, using the luminosity or alpha channel of a graphical object. Unlike clipPath (which is binary: either clipped or not), mask allows for gradients of transparency.
Key Elements and Attributes:
<mask>: The container for the mask definition.id: Unique identifier.maskUnits: Defines the coordinate system for the mask itself (userSpaceOnUseorobjectBoundingBox).maskContentUnits: Defines the coordinate system for elements inside the mask (userSpaceOnUseorobjectBoundingBox).
- Any SVG shapes/groups inside
<mask>: These define the masking effect.fillandopacityare crucial:- Black (
#000): Makes the masked area fully transparent. - White (
#FFF): Makes the masked area fully opaque. - Grayscales (e.g.,
#888): Create semi-transparent areas (darker gray = more transparent, lighter gray = more opaque). - Gradient fills: Create smooth transparency transitions.
opacity: Directly controls the transparency of the mask content itself.
- Black (
maskattribute: Applied to an SVG element, it references a<mask>by itsid.
Example: Text Reveal Mask
<svg width="300" height="200" viewBox="0 0 300 200">
<defs>
<linearGradient id="textGradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#2c3e50" />
<stop offset="100%" stop-color="#3498db" />
</linearGradient>
<!-- Mask using a linear gradient from black to white -->
<mask id="gradientMask">
<rect x="0" y="0" width="300" height="200" fill="url(#textGradient)" />
</mask>
</defs>
<!-- Rect with gradient applied, which will be masked -->
<rect x="0" y="0" width="300" height="200" fill="url(#textGradient)" mask="url(#gradientMask)" />
<!-- Text that will be masked -->
<text
x="150"
y="120"
font-family="Impact, sans-serif"
font-size="60"
text-anchor="middle"
fill="white"
mask="url(#gradientMask)"
>
MASKED
</text>
</svg>
Explanation: The text “MASKED” and the background rectangle are masked by a gradient. Where the gradient is black, the elements are transparent; where it’s white, they are opaque, creating a fade-in effect horizontally.
8.3 Filters: <filter> and Filter Primitives
SVG filters (<filter>) allow you to apply complex image processing effects to SVG (and even HTML) elements, similar to Photoshop filters. Filters are powerful, but can be performance-intensive, especially on large or animated elements.
Key Elements and Attributes:
<filter>: The container for a filter definition.id: Unique identifier.x,y,width,height: Define the region where the filter effects will be rendered. By default, it’s usuallyx="-10%" y="-10%" width="120%" height="120%"to avoid clipping filter effects like shadows.filterUnits: Coordinate system forx, y, width, height(userSpaceOnUseorobjectBoundingBox).
- Filter Primitives (
<fe...>elements): Child elements of<filter>, each performing a specific graphic operation. They often take aninattribute (input) and anresultattribute (output) to chain effects.in: Specifies the input graphic for the filter primitive. Common values:SourceGraphic: The element to which the filter is applied.SourceAlpha: The alpha channel ofSourceGraphic.BackgroundImage: Content behind the element.offsetName: The result of a previous filter primitive (using itsresultID).
result: A unique ID for the output of this filter primitive, which can then be used asinfor subsequent primitives.
Common Filter Primitives:
<feGaussianBlur>: Applies a Gaussian blur.stdDeviation: The standard deviation for the blur (higher value = more blur).
<feOffset>: Displaces the input image. Useful for creating shadows.dx,dy: Horizontal and vertical offset.
<feColorMatrix>: Transforms colors using a matrix. Useful for grayscale, sepia, brightness, contrast.type:saturate,hueRotate,luminanceToAlpha,matrix.values: The matrix values or single value forsaturate/hueRotate.
<feMerge>/<feMergeNode>: Combines multiple filter primitive results.<feDropShadow>(SVG2): A shorthand for a common drop shadow effect, effectively combiningfeGaussianBlur,feOffset, andfeMerge. (Modern alternative to manual shadow setup).filterattribute: Applied to an SVG element, it references a<filter>by itsid.
Example: Drop Shadow (using feOffset and feGaussianBlur)
<svg width="300" height="200" viewBox="0 0 300 200">
<defs>
<filter id="dropShadow" x="-20%" y="-20%" width="140%" height="140%">
<!-- Create a blurred copy (shadow) of the original graphic -->
<feGaussianBlur in="SourceAlpha" stdDeviation="5" result="blur" />
<!-- Offset the blurred copy -->
<feOffset in="blur" dx="5" dy="5" result="offsetBlur" />
<!-- Colorize the shadow to black -->
<feColorMatrix
in="offsetBlur"
type="matrix"
values="0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0.5 0"
result="coloredShadow"
/>
<!-- Merge the colored shadow with the original graphic -->
<feMerge>
<feMergeNode in="coloredShadow" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
<!-- SVG2 simplified drop shadow (if supported) -->
<!--
<filter id="simpleDropShadow">
<feDropShadow dx="5" dy="5" stdDeviation="5" flood-color="black" flood-opacity="0.5"/>
</filter>
-->
</defs>
<rect x="50" y="50" width="100" height="100" fill="coral" filter="url(#dropShadow)" />
<circle cx="220" cy="100" r="50" fill="steelblue" filter="url(#dropShadow)" />
</svg>
Note on feDropShadow: While the manual setup is good for understanding, modern browsers increasingly support <feDropShadow> directly, which is simpler to use:
<filter id="simpleDropShadow">
<feDropShadow dx="5" dy="5" stdDeviation="5" flood-color="black" flood-opacity="0.5" />
</filter>
And then apply it: filter="url(#simpleDropShadow)".
Exercises/Mini-Challenges
Circular Profile Picture Frame:
- Import a small raster image (PNG or JPG) into your SVG using
<image>. - Create a
<clipPath>in the shape of a circle. - Apply the
clip-pathto the image to make it appear as a circular profile picture.
- Import a small raster image (PNG or JPG) into your SVG using
Ghostly Text Effect:
- Create a
<filter>with at least two filter primitives:feGaussianBlurto blur the text.feOffsetto create a slight “ghosting” or displacement effect.
- Apply this filter to a
<text>element to create a spooky, ethereal text.
- Create a
Hole Punch Mask:
- Draw a large rectangle.
- Define a
<mask>containing several smaller circles filled with black. - Apply this mask to the rectangle to make it look like a “hole-punched” piece of paper.
- Try using a
radialGradientwithin one of the black circles to create a soft, feathered edge for the “hole.”
Desaturated Image Hover (Bonus - CSS & Filters):
- Import an
<image>into SVG. - Define an SVG filter that uses
feColorMatrixto desaturate the image (turn it grayscale). Researchtype="saturate"andvalues="0". - Apply this filter via CSS to the image.
- Then, use CSS
:hoverto remove the filter (or transition its values) so the image becomes colorful when hovered.
- Import an
Shimmering Background Pattern (Advanced Pattern + Filter):
- Combine a
<pattern>(e.g., stripes or a grid) with afeTurbulenceandfeDisplacementMapfilter to create a distorted, organic, or “shimmering” effect within the pattern. This can simulate water reflections or abstract textures. - Apply this filtered pattern as the fill of a large rectangle.
- Combine a