CSS :after pseudo element not showing up on img?
As answered in this question.
Using before
and after
psuedo-elements with the img
tag does not work in most browsers, by design.
Image tags are self-closing (<tag />
) tags because they contain no content. Since they do not contain any content, no generated content can be appended (::after
) or prepended (::before
) to the existing content.
The article linked above lists two work-around solutions. The CSS work-around is very hackish in nature, while the jQuery solution is much more elegant, but depends on both Javascript being enabled and the jQuery library being included.
Pseudo-class ::after doesn't work on img element
Images unfortunately don't support pseudo-elements like ::after or ::before. The easiest solution would be to wrap your images inside of a div and just give the class to the div. Like so
<div class="element">
<img src="https://raw.githubusercontent.com/SAM-dev-pixel/fylo/main/img/illustration-intro.png" alt="" class="element">
</div>
This is also the case for e.g. <input>
as these tags can't contain any content.
Why CSS Pseudo Element not Working in Image
Here is how I would solve it. First you need to give the parent a position: relative
in order to move the p
tag around in the div
And then give the pseudo-element position absolute to move it around the p
tag.
.header__shape {
position: relative;
}
.header__shape-quote {
line-height: 1.3;
font-size: 3rem;
color: red;
position: absolute;
right: 30rem;
top: 40rem;
}
.header__shape-quote::before {
font-size: 4rem;
position: absolute;
top: -50px;
left: -60px;
/* must have for fontawesome */
display: inline-block;
font-style: normal;
font-variant: normal;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
font-family: "Font Awesome 5 Free";
font-weight: 900;
content: "\f10e";
}
and in a different way. And I personally recommend this one. Over the absolute in the above example. But I don't know which is better for you. So I added both
.header__shape {
position: relative;
}
.header__shape-quote {
line-height: 1.3;
font-size: 3rem;
color: red;
margin-left: 5rem;
margin-top: 5rem;
position: relative;
}
.header__shape-quote::before {
font-size: 4rem;
position: absolute;
top: -50px;
left: -60px;
/* must have for fontawesome */
display: inline-block;
font-style: normal;
font-variant: normal;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
font-family: "Font Awesome 5 Free";
font-weight: 900;
content: "\f10e";
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" integrity="sha512-1PKOgIY59xJ8Co8+NE6FZ+LOAZKjy+KY8iq0G4B3CyeY6wYHN3yt9PW0XpSriVlkMXe40PTKnXrLnZ9+fkDaog==" crossorigin="anonymous" />
<div class="header__shape">
<img src="https://picsum.photos/600" rose couples class="header__shape-img">
<p class="header__shape-quote">
Being someone’s first love may be great, <br> but to be their last is beyond perfect.
</p>
</div>
Why is '::after' pseudo-selector over the image and not under it?
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>
Pseudo element not showing background-image
the "display" property. display is CSS's most important property for controlling layout. Every element has a default display value depending on what type of element it is. The default for most elements is usually block or inline . A block element is often called a block-level element.
&::before{
content: "";
display: block;/*missing prop*/
background-image: url('/images/theseven/seven_img_old.png');
background-repeat: no-repeat;
position: relative;
height: 817px;
width: 150px;
}
Why is not possible to position '::after' pseudo-selector after an image?
You need to add
display: block;
to your ::after
.
Because by default, pseudo-elements are inline
elements, and also img
tags are inline
as well. So they are trying to fit into the same line.
Once you make ::after
display: block
, it will fit itself in the next line and stay at the bottom of the img
tag as expected:
.test-container {
margin-left: 100px;
margin-top: 40px;
}
.test-container::after {
content: "";
display: block;
position: absolute;
height: 2px;
background-color: red;
left: 0;
right: 0;
}
<div class="test-container">
<h1>TESTE</h1>
<h2>TESTE</h2>
<img src="https://www.acmetek.com/wp-content/uploads/rapidssl-logo.png" />
</div>
Why are ::before and ::after pseudo-elements detected but not shown in Chrome?
if use position relative, chrome Taking auto width for before .if use position absolute, logo is displayed correctly.
hr.linha:before {
position: absolute;
}
Firefox not displaying :after pseudo-element
Most browsers don't support pseudo-elements on img tags.
From the spec:
Note. This specification does not fully define the interaction of
:before and :after with replaced elements (such as IMG in HTML). This
will be defined in more detail in a future specification.
See this answer for an explanation as to why.
Div with CSS content, after pseudo element is not visible
The content
property replaces all content within the element. By adding content
to a non-pseudo selector, that content will replace the ::before
and ::after
pseudo selector.
So try doing this using the content
property within the ::before
and ::after
pseudo selectors only.
.demo:before { content: url('http://placehold.it/350x150')}
.demo:after { content: 'some text'; display: block;}
<div class="demo"></div>
Related Topics
Keep Image Ratio Using Max-Width and Max-Height in Ie 11
CSS Child VS Descendent Selector
Css: A:Link VS Just a (Without the :Link Part)
CSS Solution to Hide Div After X Amount of Seconds
Css3 Animation Keep Reverting to Original State
What Is the Different Between :Host ,:Host() ,:Host-Context Selectors
Sass: How to Remove /*# Sourcemappingurl Comment
Max-Height: X% Doesn't Work on Chrome
CSS Media Query Min-Width Not Working Correctly
Why Does Firefox Render Dashed Borders Misaligned from Each Other
How to Use Multiple @Include in SCSS
Pure CSS Speech Bubble with Border
White Blur Around Image When Using CSS3 Blur Filter
Css3 Hover/Tap Doesn't Work in Mobile Browsers
Change Background from Bottom to Top on Hover