Advanced Topics: Clipping, Masking, and Filters

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 the clipPath.
      • 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 a clipPath forms the clipping region.
  • clip-path attribute: Applied to an SVG element, it references a <clipPath> by its id.

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 (userSpaceOnUse or objectBoundingBox).
    • maskContentUnits: Defines the coordinate system for elements inside the mask (userSpaceOnUse or objectBoundingBox).
  • Any SVG shapes/groups inside <mask>: These define the masking effect.
    • fill and opacity are 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.
  • mask attribute: Applied to an SVG element, it references a <mask> by its id.

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 usually x="-10%" y="-10%" width="120%" height="120%" to avoid clipping filter effects like shadows.
    • filterUnits: Coordinate system for x, y, width, height (userSpaceOnUse or objectBoundingBox).
  • Filter Primitives (<fe...> elements): Child elements of <filter>, each performing a specific graphic operation. They often take an in attribute (input) and an result attribute (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 of SourceGraphic.
      • BackgroundImage: Content behind the element.
      • offsetName: The result of a previous filter primitive (using its result ID).
    • result: A unique ID for the output of this filter primitive, which can then be used as in for 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 for saturate/hueRotate.
  • <feMerge> / <feMergeNode>: Combines multiple filter primitive results.
  • <feDropShadow> (SVG2): A shorthand for a common drop shadow effect, effectively combining feGaussianBlur, feOffset, and feMerge. (Modern alternative to manual shadow setup).
  • filter attribute: Applied to an SVG element, it references a <filter> by its id.

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

  1. 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-path to the image to make it appear as a circular profile picture.
  2. Ghostly Text Effect:

    • Create a <filter> with at least two filter primitives:
      • feGaussianBlur to blur the text.
      • feOffset to create a slight “ghosting” or displacement effect.
    • Apply this filter to a <text> element to create a spooky, ethereal text.
  3. 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 radialGradient within one of the black circles to create a soft, feathered edge for the “hole.”
  4. Desaturated Image Hover (Bonus - CSS & Filters):

    • Import an <image> into SVG.
    • Define an SVG filter that uses feColorMatrix to desaturate the image (turn it grayscale). Research type="saturate" and values="0".
    • Apply this filter via CSS to the image.
    • Then, use CSS :hover to remove the filter (or transition its values) so the image becomes colorful when hovered.
  5. Shimmering Background Pattern (Advanced Pattern + Filter):

    • Combine a <pattern> (e.g., stripes or a grid) with a feTurbulence and feDisplacementMap filter 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.