Skip to content Skip to sidebar Skip to footer

Why Is '::after' Pseudo-selector Over The Image And Not Under It?

I have this container with some text and an image inside it as last element, I am trying to set an ::after to my container, however it is being shown over the image and not as the

Solution 1:

As far as I can see, neither existing answer actually address the question of why the line is over, not under the image. The reason can be found in CSS 2.2 Section 10.6.4. Absolutely positioned, non-replaced elements where it says if:

top and bottom are auto and height is not auto, then set top to the static position, set auto values for margin-top and margin-bottom to 0, and solve for bottom

and

the static position for top is the distance from the top edge of the containing block to the top margin edge of a hypothetical box that would have been the first box of the element if its specified position value had been static and its specified float had been none and its specified clear had been none.

Which means that the top of the absolute positioned box will be the top of where the box would have been had not been position:absolute.

Since both the img and the ::after pseudo element without position:absolute are display:inline they would have lined up alongside one another. The pseudo element taken out of the flow and stretched horizontally to meet the left:0;right:0 requirements.

What this means is that you can move the red line to below the img just by making the ::after pseudo element display:block.

This is quite an interesting effect given that we normally think of position:absolute blockifying the box anyway, but this only happens after the static position calculation.

Another solution, perhaps a little more intuitive, is to make the img element display:block.

.testDiv > div::after {
  position: absolute;
  height: 2px;
  content: "";
  background-color: red;
  left: 0;
  right: 0;
  display:block;
}

.testDiv > div {
  margin-left: 100px;
}
<divclass="testDiv"><div><h1>TEST</h1><h2>TEST</h2><imgsrc="https://www.acmetek.com/wp-content/uploads/rapidssl-logo.png" /></div></div>

Solution 2:

You can still use position:relative but have your element overflow from both sides:

.testDiv>div::after {
  position: absolute;
  height: 2px;
  content: "";
  background-color: red;
  left: -100vw; /* big value here */right: 0;
  bottom: 0;
  box-shadow: 100vw00 red; /* big value here too*/
}

.testDiv>div {
  margin-left: 100px; /* we have a margin */width: 200px; /* and a width too */position: relative;
}
<divclass="testDiv"><div><h1>TEST</h1><h2>TEST</h2><imgsrc="https://www.acmetek.com/wp-content/uploads/rapidssl-logo.png" /></div></div><divclass="testDiv"><div><h1>Another one </h1><h2>TEST</h2><imgsrc="https://www.acmetek.com/wp-content/uploads/rapidssl-logo.png" /></div></div>

Solution 3:

Given your comment

It doesn't solve my problem, since I need the ::after to have the width of the screen and not only of the container

You need to set position:relative to .testDiv parent and also add bottom:0 and width:100% to the pseudo element

.testDiv {
  position: relative
}

.testDiv>div {
  margin-left: 100px;
}

.testDiv>div::after {
  position: absolute;
  height: 2px;
  content: "";
  background-color: red;
  left: 0;
  bottom: 0;
  width: 100%
}
<divclass="testDiv"><div><h1>TEST</h1><h2>TEST</h2><imgsrc="https://www.acmetek.com/wp-content/uploads/rapidssl-logo.png" /></div></div>

UPDATE - based on your comment

you will need either set bottom: (any value)(any unit you need) or top: (any value)(any unit you need)

.testDiv>div::after {
  position: absolute;
  height: 2px;
  content: "";
  background-color: red;
  left: 0;
  bottom: 50px;
  width: 100%
}
<divclass="testDiv"><div><h1>TEST</h1><h2>TEST</h2><imgsrc="https://www.acmetek.com/wp-content/uploads/rapidssl-logo.png" /></div></div>

Post a Comment for "Why Is '::after' Pseudo-selector Over The Image And Not Under It?"