Detectar se uma entrada possui texto usando CSS - em uma página que estou visitando e não controlo?


187

Existe uma maneira de detectar se uma entrada possui ou não texto via CSS? Eu tentei usar a :emptypseudo-classe e tentei usar [value=""], nenhuma das quais funcionou. Não consigo encontrar uma solução única para isso.

Eu imagino que isso deve ser possível, considerando que temos pseudo-classes para :checked, e :indeterminate, as quais são algo parecido.

Observe: estou fazendo isso para um estilo "Elegante" , que não pode utilizar JavaScript.

Observe também que o Stylish é usado, no lado do cliente, em páginas que o usuário não controla.


Não tenho certeza de uma maneira de fazê-lo com CSS (que não é atualizado em tempo real). Isso é fácil com JavaScript, no entanto.
ralph.m

Eu não acho que posso usar JavaScript. Estou trabalhando em um estilo "estiloso". Certamente isso deve ser feito inteiramente com CSS. Se não for atualizado quando o usuário digitar o texto, acho que é uma perda de tempo. Não pensei nisso. Hmm. Pelo menos isso não é crítico para o estilo, é apenas uma delicadeza que eu esperava acrescentar.
JacobTheDev

Respostas:


66

Elegante não pode fazer isso porque CSS não pode fazer isso. O CSS não possui (pseudo) seletores para <input>valor (es). Vejo:

O :emptyseletor refere-se apenas a nós filhos, não a valores de entrada.
[value=""] faz o trabalho; mas apenas para o estado inicial . Isso ocorre porque o value atributo de um nó (que o CSS vê) não é o mesmo que a propriedade do nóvalue (Alterado pelo usuário ou pelo javascript do DOM e enviado como dados do formulário).

A menos que você se importe apenas com o estado inicial, você deve usar um userscript ou script Greasemonkey. Felizmente isso não é difícil. O script a seguir funcionará no Chrome ou Firefox com o Greasemonkey ou Scriptish instalado ou em qualquer navegador que suporte scripts de usuários (ou seja, a maioria dos navegadores, exceto o IE).

Veja uma demonstração dos limites do CSS mais a solução javascript nesta 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";
}

Vou dar uma olhada nessa coisa do userscript. Obrigado.
JacobTheDev

@MartinGottweis, não no caso do OP, não. Esta é uma pergunta [elegante] .
Brock Adams

1
@BrockAdams, op está dizendo que não pode usar javascript, então a opção: valid é um caminho a percorrer. Estou esquecendo de algo?
Martin Gottweis

1
@MartinGottweis, a :validopção requer reescrever a página - que é algo que o OP não pode fazer com elegante e que nenhuma das outras respostas mostrar a todos em um contexto de navegação. O usuário não tem controle sobre a página que está visitando.
Brock Adams

265

É possível, com as ressalvas usuais de CSS e se o código HTML pode ser modificado. Se você adicionar o requiredatributo ao elemento, o elemento corresponderá :invalidou :validse o valor do controle está vazio ou não. Se o elemento não tivervalue atributo (ou tem value=""), o valor do controle está inicialmente vazio e fica vazio quando qualquer caractere (mesmo um espaço) é inserido.

Exemplo:

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

As pseudo-classificadas :valide:invalid são definidas apenas nos documentos CSS do nível Working Draft, mas o suporte é bastante difundido nos navegadores, exceto que no IE, ele veio com o IE 10.

Se você deseja tornar “vazio” incluir valores que consistem apenas em espaços, é possível adicionar o atributo pattern=.*\S.* .

Atualmente, não existe um seletor de CSS para detectar diretamente se um controle de entrada tem um valor não vazio; portanto, precisamos fazê-lo indiretamente, conforme descrito acima.

Geralmente, os seletores de CSS se referem à marcação ou, em alguns casos, às propriedades do elemento definidas com scripts (JavaScript do lado do cliente), em vez de ações do usuário. Por exemplo, :emptycombina elemento com conteúdo vazio na marcação; todos os inputelementos são inevitavelmente vazios nesse sentido. O seletor [value=""]testa se o elemento tem o valueatributo na marcação e tem a cadeia vazia como seu valor. E :checkede :indeterminatesão coisas semelhantes. Eles não são afetados pela entrada real do usuário.


7
Essa é uma ótima solução, se e somente se todas as entradas forem necessárias - caso contrário, você se depara com uma situação em que possui um campo de entrada vazio, mas válido, não afetado pelo estilo inválido . JS é provavelmente o vencedor para esta solução
AdamSchuld

7
isso é sujo, mas maravilhosamente inteligente. Não uma solução para a questão, mas com certeza fez o truque para mim
Jan

1
Solução suja. Observe que isso pode causar problemas com o preenchimento automático no Chrome se você tentar adicionar lógica de exibição rótulo com base nesta ou se a entrada na verdade não é necessária e forma baseou validação sobre este
Artjom Kurapov

1
Semanticamente, isso está errado. Conforme mencionado nos comentários anteriores, algumas entradas podem ser opcionais e o requiredatributo pode impedir o envio do formulário.
Zhenming 10/04

1
Adicionado novalidateatributo no <form>elemento para que não se preocupe com a exibição vermelha quando o campo estiver vazio depois de preenchido uma vez:<form ... novalidate> <input ... required /> </form>
Alcalyn 28/19

228

Você pode usar a :placeholder-shownpseudo classe. Tecnicamente, é necessário um espaço reservado, mas você pode usar um espaço.

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=" " />


10
Infelizmente, isso não é suportado pelo IE ou Firefox. Fonte: caniuse.com/#feat=css-placeholder-shown
Sean Dawson

2
Resposta incrível. O suporte ao navegador é péssimo, mas se um polyfill for lançado :placeholder-shown, essa deverá se tornar a resposta aceita. O requiredmétodo não leva em consideração os casos adicionais. Note-se que você pode passar um espaço para um espaço reservado e esse método ainda funcionará. Parabéns.
corysimmons

5
A outra desvantagem disso é que você parece ter realmente um espaço reservado. Em outras palavras, input:not(:placeholder-shown)sempre corresponderá <input/>mesmo que não haja valor.
redbmk

5
Para mim, funciona no Chrome, Firefox e Safari. Não no IE11.
J0ANMM 03/03

1
@redbmk como os córsomos mencionados, note que você pode passar um espaço para um espaço reservado e esse método ainda funcionará.
Naim Baghi

32
<input onkeyup="this.setAttribute('value', this.value);" />

e

input[value=""]

vai funcionar :-)

edit: http://jsfiddle.net/XwZR2/


24
Isso é CSS? Parece HTML e Javascript (mas posso estar enganado).
JWW

Brook Adams escreveu: [value = ""] funciona; mas apenas para o estado inicial. Isso ocorre porque o atributo value do nó (que o CSS vê) não é o mesmo que a propriedade value do nó (Alterado pelo usuário ou pelo javascript DOM e enviado como dados do formulário). -> A magia é atualizar o atributo de valor sobre as mudanças: jsfiddle.net/XwZR2
Tom D.

2
@ JánosWeisz não, não vai. Esse manipulador será definido antes que um script possa manipular esse elemento e possa trabalhar junto com o manipulador adicionado com addEventListener.
Dinoboff 27/03

1
Obviamente, o onkeyup cuida apenas da entrada do teclado. Não esqueça, no entanto, que você pode colar texto em uma caixa de entrada usando o mouse. Experimente: copie algum texto na área de transferência e clique com o botão direito do mouse na entrada e clique em Colar. Veja o CSS NÃO funcionando. O mesmo ocorre com o texto arrastar e soltar na caixa de entrada com o mouse.
precisa

4
input[value]:not([value=""])- é melhor. Obrigado a todos. codepen.io/iegik/pen/ObZpqo
iegik

30

Basicamente, o que todo mundo está procurando é:

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;}

1
Você claramente acabou de usar a solução de trabalho e possui 0 WaT de votos positivos?
ProNOOB

5
Resposta incrível. A pseudo-classe: placeholder-mostrado não funciona no IE ou Edge, portanto, não é uma solução completa. É bem perto, no entanto, e isso me faz querer matar Edge por não apoiá-lo. Ou seja, eu poderia aceitar, mas Edge? Vamos Microsoft!
Aaron Martin-Colby

2
Não é uma solução css puro se você tem que adicionar "necessária" para o seu html
user1566694

Obrigado, senhor, espero sinceramente que isso fique mais alto, pois, na minha opinião, é isso que a maioria das pessoas realmente deseja.
sivi911

19

Você pode usar o placeholdertruque conforme escrito acima sem o requiredcampo.

O problema requiredé que, quando você escreveu algo e o excluiu - a entrada agora será sempre vermelha como parte da especificação HTML5 -, você precisará de um CSS conforme descrito acima para corrigi-lo / substituí-lo.

Você pode fazer coisas simples sem 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;
}

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


1
Essa abordagem foi perfeita para o meu caso de uso. Eu tinha filtros de pesquisa que tinham espaços reservados de qualquer maneira e queria que a borda da caixa de entrada fosse destacada quando um valor estivesse presente.
Stephen Tuttlebee 28/11/19

9

CSS simples:

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

Este código aplicará o css fornecido no carregamento da página se a entrada estiver preenchida.


9
Isso funciona apenas no carregamento da página. Não é dinâmico digitando um valor.
Ben Racicot

O problema de carregamento da página deve ser explicitamente anotado para esta resposta.
Bryce Snyder

6

Você pode definir input[type=text]um estilo diferente, dependendo de a entrada ter ou não texto estilizando o espaço reservado. Este não é um padrão oficial neste momento, mas possui amplo suporte ao navegador, embora com prefixos diferentes:

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;
}

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


Para sua informação, isso formata o marcador de posição com segurança, mas apenas o marcador de posição em si. Isso fornece uma ilusão de alterar a cor do texto, mas esse já é o caso, apenas com cinza e preto por padrão.
John Weisz

Todos CSS é uma ilusão barato, você só mudar aparências sem afetar o conteúdo real :-)
vbraun

Isso é exatamente o que eu precisava. Eu exigi que a entrada alterasse os estilos se houvesse texto, pois o design do espaço reservado difere do estilo de entrada. Perfeito!
Christopher Marshall

Isso funciona para planos de fundo, mas não para fronteiras. Eu não me esforcei demais para tentar mudar a fronteira.
Majinnaibu 2/06

5

Usando JS e CSS: não pseudoclasse

 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="" />

   


3

O seletor válido fará o truque.

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

.myText {
    //default style of input
}
.myText:valid {
    //style when input has text
}

3

Você pode aproveitar o espaço reservado e usar:

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

1

Truque simples com jQuery e CSS Assim:

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;
    }

1

faça-o na parte HTML assim:

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

O parâmetro necessário exigirá que haja texto no campo de entrada para ser válido.


Isso não ajuda a detectar se a entrada contém texto com CSS, que era a questão.
Jukka K. Korpela 06/06/2013

Desculpe, na verdade ajuda ... Torna possível usar pseudo-classes, conforme explicado na minha resposta.
Jukka K. Korpela 06/06/2013

1
Esta é uma pergunta elegante - o que significa que o OP não pode controlar ou alterar a página de destino. Ele vê apenas a página do lado do cliente.
Brock Adams

3
Este foi super útil, aqui está um exemplo do que Xedret está falando: codepen.io/tolmark12/pen/LsBvf
tolmark

****** <input required> && input: valid {...} ******
FremyCompany

0

Sim! você pode fazer isso com atributo básico simples com seletor de valor.

Use o seletor de atributos com valor em branco e aplique propriedades input[value='']

input[value=''] {
    background: red;
}

-6

Isso não é possível com o css. Para implementar isso, você precisará usar JavaScript (por exemplo $("#input").val() == "").


2
Eu sei como fazer isso, eu preciso fazê-lo com CSS. Por favor, leia os comentários no post original. Estou construindo um estilo "Elegante", que não pode utilizar JavaScript, que eu saiba.
9789 JacobinaDev #
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.