Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS content generation before or after 'input' elements [duplicate]

Tags:

html

css

People also ask

Can I use a before or after pseudo element on an input field?

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.

Why do we use :: before in CSS?

::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.

What is :: before and :: after?

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.

When would you use the :: before or :: after pseudo element in your CSS?

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)