CSS content generation before or after 'input' elements
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.
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).