CSS Masks - Control Element Transparency with Images & Gradients

What You'll Learn

  • Control element transparency using mask-image
  • Create gradient masks for fade effects and vignettes
  • Apply SVG masks for complex shapes beyond clip-path
  • Build repeating pattern masks (stripes, dots, checkerboards)
  • Understand mask compositing and layering
  • Combine masks with animations for reveal effects
  • Distinguish between masks, clip-path, and opacity

Introduction to CSS Masks

CSS masks control an element's transparency using images or gradients as a "mask layer." Unlike clip-path which creates hard edges, masks support gradual transparency through grayscale values: black areas are fully visible, white is fully transparent, and grays create partial transparency.

Masks are perfect for fade effects, soft-edge clipping, pattern overlays, and complex transparency effects that clip-path and opacity cannot achieve.

Gradient Masks - Fade Effects

Linear and radial gradients create smooth fade effects, vignettes, and soft edges.

/* Linear gradient masks */ /* Horizontal fade (left visible, right transparent) */ .fade-horizontal { -webkit-mask-image: linear-gradient(to right, black, transparent); mask-image: linear-gradient(to right, black, transparent); } /* Vertical fade (top visible, bottom transparent) */ .fade-vertical { -webkit-mask-image: linear-gradient(to bottom, black, transparent); mask-image: linear-gradient(to bottom, black, transparent); } /* Fade both edges (center visible, edges transparent) */ .fade-edges { -webkit-mask-image: linear-gradient(to right, transparent, black 20%, black 80%, transparent); mask-image: linear-gradient(to right, transparent, black 20%, black 80%, transparent); } /* Radial gradient masks */ /* Circular vignette */ .vignette { -webkit-mask-image: radial-gradient(circle at center, black 50%, transparent 80%); mask-image: radial-gradient(circle at center, black 50%, transparent 80%); } /* Spotlight effect */ .spotlight { -webkit-mask-image: radial-gradient(circle at 30% 30%, black 20%, transparent 60%); mask-image: radial-gradient(circle at 30% 30%, black 20%, transparent 60%); } /* Soft circular mask */ .soft-circle { -webkit-mask-image: radial-gradient(circle, black 40%, transparent 50%); mask-image: radial-gradient(circle, black 40%, transparent 50%); } /* Practical examples */ /* Fade text at bottom of container */ .text-fade-bottom { -webkit-mask-image: linear-gradient(to bottom, black 70%, transparent 100%); mask-image: linear-gradient(to bottom, black 70%, transparent 100%); } /* Image gallery hover fade */ .gallery-item img { -webkit-mask-image: linear-gradient(black, black); mask-image: linear-gradient(black, black); transition: mask-image 0.3s; } .gallery-item:hover img { -webkit-mask-image: radial-gradient(circle, black 60%, transparent 80%); mask-image: radial-gradient(circle, black 60%, transparent 80%); }

Pattern Masks - Repeating Effects

Repeating gradients create pattern masks: stripes, dots, waves, and geometric patterns.

/* Diagonal stripes */ .stripes { -webkit-mask-image: repeating-linear-gradient( 45deg, black 0px, black 20px, transparent 20px, transparent 40px ); mask-image: repeating-linear-gradient( 45deg, black 0px, black 20px, transparent 20px, transparent 40px ); } /* Dots pattern */ .dots { -webkit-mask-image: radial-gradient(circle, black 30%, transparent 30%); mask-image: radial-gradient(circle, black 30%, transparent 30%); -webkit-mask-size: 30px 30px; mask-size: 30px 30px; } /* Horizontal lines */ .lines-horizontal { -webkit-mask-image: repeating-linear-gradient( to bottom, black 0px, black 15px, transparent 15px, transparent 30px ); mask-image: repeating-linear-gradient( to bottom, black 0px, black 15px, transparent 15px, transparent 30px ); } /* Wavy pattern */ .waves { -webkit-mask-image: radial-gradient(ellipse at top, transparent 50%, black 50%); mask-image: radial-gradient(ellipse at top, transparent 50%, black 50%); -webkit-mask-size: 40px 20px; mask-size: 40px 20px; } /* Checkerboard */ .checkerboard { -webkit-mask-image: repeating-linear-gradient(0deg, black 0, black 20px, transparent 20px, transparent 40px), repeating-linear-gradient(90deg, black 0, black 20px, transparent 20px, transparent 40px); mask-image: repeating-linear-gradient(0deg, black 0, black 20px, transparent 20px, transparent 40px), repeating-linear-gradient(90deg, black 0, black 20px, transparent 20px, transparent 40px); -webkit-mask-composite: source-in; mask-composite: intersect; } /* Grid pattern */ .grid-pattern { -webkit-mask-image: repeating-linear-gradient(0deg, transparent, transparent 48px, black 48px, black 50px), repeating-linear-gradient(90deg, transparent, transparent 48px, black 48px, black 50px); mask-image: repeating-linear-gradient(0deg, transparent, transparent 48px, black 48px, black 50px), repeating-linear-gradient(90deg, transparent, transparent 48px, black 48px, black 50px); }

SVG Masks - Complex Shapes

Use SVG images as masks for shapes more complex than clip-path can create, including icons, logos, and illustrations.

/* SVG shape masks using data URLs */ /* Star mask */ .star-mask { -webkit-mask-image: url('data:image/svg+xml,'); mask-image: url('data:image/svg+xml,'); -webkit-mask-size: contain; mask-size: contain; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-position: center; mask-position: center; } /* Heart mask */ .heart-mask { -webkit-mask-image: url('data:image/svg+xml,'); mask-image: url('data:image/svg+xml,'); -webkit-mask-size: contain; mask-size: contain; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-position: center; mask-position: center; } /* External SVG file */ .logo-mask { -webkit-mask-image: url('/path/to/logo-mask.svg'); mask-image: url('/path/to/logo-mask.svg'); -webkit-mask-size: contain; mask-size: contain; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; } /* Repeating SVG pattern */ .icon-pattern { -webkit-mask-image: url('/path/to/icon.svg'); mask-image: url('/path/to/icon.svg'); -webkit-mask-size: 50px 50px; mask-size: 50px 50px; -webkit-mask-repeat: repeat; mask-repeat: repeat; } /* Icon with gradient fade */ .icon-fade { -webkit-mask-image: url('/path/to/icon.svg'), linear-gradient(to bottom, black, transparent); mask-image: url('/path/to/icon.svg'), linear-gradient(to bottom, black, transparent); -webkit-mask-composite: source-in; mask-composite: intersect; }

Mask Properties - Size, Position, Repeat

Control how mask images apply to elements with sizing, positioning, and repeat properties, similar to background-* properties.

/* mask-size - Control mask dimensions */ mask-size: contain; /* Fit within element */ mask-size: cover; /* Cover entire element */ mask-size: 100px 100px; /* Fixed size */ mask-size: 50% 50%; /* Percentage of element */ /* mask-position - Position the mask */ mask-position: center; /* Center mask */ mask-position: top left; /* Keywords */ mask-position: 50% 50%; /* Percentages */ mask-position: 20px 30px; /* Pixel values */ /* mask-repeat - Control repetition */ mask-repeat: no-repeat; /* Single instance */ mask-repeat: repeat; /* Tile in both directions */ mask-repeat: repeat-x; /* Horizontal only */ mask-repeat: repeat-y; /* Vertical only */ mask-repeat: space; /* Space evenly */ mask-repeat: round; /* Stretch to fit */ /* mask-origin - Mask positioning box */ mask-origin: border-box; /* Include border */ mask-origin: padding-box; /* Exclude border (default) */ mask-origin: content-box; /* Only content area */ /* mask-clip - Mask painting area */ mask-clip: border-box; /* Paint including border */ mask-clip: padding-box; /* Exclude border */ mask-clip: content-box; /* Only content */ /* Complete example */ .masked-element { -webkit-mask-image: url('/mask.svg'); mask-image: url('/mask.svg'); -webkit-mask-size: 200px 200px; mask-size: 200px 200px; -webkit-mask-position: center; mask-position: center; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; } /* Shorthand (experimental) */ mask: url('/mask.svg') center/200px no-repeat;

Animated Masks - Reveal Effects

Animate masks for wipe transitions, reveal effects, and dynamic transparency changes.

/* Wipe reveal animation */ @keyframes wipe-reveal { from { -webkit-mask-image: linear-gradient(to right, black 0%, black 0%, transparent 0%); mask-image: linear-gradient(to right, black 0%, black 0%, transparent 0%); } to { -webkit-mask-image: linear-gradient(to right, black 100%, black 100%, transparent 100%); mask-image: linear-gradient(to right, black 100%, black 100%, transparent 100%); } } .reveal { animation: wipe-reveal 2s ease forwards; } /* Circular expand */ @keyframes expand-circle { from { -webkit-mask-image: radial-gradient(circle, black 0%, transparent 0%); mask-image: radial-gradient(circle, black 0%, transparent 0%); } to { -webkit-mask-image: radial-gradient(circle, black 100%, transparent 100%); mask-image: radial-gradient(circle, black 100%, transparent 100%); } } /* Breathing effect */ @keyframes breathe { 0%, 100% { -webkit-mask-image: radial-gradient(circle, black 50%, transparent 60%); mask-image: radial-gradient(circle, black 50%, transparent 60%); } 50% { -webkit-mask-image: radial-gradient(circle, black 60%, transparent 70%); mask-image: radial-gradient(circle, black 60%, transparent 70%); } } /* Hover reveal */ .hover-reveal { -webkit-mask-image: linear-gradient(to bottom, black 0%, transparent 0%); mask-image: linear-gradient(to bottom, black 0%, transparent 0%); transition: mask-image 0.6s ease; } .hover-reveal:hover { -webkit-mask-image: linear-gradient(to bottom, black 100%, transparent 100%); mask-image: linear-gradient(to bottom, black 100%, transparent 100%); } /* Animated pattern */ @keyframes scroll-pattern { from { -webkit-mask-position: 0 0; mask-position: 0 0; } to { -webkit-mask-position: 50px 50px; mask-position: 50px 50px; } } .scrolling-stripes { -webkit-mask-image: repeating-linear-gradient(45deg, black 0, black 20px, transparent 20px, transparent 40px); mask-image: repeating-linear-gradient(45deg, black 0, black 20px, transparent 20px, transparent 40px); animation: scroll-pattern 2s linear infinite; }

Masks vs Clip-Path vs Opacity

Choose the right technique for your transparency needs: masks for gradual fades, clip-path for hard edges, opacity for uniform transparency.

/* clip-path - Hard-edged clipping */ .clipped { clip-path: circle(50%); } /* ✓ Hard, geometric shapes ✓ Perfect for polygons, circles, basic shapes ✓ No gradual transparency ✓ Best performance */ /* mask-image - Gradual transparency */ .masked { -webkit-mask-image: radial-gradient(circle, black 40%, transparent 60%); mask-image: radial-gradient(circle, black 40%, transparent 60%); } /* ✓ Gradual fades and soft edges ✓ Pattern overlays ✓ Complex transparency with SVG ✓ More resource-intensive */ /* opacity - Uniform transparency */ .faded { opacity: 0.5; } /* ✓ Entire element becomes transparent ✓ Affects all children ✓ Simple, performant ✗ No partial transparency control */ /* Combining techniques */ .combined { clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%); -webkit-mask-image: linear-gradient(to bottom, black, transparent); mask-image: linear-gradient(to bottom, black, transparent); opacity: 0.9; } /* Clip to shape, apply gradient fade, reduce overall opacity */ /* When to use each */ /* Use clip-path for: */ .avatar { clip-path: circle(50%); } /* Profile pictures */ .diamond { clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); } /* Geometric shapes */ /* Use mask-image for: */ .text-fade { mask-image: linear-gradient(black 80%, transparent); } /* Fade effects */ .vignette { mask-image: radial-gradient(circle, black 50%, transparent 80%); } /* Soft edges */ /* Use opacity for: */ .disabled { opacity: 0.5; } /* Disabled states */ .tooltip { opacity: 0; transition: opacity 0.3s; } /* Show/hide transitions */

Key Takeaways

  • Black = visible, White = transparent: Mask images use luminance for transparency
  • Vendor prefix required: Always include -webkit-mask-image alongside mask-image
  • Gradient masks: Use linear-gradient or radial-gradient for fade effects and vignettes
  • Pattern masks: repeating-linear-gradient creates stripes, dots, and geometric patterns
  • SVG masks: Use url() with SVG files for complex shapes and icon-based masks
  • mask-size: Control pattern density; works like background-size
  • mask-position: Position masks; works like background-position
  • mask-repeat: Control tiling; works like background-repeat
  • Layered masks: Combine multiple mask-images with mask-composite
  • Animatable: Animate mask-position and mask-size for smooth effects
  • vs clip-path: Masks support gradual transparency; clip-path only hard edges
  • vs opacity: Masks control specific areas; opacity affects entire element uniformly
  • Masks are more resource-intensive than clip-path or opacity; use strategically