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.