¿Puedo usar un pseudoelemento :before o :after en un campo de entrada?
Estoy intentando utilizar el :after
pseudoelemento CSS en un input
campo, pero no funciona. Si lo uso con a span
, funciona bien.
<style type="text/css">
.mystyle:after {content:url(smiley.gif);}
.mystyle {color:red;}
</style>
Esto funciona (pone el emoticón después de "¡buu!" y antes de "algo más")
<span class="mystyle">buuu!</span>a some more
Esto no funciona: solo colorea algún valor en rojo, pero no hay ningún emoticón.
<input class="mystyle" type="text" value="someValue">
¿Qué estoy haciendo mal? ¿Debería utilizar otro pseudoselector?
Nota: No puedo agregar un span
alrededor de mi input
porque lo genera un control de terceros.
:before
y :after
renderizar dentro de un contenedor
y <input> no puede contener otros elementos.
Los pseudoelementos solo se pueden definir (o mejor dicho, solo se admiten) en elementos contenedores. Porque la forma en que se representan es dentro del propio contenedor como un elemento secundario. input
no puede contener otros elementos, por lo que no son compatibles. A, button
por otro lado, también es un elemento de formulario que los admite, porque es un contenedor de otros subelementos.
Si me preguntas, si algún navegador muestra estos dos pseudoelementos en elementos que no son contenedores, es un error y una conformidad no estándar. La especificación habla directamente sobre el contenido del elemento...
especificación W3C
Si leemos atentamente la especificación, en realidad dice que se insertan dentro de un elemento contenedor:
Los autores especifican el estilo y la ubicación del contenido generado con los pseudoelementos :before y :after. Como sus nombres lo indican, los pseudoelementos :before y :after especifican la ubicación del contenido antes y después del contenido del árbol de documentos de un elemento. La propiedad 'contenido', junto con estos pseudoelementos, especifica lo que se inserta.
¿Ver? contenido del árbol de documentos de un elemento . Según tengo entendido, esto significa dentro de un contenedor.
:after
y :before
no son compatibles con Internet Explorer 7 y versiones anteriores, en ningún elemento.
Tampoco está diseñado para usarse en elementos reemplazados, como elementos de formulario (entradas) y elementos de imagen .
En otras palabras, es imposible con CSS puro.
Sin embargo, si usas jquery puedes usar
$(".mystyle").after("add your smiley here");
Documentos API en .after
Para agregar su contenido con javascript. Esto funcionará en todos los navegadores.
Curiosamente, funciona con algunos tipos de entrada. Al menos en Chrome,
<input type="checkbox" />
funciona bien, igual que
<input type="radio" />
Es sólo type=text
y algunos otros que no funcionan.
Aquí hay otro enfoque (suponiendo que tenga control del HTML): agregue un espacio vacío <span></span>
justo después de la entrada y apunte a eso en CSS usandoinput.mystyle + span:after
.field_with_errors {
display: inline;
color: red;
}
.field_with_errors input+span:after {
content: "*"
}
<div class="field_with_errors">Label:</div>
<div class="field_with_errors">
<input type="text" /><span></span>
</div>
Estoy usando este enfoque en AngularJS porque agregará .ng-invalid
clases automáticamente a <input>
los elementos del formulario y al formulario, pero no al archivo <label>
.
:before
y :after
se aplican dentro de un contenedor, lo que significa que puede usarlo para elementos con una etiqueta final.
No aplica para elementos de cierre automático.
Como nota al margen, los elementos que se cierran automáticamente (como img/hr/input) también se conocen como "Elementos reemplazados", ya que se reemplazan con su contenido respectivo. "Objetos externos" a falta de un término mejor. Una mejor lectura aquí.