DEV Community

Cover image for Masking and coloring product images using CSS and SVG
Mads Stoumann
Mads Stoumann

Posted on

Masking and coloring product images using CSS and SVG

If you have a product that's available in several colors, it can be cumbersome and expensive to take pictures of each variant.

Luckily, we can use CSS and SVG to mask a single image.

In this tutorial, we'll create a mask for the "product"-part of an image, so we can replace it's color. We'll also remove the background of the image, so we can add our own.


Initial steps

1.
Find a useable image. I searched for "white t-shirt" on pexels.com, and found this image:

Person in a white t-shirt

2.
Then I removed the background using remove.bg (you get 1 free credit per month, so use it wisely!)

3.
I converted this image to webp, using an online converter.

4.
Then I opened the converted image in Vectornator, a great, free vector-editor – and added a path using the Pen tool (for clarity, I added a layer behind the image with a solid background-color):

Path in Vectornator

5.
Finally, I exported the mask to svg, and cleaned it up using SVGOMG.

Phew! A lot of steps, but the only time-consuming step is the "masking" in Vectornator. If you need to do this for a lot of products, consider hiring a specialist on Fiverr or similar.


Now for the fun part! First, we need some markup:



<figure>
  <img src="image.webp" alt="Text" />
  <div></div>
</figure>


Enter fullscreen mode Exit fullscreen mode

For the figure-tag, we'll add a few CSS Custom Properties, to set the t-shirt-color in hsl():



figure {
  --h: 168;
  --s: 40%;
  --l: 65%;
}


Enter fullscreen mode Exit fullscreen mode

We want to set the background to the contrast-color of the t-shirt-color. That equals rotating the hue (--h) 180 degrees.

To make it a bit more interesing, we create a gradient with subtracted saturation (20%) for the first color, and subtracted lightness (20%) for the second:



figure {
--_bg: linear-gradient(15deg,
  hsl(calc(var(--h) + 180),
  calc(var(--s) - 20%),
  var(--l)), 
  hsl(calc(var(--h) + 180),
  var(--s),
  calc(var(--l) - 20%)));

  background: var(--_bg);
}


Enter fullscreen mode Exit fullscreen mode

Let's try it out, with different --h-values:

Colored background

Cool - now, let's color the t-shirt using a mask.


Enabling the mask



div {
  background-color: hsl(
    var(--h),
    var(--s),
    var(--l)
  );
  inset: 0;
  mask-image: url('mask.svg');
  mask-position: center;
  mask-repeat: no-repeat;
  mask-size: 100%;
  mix-blend-mode: multiply;
  position: absolute;
}


Enter fullscreen mode Exit fullscreen mode

Note: For Chrome and Safari, you need to add -webkit-prefixes to all the mask-properties.

Final result

Cool! Play around in Dev Tools with the three colors variables: --h, --s and --l.


A note on the SVG-mask

To be honest, I'm not very good at masking – and I've only used Vectornator a couple of times.

To make up for my masking-skills, I decided to make the mask a bit blurry, by adding a Gaussian blur to the svg:



<filter id="f1" x="0" y="0">
  <feGaussianBlur
    in="SourceGraphic"
    stdDeviation="3" />
</filter>


Enter fullscreen mode Exit fullscreen mode

And then, in the path itself:



<path filter="url(#f1)" ...>


Enter fullscreen mode Exit fullscreen mode

And that's it!

Here's a Codepen with added controls, so you can play around with the hsl-values:

Top comments (6)

Collapse
 
link2twenty profile image
Andrew Bone

I made Shaggy from Scooby Doo

shaggy

Collapse
 
madsstoumann profile image
Mads Stoumann

😂

Collapse
 
zerooeffect profile image
Damon Cahill

love ur work dude!

Collapse
 
madsstoumann profile image
Mads Stoumann

Thank you!

Collapse
 
akinzeman profile image
akin zeman

how to apply only to the masked t-shirt ? (ignore background)

Collapse
 
madsstoumann profile image
Mads Stoumann

Just remove the background from the figure-tag