2

I need to create an overlay element with HTML/CSS that covers only a certain container, not the whole page. I could use position:absolute; and then everywhere 0px, but the trouble is that I cannot position the container that should be covered, it has to stay positioned static, and then position:absolute; will not relate to this container.

So I tried to fix this setting height and width to 100%:

body {
  background-color: grey;
}

#ovl {
  height: 100%;
  width: 100%;
  background-color: #a10000a1;
}
#container {
  border: 4px dotted blue;
}           
<!DOCTYPE html>
<html>
    <body>
        <div id="container">
            <div id="ovl">
                This Overlay should hide the images.
            </div>
            <img height=300 src="1.png" class="imgs" alt="Error!">
            <img height=300 src="2.png" class="imgs" alt="Error!">
            <img height=300 src="3.png" class="imgs" alt="Error!">
        </div>
    </body>
</html>

I expected that the red overlay element would cover the whole container and the three images in it, but I got this. The three images (music scores) are not covered by the red overlay. Is there any error in my code? How to fix?

Bill-G
  • 305
  • 4
  • 12
ferdi2003
  • 23
  • 5
  • Possible duplicate of [How exactly does absolute position element behaves inside a static parent](https://stackoverflow.com/questions/20033949/how-exactly-does-absolute-position-element-behaves-inside-a-static-parent) – Anurag Srivastava Aug 03 '19 at 17:16
  • So, the overlay is outside of the div that is nested? – Axel Anaya Aug 03 '19 at 17:55
  • display:grid could be used if you assign to the overlay the same area that image covers. see answer below. – G-Cyrillus Aug 03 '19 at 19:04
  • @AnuragSrivastava Unfortenatly this did not solve my problem. – ferdi2003 Aug 03 '19 at 20:28
  • @AxelAnaya The overlay is inside the container div, but I could change this if necessary. – ferdi2003 Aug 03 '19 at 20:29
  • Is there any case where `position:relative;` without any `top:...` or `bottom:...` although changes the position of the element? If not, and I don't think so, I could use this for the container and then `position:absolute; top:0px; bottom:0px; ...` for the overlay. – ferdi2003 Aug 03 '19 at 21:06
  • @ferdi2003 if you use `width` and `height` at 100%, you remove the use of `top` and the others, and the overlay will overlap all the div – Axel Anaya Aug 04 '19 at 00:23
  • this is my [CodePen](https://codepen.io/MaddozS/pen/PMJByW) wtih using __grid__ and __position__ – Axel Anaya Aug 04 '19 at 00:25

4 Answers4

1

CSS Grid can do that. No positioning required.

body {
  background-color: grey;
}

#ovl {
  background-color: #a10000a1;
  grid-column: 1 / -1;
  grid-row: 1;
  z-index: 2;
  color: white;
}

#container {
  border: 4px dotted blue;
  display: inline-grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: auto;
}

img {
  grid-row: 1;
  max-height: 100%;
  width: auto;
}

img:nth-of-type(1) {
  grid-column: 1;
}

img:nth-of-type(2) {
  grid-column: 2;
}

img:nth-of-type(3) {
  grid-column: 3;
}
<div id="container">
  <div id="ovl">
    This Overlay should hide the images.
  </div>
  <img height=300 src="http://www.fillmurray.com/g/140/100" class="imgs" alt="Error!">
  <img height=300 src="http://www.fillmurray.com/g/140/100" class="imgs" alt="Error!">
  <img height=300 src="http://www.fillmurray.com/g/140/100" class="imgs" alt="Error!">
</div>
Paulie_D
  • 107,962
  • 13
  • 142
  • 161
1

This is a solution using CSS Grid:

.grid{
  display:grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 1fr 1fr 1fr;
/*   grid-template-row: 1fr; */
  border: 3px dotted blue;
  width: 100%;
}
.overlay{
  background: #000000a1;
  color: white;
  grid-column: 1 / span 3;
  grid-row: 1/ span 3;
  z-index: 1;
}
.img1{
  grid-column: 1 / span 2;
  grid-row: 1/ span 1;
}
.img2{
  grid-column: 1 / span 2;
  grid-row: 2/ span 2;
}
.img3{
  grid-column: 1 / span 2;
  grid-row: 3/ span 3;
}
          
<div class="grid">
  <div class="overlay">
    This Overlay should hide the images.
  </div>
  <img src="1.png" class="img1" alt="Error!">
  <img src="2.png" class="img2" alt="Error!">
  <img src="3.png" class="img3" alt="Error!">
</div>

This is my CodePen if you want to try and experiment

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Axel Anaya
  • 122
  • 9
  • Wasn't that you who answered I should use "position:relative;" for the container, but then deleted this answer? However, the reason why I wanted to omit using `position:absolute;` for the overlay was bacause I did not know how to position the container without changing its real position. But if `position:relative;` does not change the position if top/bottom/... are not specified, I can use this. Is there any case when relative positioning without any other specification changes the position? – ferdi2003 Aug 03 '19 at 21:02
  • Yes, I deleted my answer because that you said about avoiding the use of `position`, however, if you `relative` position a top/bottom..., `position: relative` will layout an element relative to itself. In other words, the elements is laid out in normal flow, then it is removed from normal flow and offset by whatever values you have specified See [this](https://stackoverflow.com/questions/104953/position-an-html-element-relative-to-its-container-using-css?rq=1) – Axel Anaya Aug 03 '19 at 21:28
  • Then it was my fault to write that I wish to avoid `position`. So it is a good solution for my problem to `position` the container `relative` and the overlay `absolute` and everywhere `0px`...? This will **definitely not** change the position of any element except the overlay? – ferdi2003 Aug 04 '19 at 15:26
  • If you want to overlay everything in your container you should use height and width at 100%, because when you use position absolute in a tag, it will ignore all the positions of its relatives. but keeping the positions of its first position relative parent, that's why you need to use position relative in the container – Axel Anaya Aug 04 '19 at 15:30
0

The best way to do an overlay, is using position:absolute in the child and position:relative in the parent, this will be your CSS code

body {
  background-color: grey;
}

#ovl {
  background-color: #a10000a1;
  position: absolute;
  width: 100%;
  height: 100%;
}
#container {
  border: 4px dotted blue;
  position: relative;
}                 

See the results here

All the other solutions without positions absolute/relative could be very cumbersome

Community
  • 1
  • 1
Axel Anaya
  • 122
  • 9
0

In my understanding of the problem , There is an error with your Divs. try this instead:

<!DOCTYPE html>
<html>
    <body>
      <div id="ovl">
        <div id="container">

                This Overlay should hide the images.
            </div>
            <img height=300 src="1.png" class="imgs" alt="Error!">
            <img height=300 src="2.png" class="imgs" alt="Error!">
            <img height=300 src="3.png" class="imgs" alt="Error!">

        </div>
    </body>
</html>

CSS

body {
  background-color: grey;
}

#ovl {
  height: 100%;
  width: 100%;
  background-color: #a10000a1;
}
#container {
  border: 4px dotted blue;
}           
Johans
  • 5
  • 4
  • Since you only exchanged the IDs, the code you wrote will cause the image container to be red and the overlay to have a blue border, which is not my intention. My intention was to make the overlay filling the whole container, see above. – ferdi2003 Aug 03 '19 at 19:40