I want a div that covers the image. I can make the div cover the image by using position: relative
in the parent element, and position: absolute
in the div, but the background-color
fills Padding of parent elements, causing them to not cover properly.
Below is a snippet demonstrating the problem.
.parent { position: relative; padding: 10px; width: 40%; } .image { width: 100%; height: 100%; border-radius: 13px; } .overlay { position: absolute; background-color: red; width: 100%; height: 100%; border-radius: 13px; left: 0; top: 0; opacity: 0.2; }
<div class="parent"> <img class="image" src="https://cards.scryfall.io/normal/front/4/f/4f3deefe-28bc-4e45-a0a0-ab03167e2e81.jpg?1561942156"> <div class="overlay"></div> </div>
I can achieve a pretty close result by subtracting the padding with some calc()
. This almost works, but the div
has a little too much padding at the bottom. Anyway, I don't want to hardcode a lot of values for padding, so even if it works at all, I don't really like this solution.
The following is a snippet showing the calc()
method.
.parent { position: relative; padding: 10px; width: 40%; } .image { width: 100%; height: 100%; border-radius: 13px; } .overlay { position: absolute; background-color: red; width: calc(100% - 2 * 10px); height: calc(100% - 2 * 10px); border-radius: 13px; left: 10px; top: 10px; opacity: 0.2; }
<div class="parent"> <img class="image" src="https://cards.scryfall.io/normal/front/4/f/4f3deefe-28bc-4e45-a0a0-ab03167e2e81.jpg?1561942156"> <div class="overlay"></div> </div>
P粉4222270232023-09-13 00:53:20
When using HTML5, the browser adds some padding at the bottom of the img
tag. This can be avoided by setting the image as a block-level element. So just add display: block
to the .image
class and you're good to go.
By the way, to define the width/height of an absolute element, in addition to using calc()
, you can also use 4 values top
, right
, bottom
, left
to define.
:root { --custom-padding: 10px; } .parent { position: relative; padding: var(--custom-padding); width: 40%; } .image { width: 100%; height: 100%; border-radius: 13px; display: block; } .overlay { position: absolute; background-color: red; border-radius: 13px; bottom: var(--custom-padding); right: var(--custom-padding); left: var(--custom-padding); top: var(--custom-padding); opacity: 0.2; }
<div class="parent"> <img class="image" src="https://cards.scryfall.io/normal/front/4/f/4f3deefe-28bc-4e45-a0a0-ab03167e2e81.jpg?1561942156"> <div class="overlay"></div> </div>
P粉5417963222023-09-13 00:18:45
This snippet does it a slightly different way, placing the img inside the overlay div, and using the actual green, low-opacity overlay as the after pseudo-element of the overlay div.
This way you don't have to build any knowledge of the parent element's padding.
.parent { position: relative; padding: 10px; width: 40%; background: red; height: fit-content; } .image { width: 100%; border-radius: 13px; top: 0; left: 0; } .overlay { position: relative; padding: 0; width: fit-content; height: fit-content; } .overlay::after { content: ''; position: absolute; background-color: green; width: 100%; height: 100%; border-radius: 13px; left: 0; top: 0; opacity: 0.2; padding: 0px; }
<div class="parent"> <div class="overlay"> <img class="image" src="https://cards.scryfall.io/normal/front/4/f/4f3deefe-28bc-4e45-a0a0-ab03167e2e81.jpg?1561942156"></div> </div>