问题
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 last element of the container:
I understand that I can't set a pseudo-selector to an <img/>
, but here I am setting ::after
to the container and I don't get why it isn't working properly.
Why is this happening and how could I make ::after
actually the last element of testDiv
?
P.S. I can't set the container or any parent element with position: relative
, since I need ::after
to have the same width as the screen and not just to fit inside the container and I don't have any element with the same width as the screen.
P.S. The margin-left:100px
is just to make it easier to be seen in the snippet, therefore it doesn't matter to my purpose.
.testDiv > div::after {
position: absolute;
height: 2px;
content: "";
background-color: red;
left: 0;
right: 0;
}
.testDiv > div {
margin-left: 100px;
}
<div class="testDiv">
<div>
<h1>TEST</h1>
<h2>TEST</h2>
<img src="https://www.acmetek.com/wp-content/uploads/rapidssl-logo.png" />
</div>
</div>
回答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;
}
<div class="testDiv">
<div>
<h1>TEST</h1>
<h2>TEST</h2>
<img src="https://www.acmetek.com/wp-content/uploads/rapidssl-logo.png" />
</div>
</div>
回答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: 100vw 0 0 red; /* big value here too*/
}
.testDiv>div {
margin-left: 100px; /* we have a margin */
width: 200px; /* and a width too */
position: relative;
}
<div class="testDiv">
<div>
<h1>TEST</h1>
<h2>TEST</h2>
<img src="https://www.acmetek.com/wp-content/uploads/rapidssl-logo.png" />
</div>
</div>
<div class="testDiv">
<div>
<h1>Another one </h1>
<h2>TEST</h2>
<img src="https://www.acmetek.com/wp-content/uploads/rapidssl-logo.png" />
</div>
</div>
回答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%
}
<div class="testDiv">
<div>
<h1>TEST</h1>
<h2>TEST</h2>
<img src="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%
}
<div class="testDiv">
<div>
<h1>TEST</h1>
<h2>TEST</h2>
<img src="https://www.acmetek.com/wp-content/uploads/rapidssl-logo.png" />
</div>
</div>
来源:https://stackoverflow.com/questions/64996565/why-is-after-pseudo-selector-over-the-image-and-not-under-it