CSS Filters: Applying Effects to Images and Elements

Chidinduka
LearnFactory Nigeria
9 min readJun 1, 2023

CSS which stands for Cascading Style Sheet is used to style our web page to our taste. This applies to images as well as other elements on the web page. Sometimes we desire an image, text, background, or border on our web page to have a certain appearance different from the original or default appearance. To achieve this, we use the CSS filter.
CSS filter is a property of CSS that makes it possible to add certain visual effects to a web element to achieve a desired appearance. With CSS filter, one can adjust the blur, brightness, contrast, opacity, saturation, etc of a web element. There are about ten (10) filter properties in CSS namely:
1. blur()
2. brightness()
3. contrast()
4. grayscale ()
5. hue-rotate()
6. invert()
7. opacity()
8. saturate()
9. sepia()
10. drop-shadow()

How to apply a CSS filter?
To apply a CSS filter, we declare the CSS filter property inside the element's style block together with the effect function and give it a value that will give the desired effect. The value can be a percentage, decimal, length, or degree value determining the extent of the effect the filter property will have on the element.

For example: element {
filter: none | blur() | brightness() | contrast() | drop-shadow() | grayscale() | hue-rotate() | invert() | opacity() | saturate() | sepia() | url();
}
Now, let’s look at how each CSS filter works in detail.

  1. Blur

Syntax
img {
filter: blur( <length>);
}

The CSS blur filter applies a Gaussian blur visual effect to an element. It accepts a CSS length unit (px, rem, em, etc.) to determine how many pixels on the screen need to blend into each other to generate a blurred result. The larger the value of the CSS length unit passed to the filter, the more blur is applied to the element. If we do not provide a value, a default value of 0 is used.

2. Brightness


Syntax
img {
filter: brightness( <decimal> | <percentage>);
}

The brightness filter adjusts the brightness level of an image. The filter applies a linear multiplier to the input image, making it appear brighter or darker.
It accepts a decimal value between 0 and 1, or a percentage value. A value of 0 results in a completely black image. A value of 100% or 1 leaves the image as is with its original brightness level. Values greater or less than 100% or 1 determine how dark or bright the image will be.

3. Contrast


Syntax
img {
filter: contrast(<decimal> | <percentage>);
}

The contrast filter adjusts the brightness difference between the darkest and lightest parts of an image, giving the image a more or less enhanced look.
It accepts a percentage or decimal value to determine the contrast level of an image — a value of 0 results in a completely gray image. Values above 100% and 1 increase the contrast, and parameters below decrease the contrast of the image.

4. Grayscale


Syntax
img {
filter: grayscale( <decimal> | <percentage>)
}

In digital photography, an image contains both color information and luminance (brightness) information. The grayscale filter removes all color information (a representation of the three light sources — red, green, and blue (RGB) used to produce colors on a computer screen) from an image. It leaves only the luminance information — a range of monochromic (gray) shades, with pure white as the lightest shade, pure black as the darkest shade, and every other shade in between being a shade of gray — known as the grayscale.
It accepts a decimal value between 0 and 1, or a percentage value up to 100%.
A value of 100% or 1 results in a completely gray image. The image would remain unchanged with a value of 0% or 0, and values between 0% and 100% give it a tone between its original color and complete gray, making the image have a desaturated look.

5. Hue-rotate


Syntax
img {
filter: hue-rotate(<angle> | <zero>);
}

Digital photography uses a concept known as the color wheel, an organization of colors around a circle, showing the relationships between the primary, secondary, and tertiary colors to produce colors on a computer screen.
Each color in the color wheel has a property called hue, the position of the color (in angle degrees) on the wheel.
The hue-rotate filter accepts a CSS angle value (`deg`, `grad`, `rad`, or `turn`) and shifts the hue value of each color present on an element relative to the amount you specify, updating all colors relative to their hue’s starting point.
For example, red is at 0 degrees on the color wheel, and blue is at 240 degrees. If a portion of an image contains red, passing a value of `240deg` to the `hue-rotate` filter will shift the hues of all the colors on the image by 240 degrees, turning that part of the image from red to blue.
The value you enter defines the number of degrees around the color circle the image will be adjusted. 0deg is the default and represents the original image. Note: Maximum value is 360deg.
Note, the unit identifier for the hue-rotate filter is optional for zero angles. For example, both rotate(0deg) and rotate(0) are valid, but hue-rotate(45) is not.

6. Invert


img {
filter: invert(<decimal> | <percentage>);
}

Remember the color wheel mentioned in the section above? When applied to an element or image, the CSS invert filter flips the hue of every color present by 180 degrees, converting each color to the color directly opposite it on the color wheel.
The inverted filter accepts a decimal value between 0 and 1, or a percentage value up to 100% that controls the extent of the color-negative effect. A value of 0.5 or 50% turns an image completely gray.

7. Opacity


Syntax
img {
filter: opacity( <decimal> | <percentage>)
}

The opacity filter applies a transparency effect to an element’s colors. It accepts a percentage or decimal value to decide how much transparency to apply to an image. An opacity of 0% or 0 will result in a completely transparent element. 100% opacity will show no transparency. Setting the opacity between 0% and 100% will give the element or image partial transparency.
You might notice that the opacity filter works just like the CSS opacity property because both control how transparent an element should be. The difference and why you should prefer the opacity filter over the CSS opacity property is that CSS filters are hardware-accelerated.
When you use the opacity filter to add opacity to an element, the browser will offload the computing task onto the Graphics Processing Unit (GPU) — a specialized processor designed to accelerate graphics rendering within the system. This increases the browser’s efficiency and frees up the CPU to perform other tasks.

8. Saturate


Syntax
img {
filter: saturate(<decimal> | <percentage>);
}

The CSS saturate filter enhances or decreases the intensity of a color, known as its saturation, making it appear more or less vivid.
It accepts a decimal value between 0 and 1, or a percentage value. A value of 100% or 1 keeps the color as is the original form. A value above 100% or 1 amplifies the color’s intensity, making it more vibrant (saturated), while values below that reduce the color’s intensity, making the color gray and dull (desaturated).

9. Sepia


Syntax
img {
filter: sepia(<decimal> | <percentage>);
}

The sepia filter adds a soft brownish color tone to an image, giving it a warmer and vintage appearance that is calming to the eye. It is similar to using the grayscale filter but with a brownish color tone.
It accepts a decimal value between 0 and 1, or a percentage value up to 100%. A value of 0 leaves the image unchanged. A value of 100% or 1 changes the image entirely to sepia, and values between 0% and 100% give the image a tone between its original color and completely sepia.

10. Drop-shadow


Syntax
img {
filter: drop-shadow(<offset-x> <offset-y> <blur-radius> <color>);
}

The CSS drop-shadow filter applies an (often blurry) background shadow to an element, giving it a more two-dimensional look.
The drop-shadow filter accepts four parameters when applying a drop shadow to an element:
<offset-x>: A CSS length value that specifies the horizontal distance between the element and the drop shadow. Positive values place the shadow to the element’s right, and negative values place the shadow to the left.
<offset-y>: A CSS length value that specifies the vertical distance between the element and the drop shadow. Positive values place the shadow below the element, and negative values place the shadow above it.
<blur-radius>: The blur radius of the shadow is specified as a CSS length unit. The larger the value, the more blurred the shadow becomes. If left unspecified, it defaults to 0, producing a sharp and unblurred shadow. No negative values are permitted.
<color>: The color of the shadow, specified as a CSS color. If left unspecified, it defaults to the color black.
Here’s an example of setting a drop shadow to an element:
img {
filter: drop-shadow(30px 30px 50px #000);
}
Code language: CSS (css)
The code above adds a black shadow with a 50px blur to the image, setting it to 30px to the right of the image and 30px below it.
The `drop-shadow` filter looks much like the CSS `box-shadow` property at first glance. However, there’s a difference between the two, and it’s worth comparing those differences to know when to prefer one over the other.
One difference between the `drop-shadow` filter and the `box-shadow` property is the `drop-shadow` filter does not accept the `inset` keyword, which, when set, rather than aligning the shadow behind the element, inserts the shadow within the element, giving it a framed appearance.
Another difference between the `drop-shadow` filter and the `box-shadow` property is the `drop-shadow` filter does not accept the <spread-radius> parameter — a CSS length value that specifies how wide the shadow will span. Positive values cause the shadow to enlarge, and negative values cause the shadow to shrink. If not specified, it will default to a value of 0 (the shadow will be the same size as the element).
Example:
img {
box-shadow: 30px 40px 50px 70px gray;
}
The code above adds a gray shadow with a 50px blur to an image, passing an additional length value of 70px that signifies the shadow will span 50px more than the image in width.
Lastly, CSS box-shadow uses a box model, where the edges of an element are bound in a rectangular box containing its padding, border, and margin properties. Even in cases where the element does not appear to have a rectangular shape, the box is still there, which is where the shadow will be applied.
CSS filters are not bound to the box model. That means that the drop-shadow filter will only consider the outline of the element, ignoring its box model so that only the contents of the element receive the shadow.
Deciding which method to use between `drop-shadow` and `box-shadow` is totally up to you based on the effect you want to achieve.

Using CSS filters with SVGs: url() – for applying SVG filters
Many developers consider this the 11th filter property but in reality, it is actually applying filter property using SVG which does not really have in itself a distinct property from the above-listed filter properties.


.svg-filter {
filter: url('#selector-of-your-svg-filter-here');
/* you can also load filters from external SVGs this way: */
filter: url('filters.svg#name-of-your-other-filter-here');
}

The url filter takes a string value pointing to an SVG filter element and applies its effects to an HTML element.
The SVG filter element `<filter></filter>` is used to add special visual effects to SVG graphics.

Syntax:

<svg> 
<defs>
<filter id="name-your-filter-here">
... <!-- insert filters here --> ...
</filter> ...
</defs>
</svg>

The `<filter>` tag takes a required id attribute to identify the filter. We can then use the url filter to apply the SVG filters to HTML elements using either the id selector of the filter or a link to it.
For example, the code below defines a blur filter using the `<feGaussianBlur>` filter tag:

//HTML
<svg>
<defs>
<filter id="blur-filter" x="0" y="0">
<feGaussianBlur in="SourceGraphic" stdDeviation="8" />
</filter>
</defs>
</svg>

// Now, you can apply the SVG filter to an element by passing its id to the url filter:
//CSS
img {
filter: url("#blur-filter");
}

Using multiple CSS filters
It is possible to use multiple filters, all you have to do is to separate each filter with a space. The filters are applied in the order declared. Example: filter: contrast(75%) brightness(80%)

Browser Compatibility
Not all filter properties are supported by all browsers. Earlier browsers such as Internet Explorer, Edge 12, or Safari 5.1 do not support CSS filter properties. All modern browsers support virtually all CSS filter properties. However, it is important to test to ensure your browser supports the filter property you intend to apply.

--

--