Vitaliy
Vitaliy

Reputation: 429

How to place transparent color over image using ::after?

Problem: container has 200px width, image can have dynamic width (100px, 120px, whatever)

img::after does not work at all.

https://jsfiddle.net/8j1r0nmk/3/

<div class='wrapper'>
<div class='img-wrap'>
<img class='img-responsive' src='http://via.placeholder.com/150x150' alt='' />
</div>
</div>

.wrapper {
  position: relative;
  width: 200px;
  border: 1px solid black;
}
.img-responsive {
  display: block;
  max-width: 100%;
  height: 100%;
}
.img-wrap::after {
  display: block;
  position: absolute;
  content: ' ';
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
  background-color: rgba(40, 40, 60, 0.1);
}

I can not set width for .img-wrap because it breaks image width.

What are my options?

Upvotes: 1

Views: 45

Answers (3)

Fabrizio Calderan
Fabrizio Calderan

Reputation: 123397

You can achieve a similar result without using psuedoelements: the idea is to apply a SVG filter on the image itself (defined either on the page itself or as an external URL), so there's no need to make assumptions on the existant markup or about the parent containers

Codepen demo


Markup

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="overlayfilter">
  <defs>
      <filter id="overlay">
        <feColorMatrix
          type="matrix"
          values=".4  0  0  0  0
                   0 .4  0  0  0
                   0  0 .6  0  0
                   0  0  0 .6  0 ">

        </feColorMatrix>
    </filter>
  </defs>
</svg>


<img class='img-responsive' src='http://via.placeholder.com/150x150' alt='' />

CSS

[id="overlayfilter"]  { display: block; height: 0; }

.img-responsive {
  display: block;
  max-width: 100%;
  height: 100%;
  filter: url(#overlay);
}

.img-responsive:hover {
  filter: none;
}

The color of the filter is defined in this way

<filter id="linear">
  <feColorMatrix
      type="matrix"
      values="R 0 0 0 0
              0 G 0 0 0
              0 0 B 0 0
              0 0 0 A 0 "/>
  </feColorMatrix>
</filter>

(source)

So you may be able to adapt the overlay colour to your needs. Filters defined by url() are currently implemented on all modern browsers (excluding Edge).

Upvotes: 1

sol
sol

Reputation: 22949

You can apply the following CSS to img-wrap

.img-wrap {
  display: inline-block;
  position: relative;
  vertical-align: bottom;
}

I've changed the colour in the demo below to show the :after more clearly.

.wrapper {
  position: relative;
  width: 200px;
  border: 1px solid black;
}

.img-wrap {
  display: inline-block;
  position: relative;
  vertical-align: bottom;
}

.img-responsive {
  display: block;
  max-width: 100%;
  height: 100%;
}

.img-wrap::after {
  display: block;
  position: absolute;
  content: ' ';
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
  background-color: rgba(255, 0, 0, 0.2);
}
<div class='wrapper'>
  <div class='img-wrap'>
    <img class='img-responsive' src='http://via.placeholder.com/150x150' alt='' />
  </div>
</div>
<div class='wrapper'>
  <div class='img-wrap'>
    <img class='img-responsive' src='http://via.placeholder.com/120x120' alt='' />
  </div>
</div>
<div class='wrapper'>
  <div class='img-wrap'>
    <img class='img-responsive' src='http://via.placeholder.com/100x100' alt='' />
  </div>
</div>

Upvotes: 2

Liama511
Liama511

Reputation: 22

For the ::after css3 code I am sure that you have to have a ::before status included as well so that the file reads what should come before the after element. (Please don't quote me on this as I am not 100% sure however when I have worked with these I have also included an ::before)

When using the ::after content: url(/path/to/image.jpg); - The image is inserted at it's exact dimensions and cannot be resized. Since things like gradients are actually images, a pseudo element can be a gradient.

Upvotes: -1

Related Questions