Chapter 1 of ?
css 8 min read

CSS3 Mastery — Chapter 13: CSS Image Styling, Modals, Filters, Shapes & Masking

Chapter 13: CSS Image Styling, Modals, Filters, Shapes & Masking

Images are central to web storytelling and visual impact. Mastering responsive scaling, aspect-ratio preservation with object-fit, real-time CSS graphics filters (blur, drop-shadow, grayscale), complex geometry clipping (clip-path), CSS gradient masking, and pure CSS image modals unlocks studio-grade image handling.

13.1 Responsive Images & object-fit / object-position

Making images responsive requires scaling down to fit small viewports while preventing aspect ratio distortion. The object-fit and object-position properties dictate how an image resizes inside a fixed container box.

object-fit Value Behavior & Aspect Ratio Best Used For
fill (Default) Stretches image to fill container; distorts aspect ratio! Not recommended for photos.
contain Scales image to fit inside container; preserves aspect ratio (letterboxing). Logos, product thumbnails, diagrams.
cover (Recommended) Fills entire container, cropping overflow; preserves aspect ratio. Hero banners, user avatars, card thumbnails.
none Ignores container dimensions; maintains original size. Fixed 1:1 pixel assets.
<!DOCTYPE html>
<html>
<head>
  <style>
    *, *::before, *::after { box-sizing: border-box; }
    body { font-family: system-ui, sans-serif; background: #0f172a; color: #f8fafc; padding: 24px; margin: 0; }
    h3 { margin-top: 0; color: #38bdf8; }

    .grid { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 14px; }
    .card { background: #1e293b; border-radius: 10px; padding: 12px; flex: 1; min-width: 180px; }
    .label { font-size: 11px; color: #64748b; font-family: monospace; display: block; margin-bottom: 8px; }

    /* Fixed container size */
    .img-box { width: 100%; height: 120px; border-radius: 8px; overflow: hidden; background: #334155; }
    .img-box img { width: 100%; height: 100%; }

    /* object-fit variations */
    .fit-cover   { object-fit: cover; object-position: center; }
    .fit-contain { object-fit: contain; background: #0f172a; }
    .fit-fill    { object-fit: fill; }
  </style>
</head>
<body>
  <h3>object-fit &amp; object-position Comparison</h3>
  <p style="font-size:12px;color:#64748b;">Same 1:1 square SVG rendered inside a 16:9 fixed container box:</p>

  <div class="grid">
    <div class="card">
      <span class="label">object-fit: cover (cropped, clean)</span>
      <div class="img-box">
        <img class="fit-cover" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Crect width='200' height='200' fill='%236366f1'/%3E%3Ccircle cx='100' cy='100' r='60' fill='%2338bdf8'/%3E%3C/svg%3E" alt="Demo" />
      </div>
    </div>
    <div class="card">
      <span class="label">object-fit: contain (letterboxed)</span>
      <div class="img-box">
        <img class="fit-contain" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Crect width='200' height='200' fill='%236366f1'/%3E%3Ccircle cx='100' cy='100' r='60' fill='%2338bdf8'/%3E%3C/svg%3E" alt="Demo" />
      </div>
    </div>
    <div class="card">
      <span class="label">object-fit: fill (stretched/distorted)</span>
      <div class="img-box">
        <img class="fit-fill" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Crect width='200' height='200' fill='%236366f1'/%3E%3Ccircle cx='100' cy='100' r='60' fill='%2338bdf8'/%3E%3C/svg%3E" alt="Demo" />
      </div>
    </div>
  </div>
</body>
</html>

13.2 Image Filters & Visual Effects (filter)

The CSS filter property applies real-time graphical adjustments such as blurring, color shifting, brightness adjustments, and transparent PNG drop shadows directly GPU-accelerated by the browser.

Filter Function Syntax Example Visual Effect Description
blur(px) filter: blur(4px); Applies Gaussian blur (great for background frosted glass).
grayscale(%) filter: grayscale(100%); Converts image to black & white (great for team member photo hover states).
brightness(%) filter: brightness(150%); Increases or decreases image luminance.
drop-shadow() filter: drop-shadow(0 4px 10px #38bdf8); Transparent SVG/PNG Shadow! Unlike box-shadow, follows actual transparent graphic outline shapes!
<!DOCTYPE html>
<html>
<head>
  <style>
    *, *::before, *::after { box-sizing: border-box; }
    body { font-family: system-ui, sans-serif; background: #0f172a; color: #f8fafc; padding: 24px; margin: 0; }
    h3 { margin-top: 0; color: #818cf8; }

    .filter-grid { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 14px; }
    .filter-card { text-align: center; background: #1e293b; border-radius: 10px; padding: 16px; flex: 1; min-width: 140px; }
    .filter-label { font-size: 11px; color: #64748b; font-family: monospace; display: block; margin-top: 8px; }

    .fx-normal    { filter: none; }
    .fx-blur      { filter: blur(3px); }
    .fx-gray      { filter: grayscale(100%); transition: filter 0.3s; cursor: pointer; }
    .fx-gray:hover{ filter: grayscale(0%); }
    .fx-bright    { filter: brightness(140%) contrast(120%); }
    .fx-shadow    { filter: drop-shadow(0 0 12px #38bdf8); }
  </style>
</head>
<body>
  <h3>CSS filter Property Gallery</h3>

  <div class="filter-grid">
    <div class="filter-card">
      <svg class="fx-normal" width="60" height="60" viewBox="0 0 100 100"><circle cx="50" cy="50" r="40" fill="%236366f1" /><polygon points="50,20 65,70 35,70" fill="%23f59e0b"/></svg>
      <span class="filter-label">filter: none</span>
    </div>

    <div class="filter-card">
      <svg class="fx-blur" width="60" height="60" viewBox="0 0 100 100"><circle cx="50" cy="50" r="40" fill="%236366f1" /><polygon points="50,20 65,70 35,70" fill="%23f59e0b"/></svg>
      <span class="filter-label">filter: blur(3px)</span>
    </div>

    <div class="filter-card">
      <svg class="fx-gray" width="60" height="60" viewBox="0 0 100 100"><circle cx="50" cy="50" r="40" fill="%236366f1" /><polygon points="50,20 65,70 35,70" fill="%23f59e0b"/></svg>
      <span class="filter-label">grayscale(100%) (Hover me!)</span>
    </div>

    <div class="filter-card">
      <svg class="fx-shadow" width="60" height="60" viewBox="0 0 100 100"><circle cx="50" cy="50" r="40" fill="%236366f1" /><polygon points="50,20 65,70 35,70" fill="%23f59e0b"/></svg>
      <span class="filter-label">drop-shadow(cyan glow)</span>
    </div>
  </div>
</body>
</html>

13.3 CSS Shapes & Clipping Paths (clip-path)

The clip-path property clips an element into geometric vector shapes (circles, ellipses, polygons, or SVG paths) without modifying the original image file.

<!DOCTYPE html>
<html>
<head>
  <style>
    *, *::before, *::after { box-sizing: border-box; }
    body { font-family: system-ui, sans-serif; background: #0f172a; color: #f8fafc; padding: 24px; margin: 0; }
    h3 { margin-top: 0; color: #10b981; }

    .shape-grid { display: flex; flex-wrap: wrap; gap: 20px; margin-top: 14px; }
    .shape-box {
      width: 110px; height: 110px;
      background: linear-gradient(135deg, #6366f1, #38bdf8);
      display: flex; align-items: center; justify-content: center;
      font-weight: bold; font-size: 11px; text-align: center; color: #fff;
    }
    .label { font-size: 11px; color: #64748b; font-family: monospace; display: block; text-align: center; margin-top: 6px; }

    /* clip-path shapes */
    .clip-circle  { clip-path: circle(50% at 50% 50%); }
    .clip-triangle{ clip-path: polygon(50% 0%, 0% 100%, 100% 100%); }
    .clip-star    { clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%); }
    .clip-hexagon { clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%); }
  </style>
</head>
<body>
  <h3>clip-path Geometric Shapes</h3>

  <div class="shape-grid">
    <div>
      <div class="shape-box clip-circle">Circle</div>
      <span class="label">circle(50%)</span>
    </div>
    <div>
      <div class="shape-box clip-triangle">Triangle</div>
      <span class="label">polygon(triangle)</span>
    </div>
    <div>
      <div class="shape-box clip-star">Star</div>
      <span class="label">polygon(star)</span>
    </div>
    <div>
      <div class="shape-box clip-hexagon">Hexagon</div>
      <span class="label">polygon(hexagon)</span>
    </div>
  </div>
</body>
</html>

13.4 CSS Masking (mask-image & -webkit-mask-image)

CSS Masking uses an alpha channel gradient or PNG/SVG mask graphic to hide or reveal parts of an element based on transparency levels.

<!DOCTYPE html>
<html>
<head>
  <style>
    *, *::before, *::after { box-sizing: border-box; }
    body { font-family: system-ui, sans-serif; background: #0f172a; color: #f8fafc; padding: 24px; margin: 0; }
    h3 { margin-top: 0; color: #f59e0b; }

    /* Gradient Mask — fades element out towards bottom */
    .masked-box {
      width: 100%; max-width: 380px; height: 130px;
      background: linear-gradient(135deg, #4f46e5, #06b6d4);
      border-radius: 12px; padding: 20px;
      -webkit-mask-image: linear-gradient(to bottom, rgba(0,0,0,1) 30%, rgba(0,0,0,0) 100%);
      mask-image: linear-gradient(to bottom, rgba(0,0,0,1) 30%, rgba(0,0,0,0) 100%);
    }
  </style>
</head>
<body>
  <h3>mask-image Alpha Gradient Masking</h3>
  <p style="font-size:12px;color:#64748b;">The container below uses a linear-gradient mask to smoothly fade into transparency at the bottom:</p>

  <div class="masked-box">
    <h4 style="margin:0;color:#fff;">Fade Out Mask Effect</h4>
    <p style="font-size:13px;color:#a5b4fc;margin-top:6px;">Notice how the text and background color gracefully fade away towards the bottom boundary using mask-image!</p>
  </div>
</body>
</html>

13.5 Pure CSS Image Modal Lightbox Pattern

You can create a full-screen image lightbox popup using pure CSS :target selectors without writing any JavaScript code!

<!DOCTYPE html>
<html>
<head>
  <style>
    *, *::before, *::after { box-sizing: border-box; }
    body { font-family: system-ui, sans-serif; background: #0f172a; color: #f8fafc; padding: 24px; margin: 0; }
    h3 { margin-top: 0; color: #38bdf8; }

    /* Thumbnail trigger */
    .thumb {
      width: 120px; height: 90px;
      background: linear-gradient(135deg, #6366f1, #38bdf8);
      border-radius: 8px; display: inline-flex; align-items: center; justify-content: center;
      color: #fff; font-weight: bold; font-size: 12px; text-decoration: none;
      cursor: pointer; transition: transform 0.2s;
    }
    .thumb:hover { transform: scale(1.05); }

    /* Pure CSS Modal overlay via :target */
    .modal-overlay {
      position: fixed; inset: 0;
      background: rgba(15, 23, 42, 0.85);
      backdrop-filter: blur(8px);
      display: flex; align-items: center; justify-content: center;
      opacity: 0; pointer-events: none; transition: opacity 0.3s;
      z-index: 9999;
    }

    /* When URL hash matches modal ID (e.g. #img-modal), reveal overlay */
    .modal-overlay:target {
      opacity: 1; pointer-events: auto;
    }

    .modal-box {
      background: #1e293b; border: 2px solid #38bdf8; border-radius: 12px;
      padding: 24px; max-width: 380px; text-align: center; position: relative;
    }

    .close-btn {
      position: absolute; top: 10px; right: 14px;
      color: #ef4444; text-decoration: none; font-size: 20px; font-weight: bold;
    }
  </style>
</head>
<body>
  <h3>Pure CSS Modal Lightbox (:target Pattern)</h3>
  <p style="font-size:12px;color:#64748b;">Click the thumbnail to open modal popup without JavaScript:</p>

  <a href="#img-modal" class="thumb">Click Thumbnail</a>

  <!-- Target Modal Popup -->
  <div id="img-modal" class="modal-overlay">
    <div class="modal-box">
      <a href="#" class="close-btn" title="Close">&times;</a>
      <h4 style="margin-top:0;color:#38bdf8;">Modal Lightbox Popup</h4>
      <p style="font-size:13px;color:#cbd5e1;">Opened using pure CSS <code>:target</code> rule when URL hash changes to #img-modal! Click &times; to close.</p>
    </div>
  </div>
</body>
</html>

13.5 Component Project: Glassmorphic Modal Dialog with Backdrop Blur

This component combines CSS filters, backdrop-filter: blur(), and gradient masks into a production modal popup overlay:

<!DOCTYPE html>
<html>
<head>
  <style>
    *, *::before, *::after { box-sizing: border-box; }
    body {
      font-family: system-ui, sans-serif; background: #0f172a; color: #f8fafc; margin: 0; padding: 24px;
      min-height: 100vh; display: flex; align-items: center; justify-content: center;
      background-image: radial-gradient(circle at 20% 30%, rgba(99,102,241,0.4), transparent 50%),
                        radial-gradient(circle at 80% 70%, rgba(16,185,129,0.3), transparent 50%);
    }

    .modal-overlay {
      position: fixed; inset: 0; background: rgba(15, 23, 42, 0.6);
      backdrop-filter: blur(8px); display: flex; align-items: center; justify-content: center; padding: 20px;
    }

    .glass-modal {
      background: rgba(30, 41, 59, 0.7); backdrop-filter: blur(16px);
      border: 1px solid rgba(255, 255, 255, 0.15); border-radius: 16px;
      padding: 32px; max-width: 420px; text-align: center;
      box-shadow: 0 20px 50px rgba(0,0,0,0.5); filter: drop-shadow(0 10px 20px rgba(0,0,0,0.3));
    }

    .modal-title { margin: 0 0 12px; color: #38bdf8; font-size: 1.4rem; }
    .modal-desc { font-size: 13px; color: #94a3b8; margin: 0 0 24px; line-height: 1.6; }

    .btn-confirm {
      background: linear-gradient(135deg, #6366f1, #06b6d4); color: #fff; border: none;
      padding: 10px 24px; border-radius: 8px; font-weight: 700; font-size: 13px; cursor: pointer;
    }
  </style>
</head>
<body>
  <div class="modal-overlay">
    <div class="glass-modal">
      <h3 class="modal-title">Confirm Action</h3>
      <p class="modal-desc">Are you sure you want to apply these CSS backdrop filter transformations to your component library?</p>
      <button class="btn-confirm">Confirm & Apply</button>
    </div>
  </div>
</body>
</html>

13.6 Interactive Sandbox — Image Styling & FX

Test clip-path, filter: drop-shadow, and mask-image live in the code playground below:

Live Playground — Chapter 13 Sandbox
Done with this chapter?
Mark it complete to track your progress and unlock your certificate.
Next Up

Learner Reviews

Write a Review
Share your experience to help other learners.
Your Rating *