CSS Filters Tutorial
Transform elements with powerful filter effects and create stunning visual experiences
What Are CSS Filters?
CSS filters are a powerful feature that allows you to apply graphical effects like blurring, color shifting, and contrast adjustment to elements. Filters are commonly used on images, but can be applied to any HTML element.
Key Benefits:
- Create visual effects without image editing software
- Perform real-time image processing in the browser
- Animate between different filter states
- Improve performance compared to JavaScript alternatives
- Apply consistent effects across multiple elements
CSS Filters Implementation
Complete Example Code
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>CSS Filters Tutorial</title> <style> * { box-sizing: border-box; margin: 0; padding: 0; } :root { --primary-color: #6a11cb; --secondary-color: #2575fc; --accent-color: #ff416c; --dark-color: #2c3e50; --light-color: #f8f9fa; --text-color: #333; --text-light: #fff; --spacing-sm: 0.5rem; --spacing-md: 1rem; --spacing-lg: 1.5rem; --spacing-xl: 2rem; --border-radius: 0.5rem; --font-main: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; --font-heading: 'Montserrat', sans-serif; } body { font-family: var(--font-main); line-height: 1.6; color: var(--text-color); background: linear-gradient(135deg, var(--light-color) 0%, #eef2f5 100%); padding: var(--spacing-md); min-height: 100vh; } .container { max-width: 1200px; margin: 0 auto; } header { text-align: center; margin-bottom: var(--spacing-xl); padding: var(--spacing-lg); background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); color: var(--text-light); border-radius: var(--border-radius); box-shadow: 0 4px 15px rgba(0,0,0,0.1); position: relative; overflow: hidden; } header::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="none"><path d="M0,0 L100,0 L100,100 Z" fill="rgba(255,255,255,0.1)"/></svg>'); background-size: cover; filter: blur(2px); } h1 { font-family: var(--font-heading); font-size: clamp(1.8rem, 5vw, 3rem); margin-bottom: var(--spacing-sm); position: relative; text-shadow: 2px 2px 4px rgba(0,0,0,0.3); } h2 { font-family: var(--font-heading); font-size: clamp(1.4rem, 4vw, 2rem); margin: var(--spacing-lg) 0 var(--spacing-md); color: var(--dark-color); padding-bottom: var(--spacing-sm); border-bottom: 2px solid var(--primary-color); position: relative; } .example { background: white; border-radius: var(--border-radius); padding: var(--spacing-lg); margin-bottom: var(--spacing-lg); box-shadow: 0 5px 15px rgba(0,0,0,0.08); transition: transform 0.3s ease, box-shadow 0.3s ease; } .example:hover { transform: translateY(-5px); box-shadow: 0 10px 25px rgba(0,0,0,0.15); } .demo { border: 2px solid #e9ecef; border-radius: var(--border-radius); padding: var(--spacing-lg); margin: var(--spacing-md) 0; background: #f8f9fa; display: flex; flex-wrap: wrap; gap: var(--spacing-md); justify-content: center; } .filter-item { width: 150px; height: 150px; border-radius: var(--border-radius); overflow: hidden; position: relative; box-shadow: 0 4px 8px rgba(0,0,0,0.1); transition: transform 0.3s ease; } .filter-item:hover { transform: scale(1.05); } .filter-item img { width: 100%; height: 100%; object-fit: cover; } .filter-label { position: absolute; bottom: 0; left: 0; right: 0; background: rgba(0,0,0,0.7); color: white; padding: 0.3rem; text-align: center; font-size: 0.8rem; } .code-block { background: #2d2d2d; color: #f8f8f2; padding: var(--spacing-md); border-radius: var(--border-radius); overflow-x: auto; margin: var(--spacing-md) 0; font-family: 'Consolas', 'Monaco', monospace; font-size: 0.875rem; position: relative; } .code-block::before { content: 'CSS'; position: absolute; top: 0; right: 0; background: var(--primary-color); color: white; padding: 0.2rem 0.5rem; font-size: 0.7rem; border-bottom-left-radius: var(--border-radius); } .btn { display: inline-block; padding: var(--spacing-sm) var(--spacing-md); background: var(--primary-color); color: var(--text-light); border: none; border-radius: var(--border-radius); cursor: pointer; font-size: 0.875rem; margin-right: var(--spacing-sm); transition: all 0.3s ease; box-shadow: 0 2px 5px rgba(0,0,0,0.1); } .btn:hover { background: #5a0fb5; transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0,0,0,0.15); } .btn-copy { background: var(--secondary-color); } .btn-copy:hover { background: #1c67e3; } .controls { display: flex; gap: var(--spacing-sm); margin: var(--spacing-md) 0; flex-wrap: wrap; justify-content: center; } .control-btn { padding: 0.5rem 1rem; background: var(--primary-color); color: white; border: none; border-radius: var(--border-radius); cursor: pointer; transition: all 0.3s ease; } .control-btn:hover { background: var(--secondary-color); transform: translateY(-2px); } /* Example 1: Basic Filters */ .blur-filter { filter: blur(3px); } .brightness-filter { filter: brightness(150%); } .contrast-filter { filter: contrast(200%); } .grayscale-filter { filter: grayscale(100%); } /* Example 2: Hue Rotation */ .hue-rotate-container { display: flex; flex-wrap: wrap; gap: var(--spacing-md); justify-content: center; } .hue-item { width: 120px; height: 120px; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); } .hue-rotate-60 { filter: hue-rotate(60deg); } .hue-rotate-120 { filter: hue-rotate(120deg); } .hue-rotate-180 { filter: hue-rotate(180deg); } .hue-rotate-240 { filter: hue-rotate(240deg); } .hue-rotate-300 { filter: hue-rotate(300deg); } /* Example 3: Multiple Filters */ .vintage-effect { filter: sepia(50%) brightness(90%) contrast(120%) hue-rotate(-10deg); } .cool-effect { filter: brightness(110%) saturate(150%) hue-rotate(180deg) contrast(130%); } .warm-effect { filter: sepia(30%) brightness(110%) saturate(140%) hue-rotate(10deg); } /* Example 4: Interactive Filter Controls */ .interactive-demo { display: flex; flex-direction: column; align-items: center; gap: var(--spacing-md); } .filter-controls { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--spacing-md); width: 100%; } .control-group { display: flex; flex-direction: column; gap: 0.5rem; } .control-group label { font-weight: bold; color: var(--dark-color); } .control-group input { width: 100%; } .filter-result { width: 250px; height: 250px; border-radius: var(--border-radius); overflow: hidden; box-shadow: 0 5px 15px rgba(0,0,0,0.1); } .filter-result img { width: 100%; height: 100%; object-fit: cover; } /* Example 5: Filter Transitions */ .transition-demo { display: flex; justify-content: center; gap: var(--spacing-md); } .transition-item { width: 120px; height: 120px; border-radius: var(--border-radius); overflow: hidden; box-shadow: 0 4px 8px rgba(0,0,0,0.1); transition: filter 0.5s ease; } .transition-item:hover { filter: grayscale(80%) brightness(120%); } /* Example 6: Text with Filters */ .text-filters { display: flex; flex-wrap: wrap; gap: var(--spacing-md); justify-content: center; } .text-item { padding: var(--spacing-md); border-radius: var(--border-radius); font-weight: bold; font-size: 1.2rem; display: flex; align-items: center; justify-content: center; min-width: 150px; } .text-glow { background: var(--dark-color); color: white; filter: drop-shadow(0 0 10px var(--primary-color)); } .text-blur { background: var(--secondary-color); color: white; filter: blur(1px); } .text-multiple { background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); color: white; filter: drop-shadow(0 0 5px rgba(0,0,0,0.5)) brightness(110%); } /* Example 7: Background Filters */ .backdrop-demo { position: relative; height: 200px; border-radius: var(--border-radius); overflow: hidden; display: flex; align-items: center; justify-content: center; } .backdrop-image { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; filter: brightness(70%); z-index: 1; } .backdrop-content { position: relative; z-index: 2; background: rgba(255, 255, 255, 0.2); backdrop-filter: blur(10px) brightness(120%); padding: var(--spacing-md); border-radius: var(--border-radius); color: white; text-align: center; width: 80%; box-shadow: 0 4px 10px rgba(0,0,0,0.2); } /* Example 8: SVG Filters */ .svg-filters { display: flex; flex-wrap: wrap; gap: var(--spacing-md); justify-content: center; } .svg-item { width: 120px; height: 120px; } /* Example 9: Image Gallery */ .gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--spacing-md); } .gallery-item { border-radius: var(--border-radius); overflow: hidden; height: 150px; transition: filter 0.3s ease; cursor: pointer; } .gallery-item:nth-child(1):hover { filter: sepia(100%); } .gallery-item:nth-child(2):hover { filter: invert(100%); } .gallery-item:nth-child(3):hover { filter: hue-rotate(90deg); } .gallery-item:nth-child(4):hover { filter: saturate(200%); } .gallery-item:nth-child(5):hover { filter: contrast(200%); } .gallery-item:nth-child(6):hover { filter: brightness(150%) contrast(120%); } .gallery-item img { width: 100%; height: 100%; object-fit: cover; } /* Example 10: Creative Effects */ .creative-effects { display: flex; flex-wrap: wrap; gap: var(--spacing-md); justify-content: center; } .creative-item { width: 150px; height: 150px; border-radius: var(--border-radius); overflow: hidden; position: relative; } .creative-item img { width: 100%; height: 100%; object-fit: cover; } .effect-dreamy { filter: brightness(110%) saturate(150%) hue-rotate(315deg) contrast(130%) blur(0.5px); } .effect-noir { filter: grayscale(100%) contrast(150%) brightness(80%); } .effect-sunset { filter: hue-rotate(330deg) saturate(150%) brightness(110%); } .effect-frosted { filter: brightness(120%) blur(1px) contrast(90%); } </style> </head> <body> <div class="container"> <header> <h1>CSS Filters Tutorial</h1> <p>Transform elements with powerful filter effects</p> </header> <section class="example"> <h2>1. Basic Filter Effects</h2> <p>CSS provides several basic filter functions that can be applied to elements.</p> <div class="demo"> <div class="filter-item"> <img src="https://picsum.photos/200/300" alt="Mountain landscape"> <div class="filter-label">Original</div> </div> <div class="filter-item"> <img class="blur-filter" src="https://picsum.photos/200/300" alt="Blurred landscape"> <div class="filter-label">Blur(3px)</div> </div> <div class="filter-item"> <img class="brightness-filter" src="https://picsum.photos/200/300" alt="Bright landscape"> <div class="filter-label">Brightness(150%)</div> </div> <div class="filter-item"> <img class="contrast-filter" src="https://picsum.photos/200/300" alt="High contrast landscape"> <div class="filter-label">Contrast(200%)</div> </div> <div class="filter-item"> <img class="grayscale-filter" src="https://picsum.photos/200/300" alt="Grayscale landscape"> <div class="filter-label">Grayscale(100%)</div> </div> </div> <div class="code-block"> .blur-filter { filter: blur(3px); } .brightness-filter { filter: brightness(150%); } .contrast-filter { filter: contrast(200%); } .grayscale-filter { filter: grayscale(100%); } </div> </section> <section class="example"> <h2>2. Hue Rotation</h2> <p>The hue-rotate() function shifts the hue of an element's colors.</p> <div class="demo"> <div class="hue-rotate-container"> <div class="hue-item">0°</div> <div class="hue-item hue-rotate-60">60°</div> <div class="hue-item hue-rotate-120">120°</div> <div class="hue-item hue-rotate-180">180°</div> <div class="hue-item hue-rotate-240">240°</div> <div class="hue-item hue-rotate-300">300°</div> </div> </div> <div class="code-block"> .hue-rotate-60 { filter: hue-rotate(60deg); } .hue-rotate-120 { filter: hue-rotate(120deg); } .hue-rotate-180 { filter: hue-rotate(180deg); } .hue-rotate-240 { filter: hue-rotate(240deg); } .hue-rotate-300 { filter: hue-rotate(300deg); } </div> </section> <section class="example"> <h2>3. Multiple Filters</h2> <p>Combine multiple filter functions to create complex visual effects.</p> <div class="demo"> <div class="filter-item"> <img src="https://picsum.photos/200/300" alt="Original"> <div class="filter-label">Original</div> </div> <div class="filter-item"> <img class="vintage-effect" src="https://picsum.photos/200/300" alt="Vintage effect"> <div class="filter-label">Vintage</div> </div> <div class="filter-item"> <img class="cool-effect" src="https://picsum.photos/200/300" alt="Cool effect"> <div class="filter-label">Cool</div> </div> <div class="filter-item"> <img class="warm-effect" src="https://picsum.photos/200/300" alt="Warm effect"> <div class="filter-label">Warm</div> </div> </div> <div class="code-block"> .vintage-effect { filter: sepia(50%) brightness(90%) contrast(120%) hue-rotate(-10deg); } .cool-effect { filter: brightness(110%) saturate(150%) hue-rotate(180deg) contrast(130%); } .warm-effect { filter: sepia(30%) brightness(110%) saturate(140%) hue-rotate(10deg); } </div> </section> <section class="example"> <h2>4. Interactive Filter Controls</h2> <p>Use JavaScript to dynamically control CSS filters.</p> <div class="demo interactive-demo"> <div class="filter-controls"> <div class="control-group"> <label for="blur">Blur: <span id="blur-value">0px</span></label> <input type="range" id="blur" min="0" max="10" step="0.5" value="0"> </div> <div class="control-group"> <label for="brightness">Brightness: <span id="brightness-value">100%</span></label> <input type="range" id="brightness" min="0" max="200" step="5" value="100"> </div> <div class="control-group"> <label for="contrast">Contrast: <span id="contrast-value">100%</span></label> <input type="range" id="contrast" min="0" max="200" step="5" value="100"> </div> <div class="control-group"> <label for="hue">Hue: <span id="hue-value">0deg</span></label> <input type="range" id="hue" min="0" max="360" step="5" value="0"> </div> </div> <div class="filter-result" id="interactive-result"> <img src="https://picsum.photos/200/300" alt="Interactive filter demo"> </div> <button onclick="resetFilters()" class="control-btn">Reset Filters</button> </div> <div class="code-block"> // JavaScript to control filters const blurInput = document.getElementById('blur'); const brightnessInput = document.getElementById('brightness'); const contrastInput = document.getElementById('contrast'); const hueInput = document.getElementById('hue'); const result = document.getElementById('interactive-result'); function updateFilter() { result.style.filter = `blur(${blurInput.value}px) brightness(${brightnessInput.value}%) contrast(${contrastInput.value}%) hue-rotate(${hueInput.value}deg)`; } function resetFilters() { blurInput.value = 0; brightnessInput.value = 100; contrastInput.value = 100; hueInput.value = 0; updateFilter(); updateValueDisplays(); } function updateValueDisplays() { document.getElementById('blur-value').textContent = `${blurInput.value}px`; document.getElementById('brightness-value').textContent = `${brightnessInput.value}%`; document.getElementById('contrast-value').textContent = `${contrastInput.value}%`; document.getElementById('hue-value').textContent = `${hueInput.value}deg`; } // Add event listeners [blurInput, brightnessInput, contrastInput, hueInput].forEach(input => { input.addEventListener('input', () => { updateFilter(); updateValueDisplays(); }); }); </div> </section> <section class="example"> <h2>5. Filter Transitions</h2> <p>Apply smooth transitions to filter changes for animated effects.</p> <div class="demo transition-demo"> <div class="transition-item"> <img src="https://picsum.photos/200/300" alt="Forest"> </div> <div class="transition-item"> <img src="https://picsum.photos/200/300" alt="Forest"> </div> <div class="transition-item"> <img src="https://picsum.photos/200/300" alt="Forest"> </div> </div> <div class="code-block"> .transition-item { transition: filter 0.5s ease; } .transition-item:hover { filter: grayscale(80%) brightness(120%); } </div> </section> <section class="example"> <h2>6. Text with Filters</h2> <p>Apply filters to text elements for creative typography effects.</p> <div class="demo text-filters"> <div class="text-item text-glow">Glow Effect</div> <div class="text-item text-blur">Blur Effect</div> <div class="text-item text-multiple">Multiple Filters</div> </div> <div class="code-block"> .text-glow { filter: drop-shadow(0 0 10px var(--primary-color)); } .text-blur { filter: blur(1px); } .text-multiple { filter: drop-shadow(0 0 5px rgba(0,0,0,0.5)) brightness(110%); } </div> </section> <section class="example"> <h2>7. Backdrop Filters</h2> <p>Apply filters to the area behind an element using backdrop-filter.</p> <div class="demo"> <div class="backdrop-demo"> <img class="backdrop-image" src="https://picsum.photos/200/300" alt="Mountain background"> <div class="backdrop-content"> <h3>Frosted Glass Effect</h3> <p>This content has a backdrop filter applied</p> </div> </div> </div> <div class="code-block"> .backdrop-content { backdrop-filter: blur(10px) brightness(120%); } </div> </section> <section class="example"> <h2>8. Creative Filter Effects</h2> <p>Combine filters to create unique artistic effects.</p> <div class="demo creative-effects"> <div class="creative-item"> <img src="https://picsum.photos/200/300" alt="Dreamy effect"> <div class="filter-label">Dreamy</div> </div> <div class="creative-item"> <img class="effect-noir" src="https://picsum.photos/200/300" alt="Noir effect"> <div class="filter-label">Noir</div> </div> <div class="creative-item"> <img class="effect-sunset" src="https://picsum.photos/200/300" alt="Sunset effect"> <div class="filter-label">Sunset</div> </div> <div class="creative-item"> <img class="effect-frosted" src="https://picsum.photos/200/300" alt="Frosted effect"> <div class="filter-label">Frosted</div> </div> </div> <div class="code-block"> .effect-dreamy { filter: brightness(110%) saturate(150%) hue-rotate(315deg) contrast(130%) blur(0.5px); } .effect-noir { filter: grayscale(100%) contrast(150%) brightness(80%); } .effect-sunset { filter: hue-rotate(330deg) saturate(150%) brightness(110%); } .effect-frosted { filter: brightness(120%) blur(1px) contrast(90%); } </div> </section> </div> <script> // Interactive filter controls const blurInput = document.getElementById('blur'); const brightnessInput = document.getElementById('brightness'); const contrastInput = document.getElementById('contrast'); const hueInput = document.getElementById('hue'); const result = document.getElementById('interactive-result'); function updateFilter() { result.style.filter = `blur(${blurInput.value}px) brightness(${brightnessInput.value}%) contrast(${contrastInput.value}%) hue-rotate(${hueInput.value}deg)`; } function resetFilters() { blurInput.value = 0; brightnessInput.value = 100; contrastInput.value = 100; hueInput.value = 0; updateFilter(); updateValueDisplays(); } function updateValueDisplays() { document.getElementById('blur-value').textContent = `${blurInput.value}px`; document.getElementById('brightness-value').textContent = `${brightnessInput.value}%`; document.getElementById('contrast-value').textContent = `${contrastInput.value}%`; document.getElementById('hue-value').textContent = `${hueInput.value}deg`; } // Add event listeners [blurInput, brightnessInput, contrastInput, hueInput].forEach(input => { input.addEventListener('input', () => { updateFilter(); updateValueDisplays(); }); }); // Initialize values updateValueDisplays(); </script> </body> </html>
Key CSS Filters Concepts
Filter Functions
blur()
: Applies a Gaussian blurbrightness()
: Adjusts element brightnesscontrast()
: Adjusts element contrastgrayscale()
: Converts to grayscalehue-rotate()
: Shifts hue of colorsinvert()
: Inverts colorsopacity()
: Adjusts transparencysaturate()
: Adjusts color saturationsepia()
: Applies sepia tonedrop-shadow()
: Applies shadow effect
Advanced Techniques
- Combine multiple filter functions
- Use with CSS transitions for animations
- Apply to non-image elements (text, divs, etc.)
- Create backdrop filters for frosted glass effects
- Use with SVG elements and filters
- Chain filters for complex visual effects
- Control filters dynamically with JavaScript
CSS Filters Best Practices
Do's
- Use for subtle enhancements rather than drastic changes
- Test performance impact on lower-powered devices
- Combine with CSS transitions for smooth effects
- Use fallbacks for browsers that don't support filters
- Experiment with different filter combinations
Don'ts
- Don't overuse heavy filters that impact performance
- Avoid applying filters to large numbers of elements
- Don't rely solely on filters for critical visual information
- Avoid extreme values that make content inaccessible
- Don't forget to test across different browsers
Real-World Applications
Where to Use CSS Filters
- Image Galleries: Apply hover effects to images
- User Interfaces: Create disabled states with grayscale
- Hero Sections: Add subtle blur to background images
- Loading States: Use blur to indicate loading
- Theming: Create color variations with hue-rotate
- Accessibility: Enhance contrast for better readability
- Artistic Effects: Create unique visual styles
Browser Support & Limitations
Compatibility Information
CSS filters have excellent support in modern browsers, but there are some considerations for older browsers.
- Supported in Chrome 53+, Firefox 35+, Safari 9.1+, Edge 79+
- Partial support in older versions with prefixes
- Backdrop-filter has more limited support
- Consider using @supports for feature detection
- Provide fallback designs for unsupported browsers
Ready to Experiment with CSS Filters?
Try these CSS filters examples in our interactive editor. Modify the code, see the results in real-time, and practice implementing visual effects in your projects.