¿Puedo usar un: antes o después del pseudo-elemento en un campo de entrada?

Estoy tratando de usar :after pseudo-elemento CSS en un campo de input , pero no funciona. Si lo uso con un span , funciona bien.

  .mystyle:after {content:url(smiley.gif);} .mystyle {color:red;}  

Esto funciona (pone el emoticono después de “buu!” Y antes de “un poco más”)

 buuu!a some more 

Esto no funciona, solo colorea algunos valores en rojo, pero no hay emoticones.

  

¿Qué estoy haciendo mal? ¿Debería usar otro pseudo-selector?

Nota: No puedo agregar un span alrededor de mi input , porque está siendo generado por un control de un tercero.

:after y :before no son compatibles con Internet Explorer 7 y versiones anteriores, en ningún elemento.

Tampoco está destinado a ser utilizado en elementos reemplazados, como elementos de formulario (entradas) y elementos de imagen .

En otras palabras, es imposible con CSS puro.

Sin embargo, si usa jquery puede usar

 $(".mystyle").after("add your smiley here"); 

Docs de API en .after

Para agregar su contenido con javascript. Esto funcionará en todos los navegadores.

:before y :after render dentro de un contenedor

y no puede contener otros elementos.


Los pseudo-elementos solo se pueden definir (o mejor dicho solo son compatibles) en elementos de contenedor. Porque la forma en que se representan está dentro del contenedor como un elemento secundario. input no puede contener otros elementos, por lo tanto, no son compatibles. Por otro lado, un button que también es un elemento de formulario 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 cuidadosamente las especificaciones, en realidad dice que están insertadas dentro de un elemento contenedor:

Los autores especifican el estilo y la ubicación del contenido generado con los pseudo-elementos: before y: after. Como indican sus nombres, los pseudo-elementos: 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 pseudo-elementos, especifica qué se inserta.

¿Ver? el contenido del árbol de documentos de un elemento . Según entiendo, esto significa dentro de un contenedor.

Curiosamente, funciona con algunos tipos de entrada. Al menos en Chrome,

  

funciona bien, lo mismo que

  

Es solo type=text y algunos otros que no funcionan.

Aquí hay otro enfoque (suponiendo que tenga el control del HTML): agregue un vacío justo después de la entrada, y input.mystyle + span:after en CSS usando input.mystyle + span:after

 .field_with_errors { display: inline; color: red; } .field_with_errors input+span:after { content: "*" } 
 
Label:

:before y :after se aplican dentro de un contenedor, lo que significa que puede usarlo para elementos con una etiqueta de cierre.

No se aplica a elementos de cierre automático.

En una nota lateral, los elementos que se cierran automáticamente (como img / hr / input) también se conocen como ‘Elementos reemplazados’, ya que se reemplazan por sus respectivos contenidos. “Objetos externos” por la falta de un término mejor. Una mejor lectura aquí

Usé la background-image para crear el punto rojo para los campos obligatorios.

 input[type="text"][required] { background-image: radial-gradient(red 15%, transparent 16%); background-size: 1em 1em; background-position: top right; background-repeat: no-repeat } 

Ver en Codepen

No puede poner un pseudo elemento en un elemento de entrada, pero puede ponerlo en un elemento sombreado, ¡como un marcador de posición!

 input[type="text"] { &::-webkit-input-placeholder { &:before { // your code } } } 

Para que funcione en otros navegadores, use :-moz-placeholder , ::-moz-placeholder y :-ms-input-placeholder en diferentes selectores . No se pueden agrupar los selectores porque, si el navegador no reconoce, el selector invalida la statement completa.

ACTUALIZACIÓN : El código anterior funciona solo con preprocesador CSS (SASS, LESS …), sin uso de preprocesadores:

 input[type="text"]::-webkit-input-placeholder:before { // your code } 

Encontré esta publicación porque tenía el mismo problema, esta fue la solución que funcionó para mí. A diferencia de reemplazar el valor de la entrada simplemente elimínelo y coloque un tramo detrás de él que tenga el mismo tamaño, el tramo puede tener una :before aplique una pseudo clase con la fuente del icono de su elección.

  

Los pseudo elementos como :after :before son solo para elementos de contenedor. Los elementos que comienzan y cierran en un solo lugar como , etc. no son elementos contenedores y, por lo tanto, los pseudo elementos no son compatibles. Una vez que aplica un pseudo elemento al elemento contenedor como

y si inspecciona el código (ver la imagen) puede entender lo que quiero decir. En realidad, el pseudo elemento se crea dentro del elemento contenedor. Esto no es posible en el caso de o

enter image description here

De acuerdo con una nota en la especificación CSS 2.1, la especificación “no define completamente la interacción de: before y: after con elementos reemplazados (como IMG en HTML). Esto se definirá con más detalle en una futura especificación. “Aunque la input ya no es realmente un elemento reemplazado, la situación básica no ha cambiado: el efecto de :before y :after de no especificado y generalmente no tiene efecto.

La solución es encontrar un enfoque diferente para el problema que está intentando abordar de esta manera. Poner el contenido generado en un control de entrada de texto sería muy engañoso: para el usuario, parecería ser parte del valor inicial en el control, pero no se puede modificar, por lo que parecería ser algo forzado al inicio del proceso. control, pero aún no se enviaría como parte de los datos del formulario.

Como otros explicaron, las input s son elementos vacíos poco reemplazados, por lo que la mayoría de los navegadores no le permitirán generar ::before ni ::after pseudo-elements en ellos.

Sin embargo, el grupo de trabajo de CSS está considerando explícitamente permitir ::before y ::after en caso de que la input tenga appearance: none .

De https://lists.w3.org/Archives/Public/www-style/2016Mar/0190.html ,

Safari y Chrome permiten pseudoelementos en sus entradas de formulario. Otros navegadores no. Buscamos eliminar esto, pero el contador de uso registra ~ .07% de las páginas que lo usan, que es 20 veces nuestro umbral máximo de eliminación.

En realidad, especificar los pseudoelementos en las entradas requeriría especificar al menos la estructura interna de las entradas, algo que aún no logramos (y no estoy seguro de que * podamos * hacerlo). Pero Boris sugirió, en uno de los hilos de error, permitirlo en apariencia: ninguna entrada, básicamente convirtiéndola en elementos

s, en lugar de elementos “un poco reemplazados”.

Una solución de trabajo en CSS puro:

El truco es suponer que hay un elemento dom después del campo de texto.

 /* * The trick is here: * this selector says "take the first dom element after * the input text (+) and set its before content to the * value (:before). */ input#myTextField + *:before { content: "👍"; } 
    

Debe tener algún tipo de envoltorio alrededor de la entrada para usar un pseudo-elemento antes o después. Aquí hay un violín que tiene un antes en el envoltorio div de una entrada y luego coloca el antes dentro de la entrada, o al menos así lo parece. Obviamente, este es un trabajo de alrededor, pero efectivo en un apuro y se presta a ser receptivo. Puedes hacer esto fácilmente si necesitas poner algún otro contenido.

Fiddle de trabajo

Signo de dólar dentro de una entrada como un pseudo-elemento: http://jsfiddle.net/kapunahele/ose4r8uj/1/

El HTML:

 

El CSS:

 input { margin: 3em; padding-left: 2em; padding-top: 1em; padding-bottom: 1em; width:20%; } .test { position: relative; background-color: #dedede; display: inline; } .test:before { content: '$'; position: absolute; top: 0; left: 40px; z-index: 1; } 

prueba a continuación:

 label[for="userName"] { position: relative; } label[for="userName"]::after { content: '[after]'; width: 22px; height: 22px; display: inline-block; position: absolute; right: -30px; } 
  

Si intentas diseñar un elemento de entrada con: before y: after, lo más probable es que intentes imitar los efectos de otros span, div o incluso elementos en tu stack de CSS.

Como señala la respuesta de Robert Koritnik,: before y: after solo se puede aplicar a los elementos del contenedor y los elementos de entrada no son contenedores.

SIN EMBARGO, HTML 5 introdujo el elemento de botón que es un contenedor y se comporta como un elemento de entrada [type = “submit | reset”].

   

Resumen

No funciona con , pero funciona bien con .

Fiddle : http://jsfiddle.net/gb2wY/50/

HTML :

 



CSS :

 #submit-button::before, #submit-cb::before { content: ' '; background: transparent; border: 3px solid crimson; display: inline-block; width: 100%; height: 100%; padding: 0; margin: -3px -3px; } 

:before y :after funciona solo para nodos que pueden tener nodos secundarios ya que insertan un nuevo nodo como primer o último nodo.

Descubrí que puedes hacerlo así:

 .submit .btn input { padding:11px 28px 12px 14px; background:#004990; border:none; color:#fff; } .submit .btn { border:none; color:#fff; font-family: 'Open Sans', sans-serif; font-size:1em; min-width:96px; display:inline-block; position:relative; } .submit .btn:after { content:">"; width:6px; height:17px; position:absolute; right:36px; color:#fff; top:7px; } 
 

Puede usar después o antes del elemento en su bloque padre con jQuery. Me gusta esto:

 $(yourInput).parent().addClass("error-form-field");