Search code examples
csscss-mask

How to use a CSS mask with an image?


I am trying to put gradient mask on image but it's not working

     <div className="first-section">
     <img src={BgPic} alt="Bg-pic" className="bg-pic" />
     </div>
 .bg-pic{
     width:100%;

     mask-image:linear-gradient(180deg, #000000 0%, #380A46 100%) 0% 0% no-repeat padding-box;
  }

What's the correct way to use mask:


Solution

  • To understand how to correctly use mask you need to first refer to the mask-mode as detailed in the specification

    The mask-mode property indicates whether the <mask-reference> is treated as luminance mask or alpha mask. (See Mask processing.)

     <masking-mode> = alpha | luminance | match-source
    

    The default value is match-source and when using gradient you will have:

    If the <mask-reference> of the mask-image property is of type <image> the alpha values of the mask layer image should be used as the mask values.

    gradients are images: https://drafts.csswg.org/css-images-3/#typedef-image

    Then if you refer to the mask processing you will read:

    The first and simplest method of calculating the mask values is to use the alpha channel of the mask image. In this case the mask value at a given point is simply the value of the alpha channel at that point. The color channels do not contribute to the mask value.

    So using your gradient you will have nothing since the alpha channel of your colors are equal to 1

    Either consider transparent (or semi-transparent) colors

    img{
      -webkit-mask: linear-gradient(180deg, transparent 0%, #380A46 100%) 0% 0% no-repeat padding-box;
              mask: linear-gradient(180deg, transparent 0%, #380A46 100%) 0% 0% no-repeat padding-box;
    }
    <img src="https://picsum.photos/id/1/300/200" >

    Or change the mode (will only work on Firefox)

    img{
      -webkit-mask: linear-gradient(180deg, #000000 0%, #380A46 100%) 0% 0% no-repeat padding-box;
              mask: linear-gradient(180deg, #000000 0%, #380A46 100%) 0% 0% no-repeat padding-box;
              mask-mode:luminance;
    }
    <img src="https://picsum.photos/id/1/300/200" >

    Note that I am using mask and not mask-image which is what you need here since you are considering other values like mask-repeat, mask-position, mask-clip so the longhand property is the one needed here.