Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

I’m trying to make all the images on my site duotone without having to use pseudo-elements and wrappers. (Trying to keep the HTML clean)

Currently, I’ve been using this tutorial. But it is just not as clean As I’d have hoped, and I’m sure there is a better alternative.

I know I can do this:

.img-wrap{
    position: relative;
}
.img-wrap img{
    filter: grayscale(1);
    width: 100%;
    z-index: 0;
}
.img-wrap::before{
    content:'';
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background: red;
    z-index: 1;
    mix-blend-mode: screen;
}
<div class="img-wrap">
  <img src="https://picsum.photos/200/100/">
</div>

But I want to accomplish this without having to use a wrapper.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You can use SVG filters to do this.

img{
  width: 100%;
  filter: url(#duotone);
}
<img src="https://picsum.photos/200/100"/>

<svg xmlns="http://www.w3.org/2000/svg">
  <filter id="duotone">
    <feColorMatrix type="matrix" result="grayscale"
      values="1 0 0 0 0
              1 0 0 0 0
              1 0 0 0 0
              0 0 0 1 0" >
    </feColorMatrix>
    <feComponentTransfer color-interpolation-filters="sRGB" result="duotone">
      <feFuncR type="table" tableValues="1 1"></feFuncR>
      <feFuncG type="table" tableValues="0 1"></feFuncG>
      <feFuncB type="table" tableValues="0 1"></feFuncB>
      <feFuncA type="table" tableValues="0 1"></feFuncA>
    </feComponentTransfer>
  </filter>
</svg>

The way this works is:

  1. We define the filter as #duotone in our SVG.
  2. We convert the image to grayscale feColorMatrix.
  3. Finally, we apply a RGBA filter on top of that image. These values are set via the tableValues. The first of two values being the amount (from 0 → 1). A common way to understand this is by taking the RGBA values you are used to and dividing them by 255 (since thats the max). For example, a red value of 100 would be 100/255=0.3921 OR <feFuncR type="table" tableValues="0.3921 1"></feFuncR>.
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading