I am trying to use the :after
CSS pseudo-element on an input
field, but it does not work. If I use it with a span
, it works OK.
<style type="text/css">
.mystyle:after {content:url(smiley.gif);}
.mystyle {color:red;}
</style>
This works (puts the smiley after "buu!" and before "some more")
<span class="mystyle">buuu!</span>a some more
This does not work - it only colors someValue in red, but there is no smiley.
<input class="mystyle" type="text" value="someValue">
What am I doing wrong? should I use another pseudo-selector?
Note: I cannot add a span
around my input
, because it is being generated by a third-party control.
try next:
As others explained,
input
s are kinda-replaced void elements, so most browsers won't allow you to generate::before
nor::after
pseudo-elements in them.However, the CSS Working Group is considering explicitly allowing
::before
and::after
in case theinput
hasappearance: none
.From https://lists.w3.org/Archives/Public/www-style/2016Mar/0190.html,
I found this post as I was having the same issue, this was the solution that worked for me. As opposed to replacing the input's value just remove it and absolutely position a span behind it that is the same size, the span can have a
:before
pseudo class applied to it with the icon font of your choice.:before
and:after
are applied inside a container, which means you can use it for elements with an end tag.On a side note, elements which are self-closing (such as img/hr/input) are also known as 'Replaced Elements', as they are replaced with their respective content. "External Objects" for the lack of a better term. A better read here
According to a note in the CSS 2.1 spec, the 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.” Although
input
is not really a replaced element any more, the basic situation has not changed: the effect of:before
and:after
on it in unspecified and generally has no effect.The solution is to find a different approach to the problem you are trying to address this way. Putting generated content into a text input control would be very misleading: to the user, it would appear to be part of the initial value in the control, but it cannot be modified – so it would appear to be something forced at the start of the control, but yet it would not be submitted as part of form data.
:before
and:after
render inside a containerand <input> can not contain other elements.
Pseudo-elements can only be defined (or better said are only supported) on container elements. Because the way they are rendered is within the container itself as a child element.
input
can not contain other elements hence they're not supported. Abutton
on the other hand that's also a form element supports them, because it's a container of other sub-elements.If you ask me, if some browser does display these two pseudo-elements on non-container elements, it's a bug and a non-standard conformance. Specification directly talks about element content...
W3C specification
If we carefully read the specification it actually says that they are inserted inside a containing element:
See? an element's document tree content. As I understand it this means within a container.