The input element has no content in the CSS view, and so has no :before or :after pseudo content. This is true of many other void or replaced elements. There is no pseudo element referring to outside the element.
::before (:before) In CSS, ::before creates a pseudo-element that is the first child of the selected element. It is often used to add cosmetic content to an element with the content property. It is inline by default.
Definition and UsageThe ::before selector inserts something before the content of each selected element(s). Use the content property to specify the content to insert. Use the ::after selector to insert something after the content.
Special welcome offer: get $100 of free credit. CSS ::before and ::after pseudo-elements allow you to insert “content” before and after any non-replaced element (e.g. they work on a <div> but not an <input> ). This effectively allows you to show something on a web page that might not be present in the HTML content.
With :before
and :after
you specify which content should be inserted before (or after) the content inside of that element. input
elements have no content.
E.g. if you write <input type="text">Test</input>
(which is wrong) the browser will correct this and put the text after the input element.
The only thing you could do is to wrap every input element in a span or div and apply the CSS on these.
See the examples in the specification:
For example, the following document fragment and style sheet:
<h2> Header </h2> h2 { display: run-in; } <p> Text </p> p:before { display: block; content: 'Some'; }
...would render in exactly the same way as the following document fragment and style sheet:
<h2> Header </h2> h2 { display: run-in; } <p><span>Some</span> Text </p> span { display: block }
This is the same reason why it does not work for <br>
, <img>
, etc. (<textarea>
seems to be special).
This is not due to input
tags not having any content per-se, but that their content is outside the scope of CSS.
input
elements are a special type called replaced elements
, these do not support :pseudo
selectors like :before
and :after
.
In CSS, a replaced element is an element whose representation is outside the scope of CSS. These are kind of external objects whose representation is independent of the CSS. Typical replaced elements are
<img>
,<object>
,<video>
or form elements like<textarea>
and<input>
. Some elements, like<audio>
or<canvas>
are replaced elements only in specific cases. Objects inserted using the CSS content properties are anonymous replaced elements.
Note that this is even referred to in the spec:
This specification does not fully define the interaction of
:before
and:after
with replaced elements (such as IMG in HTML).
And more explicitly:
Replaced elements do not have
::before
and::after
pseudo-elements
Something like this works:
input + label::after {
content: 'click my input';
color: black;
}
input:focus + label::after {
content: 'not valid yet';
color: red;
}
input:valid + label::after {
content: 'looks good';
color: green;
}
<input id="input" type="number" required />
<label for="input"></label>
Then add some floats or positioning to order stuff.
fyi <form>
supports :before
/ :after
as well, might be of help if you wrap your <input>
element with it... (got myself a design issue with that too)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With