¿Detecta si una entrada tiene texto usando CSS - en una página que estoy visitando y no controlo?

187

¿Hay alguna manera de detectar si una entrada tiene o no texto a través de CSS? He intentado usar la :emptypseudo-clase, y he intentado usar [value=""], ninguno de los cuales funcionó. Parece que no puedo encontrar una solución única para esto.

Me imagino que esto debe ser posible, teniendo en cuenta que tenemos pseudo-clases para :checked, y :indeterminate, las cuales son algo similar.

Tenga en cuenta: estoy haciendo esto para un estilo "elegante" , que no puede utilizar JavaScript.

También tenga en cuenta que Stylish se usa, del lado del cliente, en páginas que el usuario no controla.

JacobTheDev
fuente
No estoy seguro de una manera de hacerlo con CSS (que de todos modos no se actualiza sobre la marcha). Sin embargo, esto es fácil con JavaScript.
ralph.m
No creo que pueda usar JavaScript. Estoy trabajando en un estilo "elegante". Estoy bastante seguro de que debe hacerse completamente con CSS. Si no se actualiza cuando el usuario ingresa texto, supongo que es una pérdida de tiempo. No pensé en eso. Hmm Al menos esto no es crítico para el estilo, es solo un detalle que esperaba agregar.
JacobTheDev
2
posible duplicado de : not (: empty) ¿El selector CSS no funciona?
Danny Beckett

Respuestas:

66

Elegante no puede hacer esto porque CSS no puede hacer esto. CSS no tiene (pseudo) selectores para los <input>valores. Ver:

El :emptyselector se refiere solo a nodos secundarios, no a valores de entrada.
[value=""] hace el trabajo; pero solo para el estado inicial . Esto se debe a que el value atributo de un nodo (que CSS ve) no es lo mismo que la value propiedad del nodo (modificado por el usuario o DOM javascript, y enviado como datos de formulario).

A menos que sólo se preocupan por el estado inicial, se debe utilizar un userscript o script de Greasemonkey. Afortunadamente esto no es difícil. El siguiente script funcionará en Chrome o Firefox con Greasemonkey o Scriptish instalado, o en cualquier navegador que admita scripts de usuario (es decir, la mayoría de los navegadores, excepto IE).

Vea una demostración de los límites de CSS más la solución de JavaScript en esta página jsBin .

// ==UserScript==
// @name     _Dynamically style inputs based on whether they are blank.
// @include  http://YOUR_SERVER.COM/YOUR_PATH/*
// @grant    GM_addStyle
// ==/UserScript==
/*- The @grant directive is needed to work around a design change
    introduced in GM 1.0.   It restores the sandbox.
*/

var inpsToMonitor = document.querySelectorAll (
    "form[name='JustCSS'] input[name^='inp']"
);
for (var J = inpsToMonitor.length - 1;  J >= 0;  --J) {
    inpsToMonitor[J].addEventListener ("change",    adjustStyling, false);
    inpsToMonitor[J].addEventListener ("keyup",     adjustStyling, false);
    inpsToMonitor[J].addEventListener ("focus",     adjustStyling, false);
    inpsToMonitor[J].addEventListener ("blur",      adjustStyling, false);
    inpsToMonitor[J].addEventListener ("mousedown", adjustStyling, false);

    //-- Initial update. note that IE support is NOT needed.
    var evt = document.createEvent ("HTMLEvents");
    evt.initEvent ("change", false, true);
    inpsToMonitor[J].dispatchEvent (evt);
}

function adjustStyling (zEvent) {
    var inpVal  = zEvent.target.value;
    if (inpVal  &&  inpVal.replace (/^\s+|\s+$/g, "") )
        zEvent.target.style.background = "lime";
    else
        zEvent.target.style.background = "inherit";
}
Brock Adams
fuente
Me ocuparé de esa cosa del script de usuario. Gracias.
JacobTheDev
@MartinGottweis, no en el caso del OP, no lo hace. Esta es una pregunta [elegante] .
Brock Adams
1
@BrockAdams, op está diciendo que no puede usar javascript, por lo que la opción válida es un camino a seguir. ¿Me estoy perdiendo de algo?
Martin Gottweis
1
@MartinGottweis, la :validopción requiere reescribir la página, que es algo que el OP no puede hacer con estilo y que ninguna de las otras respuestas muestra en absoluto en un contexto de navegación. El usuario no tiene control sobre la página que está visitando.
Brock Adams
265

Es posible, con las advertencias habituales de CSS y si se puede modificar el código HTML. Si agrega el requiredatributo al elemento, el elemento coincidirá :invalido :validsegún si el valor del control está vacío o no. Si el elemento no tiene ningún valueatributo (o lo tiene value=""), el valor del control está inicialmente vacío y deja de estar vacío cuando se ingresa cualquier carácter (incluso un espacio).

Ejemplo:

<style>
#foo { background: yellow; }
#foo:valid { outline: solid blue 2px; }
#foo:invalid { outline: solid red 2px; }
</style>
<input id=foo required>

Los pseudo-clasificados :validy :invalidse definen solo en documentos CSS de nivel Working Draft, pero el soporte está bastante extendido en los navegadores, excepto que en IE, vino con IE 10.

Si desea que los valores de inclusión "vacíos" incluyan solo espacios, puede agregar el atributo pattern=.*\S.*.

No existe (actualmente) un selector CSS para detectar directamente si un control de entrada tiene un valor no vacío, por lo que debemos hacerlo indirectamente, como se describió anteriormente.

En general, los selectores CSS se refieren al marcado o, en algunos casos, a las propiedades de los elementos configurados con secuencias de comandos (JavaScript del lado del cliente), en lugar de las acciones del usuario. Por ejemplo, :emptycoincide con el elemento con contenido vacío en el marcado; Todos los inputelementos están inevitablemente vacíos en este sentido. El selector [value=""]prueba si el elemento tiene el valueatributo en marcado y tiene la cadena vacía como su valor. Y :checkedya :indeterminateson cosas similares. No se ven afectados por la entrada real del usuario.

Jukka K. Korpela
fuente
77
Esta es una gran solución si y solo si se requieren todas las entradas; de lo contrario, se encuentra con una situación en la que tiene un campo de entrada vacío pero válido que no se ve afectado por el estilo no válido . JS es probablemente el ganador de esta solución
AdamSchuld
77
Esto es sucio pero maravillosamente inteligente. No es una solución a la pregunta, pero seguro que me funcionó
Jan
1
Solución sucia Tenga en cuenta que esto puede causar problemas con el autocompletado en Chrome si intenta agregar una lógica de visualización de etiquetas basada en esto O si la entrada no es realmente necesaria y el formulario tiene una validación basada en esto
Artjom Kurapov
1
Semánticamente esto está mal. Como se mencionó en comentarios anteriores, algunas entradas pueden ser opcionales y el requiredatributo puede evitar el envío de formularios.
zhenming
1
Se agregó un novalidateatributo en el <form>elemento para que no se preocupe por la pantalla roja cuando el campo está vacío después de haber sido llenado una vez:<form ... novalidate> <input ... required /> </form>
Alcalyn
228

Puedes usar la :placeholder-shownpseudo clase. Técnicamente se requiere un marcador de posición, pero puede utilizar un espacio en su lugar.

input:not(:placeholder-shown) {
  border-color: green;
}

input:placeholder-shown {
  border-color: red;
}
<input placeholder="Text is required" />
<input placeholder=" " value="This one is valid" />
<input placeholder=" " />

ngryman
fuente
10
Desafortunadamente, IE o Firefox no lo admiten en absoluto. Fuente: caniuse.com/#feat=css-placeholder-shown
Sean Dawson
2
Impresionante respuesta. El soporte del navegador es una mierda, pero si sale un polyfill :placeholder-shown, esta debería ser la respuesta aceptada. El requiredmétodo no tiene en cuenta los casos marginales. Cabe señalar que puede pasar un espacio a un marcador de posición y este método seguirá funcionando. Prestigio.
corysimmons
55
La otra desventaja de esto es que parece que realmente necesitas tener un marcador de posición. En otras palabras, input:not(:placeholder-shown)siempre coincidirá <input/>incluso si no hay ningún valor.
redbmk
55
Para mí funciona en Chrome, Firefox y Safari. No en IE11.
J0ANMM
1
@redbmk como mencionó corysimmons, debe tenerse en cuenta que puede pasar un espacio a un marcador de posición y este método seguirá funcionando.
Naeem Baghi
32
<input onkeyup="this.setAttribute('value', this.value);" />

y

input[value=""]

trabajará :-)

editar: http://jsfiddle.net/XwZR2/

Tom D.
fuente
24
¿Eso es CSS? Parece HTML y Javascript (pero podría estar equivocado).
jww
Brook Adams escribió: [value = ""] funciona; pero solo para el estado inicial. Esto se debe a que el atributo de valor de un nodo (que CSS ve) no es lo mismo que la propiedad de valor del nodo (modificado por el usuario o DOM javascript, y enviado como datos de formulario). -> La magia es actualizar el atributo de valor en los cambios: jsfiddle.net/XwZR2
Tom D.
2
@ JánosWeisz no, no lo hará. Ese controlador se establecerá antes de que un script pueda manipular ese elemento y pueda funcionar junto con el controlador agregado con addEventListener.
Dinoboff
1
Obviamente, onkeyup se encarga solo de la entrada del teclado. Sin embargo, no olvide que puede pegar texto en un cuadro de entrada con el mouse. Pruébelo: copie algo de texto en su portapapeles y luego haga clic derecho en la entrada y haga clic en Pegar. Mira que el CSS NO funciona. Lo mismo con el texto de arrastrar y soltar en el cuadro de entrada con el mouse.
beluga
44
input[value]:not([value=""])- es mejor. Gracias a todos. codepen.io/iegik/pen/ObZpqo
iegik
30

Básicamente, lo que todos buscan es:

MENOS:

input:focus:required{
    &:invalid{ color: red; border-color: red; box-shadow: 0 0 6px red;}
    &:valid,
    &:placeholder-shown{ border-color: green; box-shadow: 0 0 8px green;}
}

CSS puro:

input:focus:required:invalid{ color: red; border-color: red; box-shadow: 0 0 6px red;}
input:focus:required:valid,
input:focus:required:placeholder-shown{ border-color: green; box-shadow: 0 0 8px green;}
Fábio ZC
fuente
1
Claramente acabas de dar uso de la solución de trabajo y tienes 0 votos WaT?
ProNOOB
55
Impresionante respuesta. Sin embargo, la pseudoclase mostrada por marcador de posición no funciona en IE o Edge, por lo que no es una solución completa. Sin embargo, está muy cerca, y me dan ganas de asesinar a Edge por no apoyarlo. IE podría aceptar, pero ¿Edge? Vamos Microsoft!
Aaron Martin-Colby el
2
No es una solución CSS pura si tiene que agregar "requerido" a su html
user1566694
Gracias amable señor, sinceramente espero que esto suba más, ya que en mi opinión esto es lo que la mayoría de la gente realmente quiere.
sivi911
20

Puedes usar el placeholdertruco como está escrito arriba sin requiredcampo.

El problema requiredes que cuando escribiste algo, luego lo borraste (la entrada ahora siempre será roja como parte de la especificación HTML5), entonces necesitarás un CSS como se escribió anteriormente para corregirlo / anularlo.

Usted puede hacer algo simple sin required

<input type="text" placeholder="filter here" id="mytest" />

CSS

#mytest:placeholder-shown {
/* if placeholder is shown - meaning - no value in input */
  border: black 1px solid;
  color: black;
}
#mytest {
  /* placeholder isn't shown - we have a value in input */
  border: red 1px solid;
  color: red;
}

Pluma de código: https://codepen.io/arlevi/pen/LBgXjZ

Ricky Levi
fuente
1
Este enfoque fue perfecto para mi caso de uso. Tenía filtros de búsqueda que tenían marcadores de posición de todos modos, y quería que el borde del cuadro de entrada se resaltara cuando había un valor presente.
Stephen Tuttlebee el
9

CSS simple:

input[value]:not([value=""])

Este código va a aplicar el css dado en la carga de la página si se llena la entrada.

Breno Teixeira
fuente
9
Esto solo funciona en la carga de la página. No dinámico escribiendo un valor.
Ben Racicot
El problema de carga de la página debe indicarse explícitamente para esta respuesta.
Bryce Snyder
6

Puede aplicar un estilo input[type=text]diferente dependiendo de si la entrada tiene texto o no al diseñar el marcador de posición. Este no es un estándar oficial en este momento, pero tiene un amplio soporte para el navegador, aunque con diferentes prefijos:

input[type=text] {
    color: red;
}
input[type=text]:-moz-placeholder {
    color: green;
}
input[type=text]::-moz-placeholder {
    color: green;
}
input[type=text]:-ms-input-placeholder {
    color: green;
}
input[type=text]::-webkit-input-placeholder {
    color: green;
}

Ejemplo: http://fiddlesalad.com/scss/input-placeholder-css

vbraun
fuente
Para su información, esto formatea de forma confiable el marcador de posición, pero solo el marcador de posición en sí. Esto le da la ilusión de cambiar el color del texto, pero ese ya es el caso, solo con gris y negro por defecto.
John Weisz
Todo CSS es una ilusión barata, solo cambias las apariencias sin afectar el contenido real :-)
vbraun
Esto es exactamente lo que necesitaba. Necesitaba la entrada para cambiar los estilos si tenía texto, ya que el diseño para el marcador de posición difiere del estilo de entrada. ¡Perfecto!
Christopher Marshall
Esto funciona para fondos, pero no para fronteras. Sin embargo, no profundicé demasiado en tratar de cambiar la frontera.
majinnaibu
5

Usando JS y CSS: no pseudoclase

 input {
        font-size: 13px;
        padding: 5px;
        width: 100px;
    }

    input[value=""] {
        border: 2px solid #fa0000;
    }

    input:not([value=""]) {
        border: 2px solid #fafa00;
    }
<input type="text" onkeyup="this.setAttribute('value', this.value);" value="" />

   

Pavlo Kozachuk
fuente
4

Puede aprovechar el marcador de posición y usar:

input:not(:placeholder-shown) {
  border: 1px solid red;
}
Scottyzen
fuente
3

El selector válido hará el truco.

<input type="text" class="myText" required="required" />

.myText {
    //default style of input
}
.myText:valid {
    //style when input has text
}
Niels Steenbeek
fuente
1

Truco simple con jQuery y CSS Así:

JQuery:

$('input[value=""]').addClass('empty');
        $('input').keyup(function(){
            if( $(this).val() == ""){
                $(this).addClass("empty");
            }else{
                $(this).removeClass("empty");
            }
        });

CSS:

input.empty:valid{
        box-shadow: none;
        background-image: none;
        border: 1px solid #000;
    }

    input:invalid,
    input:required {
        box-shadow: 3px 1px 5px rgba(200, 0, 0, 0.85);
        border: 1px solid rgb(200,0,0);
    }




    input:valid{
        box-shadow: none;
        border: 1px solid #0f0;
    }
Bren1818
fuente
1

hazlo en la parte HTML así:

<input type="text" name="Example" placeholder="Example" required/>

El parámetro requerido requerirá que tenga texto en el campo de entrada para que sea válido.

Xedret
fuente
Esto no ayuda a detectar si la entrada tiene texto con CSS, que era la pregunta.
Jukka K. Korpela
Lo sentimos, en realidad ayuda ... Hace posible el uso de pseudo-clases, como se explica en mi respuesta.
Jukka K. Korpela
1
Esta es una pregunta elegante , lo que significa que el OP no puede controlar o alterar la página de destino. Solo ve la página del lado del cliente.
Brock Adams
3
Esto fue súper útil, aquí hay un ejemplo de lo que está hablando Xedret : codepen.io/tolmark12/pen/LsBvf
tolmark
****** <entrada requerida> && input: válido {...} ******
FremyCompany
0

¡Si! puedes hacerlo con un atributo básico simple con selector de valor.

Use el selector de atributos con un valor en blanco y aplique propiedades input[value='']

input[value=''] {
    background: red;
}
Hidayt Rahman
fuente
-6

Esto no es posible con css. Para implementar esto, deberá usar JavaScript (por ejemplo $("#input").val() == "").

Logan
fuente
2
Sé cómo hacerlo, necesito hacerlo con CSS. Por favor, lea los comentarios en la publicación original. Estoy construyendo un estilo "elegante", que no puede utilizar JavaScript, que yo sepa.
JacobTheDev