CSS content generation before or after 'input' elements
HtmlCssHtml Problem Overview
In Firefox 3 and Google Chrome 8.0 the following works as expected:
<style type="text/css">
span:before { content: 'span: '; }
</style>
<span>Test</span> <!-- produces: "span: Test" -->
But it doesn't when the element is <input>
:
<style type="text/css">
input:before { content: 'input: '; }
</style>
<input type="text"></input> <!-- produces only the textbox; the generated content
is nowhere to be seen in both FF3 and Chrome 8 -->
Why is it not working like I expected?
Html Solutions
Solution 1 - Html
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 { display: run-in; } Header
Text
p:before { display: block; content: 'Some'; } ...would render in exactly the same way as the following document fragment and style sheet: >h2 { display: run-in; } Header
Some Text
span { display: block }This is the same reason why it does not work for <br>
, <img>
, etc. (<textarea>
seems to be special).
Solution 2 - Html
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
Solution 3 - Html
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.
Solution 4 - Html
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)
Solution 5 - Html
Use tags label and our method for =, is bound to input. If follow the rules of the form, and avoid confusion with tags, use the following:
<style type="text/css">
label.lab:before { content: 'input: '; }
</style>
or compare (short code):
<style type="text/css">
div label { content: 'input: '; color: red; }
</style>
form....
<label class="lab" for="single"></label><input name="n" id="single" ...><label for="single"> - simle</label>
or compare (short code):
<div><label></label><input name="n" ...></div>