Search code examples
cssopacitylinear-gradientscss-mask

How to make a rectangular transparency gradient CSS3?


I am trying to make in CSS3 rectangular gradient like done with older:

filter: alpha(opacity=65, style=3)

gradient

Unfortunately mask-image property (which i used in order to achieve elliptic ones) does not have rectangular-gradient option.

( pre CSS3 snippet )

.foto_1 { filter: alpha(opacity=65, style=0); }
.foto_2 { filter: alpha(opacity=65, style=1); }
.foto_3 { filter: alpha(opacity=65, style=2); }
.foto_4 { filter: alpha(opacity=65, style=3); }
<div class="div_2"><img src="https://i.sstatic.net/HGRgk.jpg" alt=""><img class="foto_1" src="https://i.sstatic.net/HGRgk.jpg" alt=""></div><div class="div_2"><img src="https://i.sstatic.net/HGRgk.jpg" alt=""><img class="foto_2" src="https://i.sstatic.net/HGRgk.jpg" alt=""></div><div class="div_2"><img src="https://i.sstatic.net/HGRgk.jpg" alt=""><img class="foto_3" src="https://i.sstatic.net/HGRgk.jpg" alt=""></div><div class="div_2"><img src="https://i.sstatic.net/HGRgk.jpg" alt=""><img class="foto_4" src="https://i.sstatic.net/HGRgk.jpg" alt=""></div>

(CSS3 what I was able to recreate was only first 3 pictures)

/* CSS3 */
.foto_1 { filter: opacity(65%); }
.foto_2 { filter: opacity(65%); mask-image: linear-gradient(to left, transparent, black); }
.foto_3 { filter: opacity(65%); mask-image: radial-gradient(circle, black, transparent 65%); }
.foto_4 { filter: opacity(65%); }
<div class="div_2"><img src="https://i.sstatic.net/HGRgk.jpg" alt=""><img class="foto_1" src="https://i.sstatic.net/HGRgk.jpg" alt=""></div>
	<div class="div_2"><img src="https://i.sstatic.net/HGRgk.jpg" alt=""><img class="foto_2" src="https://i.sstatic.net/HGRgk.jpg" alt=""></div>
	<div class="div_2"><img src="https://i.sstatic.net/HGRgk.jpg" alt=""><img class="foto_3" src="https://i.sstatic.net/HGRgk.jpg" alt=""></div>
	<div class="div_2"><img src="https://i.sstatic.net/HGRgk.jpg" alt=""><img class="foto_4" src="https://i.sstatic.net/HGRgk.jpg" alt=""></div>


Solution

  • Unfortunately mask-image property (which i used in order to achieve elliptic ones) does not have rectangular-gradient option.

    You can build it with multiple mask:

    .foto_1 {
      -webkit-mask:
        linear-gradient(to right ,rgba(0,0,0,0.2) ,white ,rgba(0,0,0,0.2)),
        linear-gradient(to bottom,rgba(0,0,0,0.2) ,white ,rgba(0,0,0,0.2));
      mask:
        linear-gradient(to right ,rgba(0,0,0,0.2) ,white ,rgba(0,0,0,0.2)),
        linear-gradient(to bottom,rgba(0,0,0,0.2) ,white ,rgba(0,0,0,0.2));
      -webkit-mask-composite: source-in; /* For Chrome */
      mask-composite: intersect; /* For Firefox */
    }
    <img src="https://i.sstatic.net/HGRgk.jpg" alt="">
    <img class="foto_1" src="https://i.sstatic.net/HGRgk.jpg" alt="">

    Changing the color stops to better see the rectangle:

    .foto_1 {
      -webkit-mask:
        linear-gradient(to right ,rgba(0,0,0,0.2) 20% ,white 20% 80%,rgba(0,0,0,0.2) 80%),
        linear-gradient(to bottom,rgba(0,0,0,0.2) 20%, white 20% 80%,rgba(0,0,0,0.2) 80%);
      mask:
        linear-gradient(to right ,rgba(0,0,0,0.2) 20% ,white 20% 80%,rgba(0,0,0,0.2) 80%),
        linear-gradient(to bottom,rgba(0,0,0,0.2) 20%, white 20% 80%,rgba(0,0,0,0.2) 80%);
      -webkit-mask-composite: source-in; /* For Chrome */
      mask-composite: intersect; /* For Firefox */
    }
    <img src="https://i.sstatic.net/HGRgk.jpg" alt="">
    <img class="foto_1" src="https://i.sstatic.net/HGRgk.jpg" alt="">

    Another idea to avoid the corner effect of the previous one:

    .box {
      display:inline-block;
      position:relative;
    }
    .box:before,
    .box:after{
      content:var(--img);
      display:block;
      -webkit-mask:linear-gradient(to var(--d,bottom) ,rgba(0,0,0,0.1) ,white,rgba(0,0,0,0.1));
      mask:linear-gradient(to var(--d,bottom),rgba(0,0,0,0.1) ,white,rgba(0,0,0,0.1));
      clip-path:polygon(0 0,100% 100%,0 100%, 100% 0);
    }
    .box:after {
      position:absolute;
      top:0;
      left:0;
      --d:right;
      clip-path:polygon(0 0, 100% 100%, 100% 0,0 100%);
    }
    <div class="box" style="--img:url(https://i.sstatic.net/HGRgk.jpg)"></div>