Why don't :before and :after pseudo elements work with `img` elements?
The spec says...
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.
I guess this means they don't work with img
elements (for now).
Also see this answer.
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 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 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>
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.
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>
why a div can accept before and after selector but an img tag can not?
The ::before
and ::after
psuedo-elements appear at the start and end of the content of the element.
An <img>
is a replaced element, it can't have any content.
Does :before not work on img elements?
Unfortunately, most browsers do not support using :after
or :before
on img tags.
http://lildude.co.uk/after-css-property-for-img-tag
However, it IS possible for you to accomplish what you need with JavaScript/jQuery. Check out this fiddle:
http://jsfiddle.net/xixonia/ahnGT/
$(function() {
$('.target').after('<img src="..." />');
});
Edit:
For the reason why this isn't supported, check out coreyward's answer.
:after pseudo selector on an image? CSS
:after
and other pseudo elements will not work with replaced elements such as img
, input
etc..
pseudo element :before or :after on an image element
This is correct. You are not able to use pseudo elements on images
Related Topics
Change Button Border Color When the Button Is Being Clicked and After
Simulate Display: Inline in React Native
How to Add Fonts to Create-React-App Based Projects
Change a Html5 Input'S Placeholder Color With Css
What Does the CSS Rule "Clear: Both" Do
How to Combine a Background-Image and Css3 Gradient on the Same Element
Is There a CSS Selector For Text Nodes
How to Get Div Height to Auto-Adjust to Background Size
How to Make a Child Div'S Width Wider Than the Parent Div Using Css
Child Inside Parent With Min-Height: 100% Not Inheriting Height
Vertical Align Center in Bootstrap 4
Font Scaling Based on Width of Container
Media Queries: How to Target Desktop, Tablet, and Mobile
Does Height and Width Not Apply to Span
How to Apply a CSS Style on Html5 Datalist Options
How to Suppress Spacing Between Paragraphs of the Same CSS Class
Background-Image in Keyframe Does Not Display in Firefox or Internet Explorer