Détecter si une entrée contient du texte en utilisant CSS - sur une page que je visite et que je ne contrôle pas?

187

Existe-t-il un moyen de détecter si une entrée contient du texte via CSS? J'ai essayé d'utiliser la :emptypseudo-classe, et j'ai essayé d'utiliser [value=""], ni l'une ni l'autre n'a fonctionné. Je n'arrive pas à trouver une solution unique à cela.

J'imagine que cela doit être possible, étant donné que nous avons des pseudo-classes pour :checkedet :indeterminate, qui sont toutes deux un peu similaires.

Remarque: je fais cela pour un style "élégant" , qui ne peut pas utiliser JavaScript.

Notez également que Stylish est utilisé, côté client, sur des pages que l'utilisateur ne contrôle pas.

JacobTheDev
la source
Je ne suis pas sûr d'un moyen de le faire avec CSS (qui ne se met pas à jour à la volée, de toute façon). Cependant, c'est facile avec JavaScript.
ralph.m
Je ne pense pas pouvoir utiliser JavaScript. Je travaille sur un style "stylé". À peu près sûr que cela doit être fait entièrement avec CSS. S'il ne se mettait pas à jour lorsque l'utilisateur saisit du texte, je suppose que c'est une sorte de perte de temps. Je n'ai pas pensé à ça. Hmm. Au moins, ce n'est pas critique pour le style, c'est juste une subtilité que j'espérais ajouter.
JacobTheDev
2
duplication possible de : not (: vide) Le sélecteur CSS ne fonctionne pas?
Danny Beckett

Réponses:

66

Stylish ne peut pas faire cela car CSS ne peut pas le faire. CSS n'a pas de (pseudo) sélecteurs pour les <input>valeurs. Voir:

Le :emptysélecteur fait uniquement référence aux nœuds enfants, pas aux valeurs d'entrée.
[value=""] fait le travail; mais seulement pour l' état initial . C'est parce que l' value attribut d' un nœud (que CSS voit), n'est pas le même que la value propriété du nœud (modifié par l'utilisateur ou le javascript DOM, et soumis en tant que données de formulaire).

Sauf si vous vous souciez uniquement de l'état initial, vous devez utiliser un script utilisateur ou un script Greasemonkey. Heureusement, ce n'est pas difficile. Le script suivant fonctionnera dans Chrome, ou Firefox avec Greasemonkey ou Scriptish installé, ou dans tout navigateur prenant en charge les scripts utilisateur (c'est-à-dire la plupart des navigateurs, à l'exception d'IE).

Voir une démo des limites du CSS et de la solution javascript sur cette page 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
la source
Je vais regarder ce truc de usercript. Merci.
JacobTheDev
@MartinGottweis, pas dans le cas du PO, ce n'est pas le cas. C'est une question [élégante] .
Brock Adams
1
@BrockAdams, op dit qu'il ne peut pas utiliser javascript, donc l'option: valid est une solution. Est-ce que je manque quelque chose?
Martin Gottweis
1
@MartinGottweis, l' :validoption nécessite la réécriture de la page - ce que l'OP ne peut pas faire avec Stylish et qu'aucune des autres réponses ne montre du tout dans un contexte de navigation. L'utilisateur n'a aucun contrôle sur la page qu'il visite.
Brock Adams
265

C'est possible, avec les mises en garde CSS habituelles et si le code HTML peut être modifié. Si vous ajoutez l' requiredattribut à l'élément, alors l'élément correspondra :invalidou :validselon que la valeur du contrôle est vide ou non. Si l'élément n'a pas d' valueattribut (ou s'il en a value=""), la valeur du contrôle est initialement vide et devient non vide lorsqu'un caractère (même un espace) est entré.

Exemple:

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

Les pseudo-classés :validet :invalidsont définis dans les documents CSS de niveau Working Draft uniquement, mais le support est assez répandu dans les navigateurs, sauf que dans IE, il est venu avec IE 10.

Si vous souhaitez que «vide» inclue des valeurs constituées uniquement d'espaces, vous pouvez ajouter l'attribut pattern=.*\S.*.

Il n'y a (actuellement) pas de sélecteur CSS pour détecter directement si un contrôle d'entrée a une valeur non vide, nous devons donc le faire indirectement, comme décrit ci-dessus.

En général, les sélecteurs CSS font référence au balisage ou, dans certains cas, aux propriétés d'élément définies avec le script (JavaScript côté client), plutôt qu'aux actions de l'utilisateur. Par exemple, :emptycorrespond à un élément avec un contenu vide dans le balisage; tous les inputéléments sont inévitablement vides en ce sens. Le sélecteur [value=""]teste si l'élément a l' valueattribut dans le balisage et la chaîne vide comme valeur. Et :checkedet :indeterminatesont des choses similaires. Ils ne sont pas affectés par l'entrée réelle de l'utilisateur.

Jukka K. Korpela
la source
7
C'est une excellente solution si et seulement si chaque entrée est requise - sinon, vous vous trouvez dans une situation où vous avez un champ d'entrée vide mais valide non affecté par le style invalide . JS est probablement le gagnant pour cette solution
AdamSchuld
7
c'est sale mais merveilleusement intelligent. Ce n'est pas une solution à la question, mais cela a certainement fait l'affaire pour moi
janvier
1
Solution sale. Notez que cela peut causer des problèmes avec la saisie semi-automatique dans Chrome si vous essayez d'ajouter une logique d'affichage d'étiquette basée sur cette OU si l'entrée n'est pas réellement requise et que le formulaire a une validation basée sur cela
Artjom Kurapov
1
Sémantiquement, c'est faux. Comme mentionné dans les commentaires précédents, certaines entrées peuvent être facultatives et l' requiredattribut peut empêcher la soumission du formulaire.
zhenming
1
Ajout d'un novalidateattribut sur l' <form>élément pour ne pas vous soucier de l'affichage rouge lorsque le champ est vide après avoir été rempli une fois:<form ... novalidate> <input ... required /> </form>
Alcalyn
228

Vous pouvez utiliser la :placeholder-shownpseudo classe. Techniquement, un espace réservé est requis, mais vous pouvez utiliser un espace à la place.

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
la source
10
Ceci n'est malheureusement pas du tout pris en charge par IE ou Firefox. Source: caniuse.com/#feat=css-placeholder-shown
Sean Dawson
2
Réponse géniale. Le support du navigateur est nul, mais si un polyfill sort, :placeholder-showncela devrait devenir la réponse acceptée. La requiredméthode ne prend pas en compte les cas marginaux. Il convient de noter que vous pouvez passer un espace à un espace réservé et cette méthode fonctionnera toujours. Gloire.
corysimmons
5
L'autre inconvénient est que vous semblez avoir besoin d'un espace réservé. En d'autres termes, input:not(:placeholder-shown)correspondra toujours <input/>même s'il n'y a pas de valeur.
redbmk le
5
Pour moi, cela fonctionne dans Chrome, Firefox et Safari. Pas dans IE11.
J0ANMM
1
@redbmk comme corysimmons mentionné, il convient de noter que vous pouvez passer un espace à un espace réservé et cette méthode fonctionnera toujours.
Naeem Baghi
32
<input onkeyup="this.setAttribute('value', this.value);" />

et

input[value=""]

marchera :-)

modifier: http://jsfiddle.net/XwZR2/

Tom D.
la source
24
Est-ce que c'est CSS? Cela ressemble à du HTML et du Javascript (mais je peux me tromper).
jww
Brook Adams a écrit: [value = ""] fonctionne; mais seulement pour l'état initial. En effet, l'attribut de valeur d'un nœud (que voit CSS) n'est pas le même que la propriété de valeur du nœud (modifié par l'utilisateur ou le javascript DOM, et soumis en tant que données de formulaire). -> La magie est de mettre à jour l'attribut value sur les changements: jsfiddle.net/XwZR2
Tom D.
2
@ JánosWeisz non, ce ne sera pas le cas. Ce gestionnaire sera défini avant qu'un script puisse manipuler cet élément et il peut fonctionner avec le gestionnaire ajouté avec addEventListener.
Dinoboff
1
De toute évidence, onkeyup ne prend en charge que la saisie au clavier. N'oubliez pas, cependant, que vous pouvez coller du texte dans une zone de saisie à l'aide de votre souris. Essayez-le: copiez du texte dans votre presse-papiers, puis cliquez avec le bouton droit sur l'entrée et cliquez sur Coller. Regardez le CSS ne fonctionne pas. Idem avec le glisser-déposer de texte dans la zone de saisie avec votre souris.
beluga
4
input[value]:not([value=""])- est mieux. Merci à tous. codepen.io/iegik/pen/ObZpqo
iegik
30

Fondamentalement, tout le monde recherche:

MOINS:

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 pur:

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
la source
1
Vous venez clairement d'utiliser la solution de travail et vous avez 0 votes positifs WaT?
ProNOOB
5
Réponse géniale. Cependant, la pseudo-classe: placeholder-shown ne fonctionne pas dans IE ou Edge, ce n'est donc pas une solution complète. C'est sacrément proche, cependant, et cela me donne envie d'assassiner Edge pour ne pas l'avoir soutenu. IE je pourrais accepter, mais Edge? Allez Microsoft!
Aaron Martin-Colby
2
Ce n'est pas une solution pure css si vous devez ajouter "obligatoire" à votre
code
Merci gentil monsieur, j'espère sincèrement que cela augmentera car à mon avis, c'est ce que la plupart des gens veulent vraiment.
sivi911
20

Vous pouvez utiliser l' placeholderastuce comme indiqué ci-dessus sans requiredchamp.

Le problème requiredest que lorsque vous avez écrit quelque chose, puis que vous l'avez supprimé - l'entrée sera désormais toujours rouge dans le cadre de la spécification HTML5 - alors vous aurez besoin d'un CSS comme écrit ci-dessus pour le corriger / le remplacer.

Vous pouvez simplement faire quelque chose sans 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;
}

Stylo code: https://codepen.io/arlevi/pen/LBgXjZ

Ricky Levi
la source
1
Cette approche correspondait parfaitement à mon cas d'utilisation. J'avais des filtres de recherche qui avaient de toute façon des espaces réservés, et je voulais que la bordure de la zone de saisie soit mise en évidence lorsqu'une valeur était présente.
Stephen Tuttlebee
9

CSS simple:

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

Ce code va appliquer le css donné au chargement de la page si l'entrée est remplie.

Breno Teixeira
la source
9
Cela ne fonctionne qu'au chargement de la page. Pas de saisie dynamique d'une valeur.
Ben Racicot
Le problème de chargement de page doit être explicitement noté pour cette réponse.
Bryce Snyder le
6

Vous pouvez input[type=text]styliser différemment selon que l'entrée contient du texte ou non en stylisant l'espace réservé. Ce n'est pas une norme officielle à ce stade, mais il prend en charge un large navigateur, bien qu'avec des préfixes différents:

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

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

vbraun
la source
Pour info, cela formate de manière fiable l'espace réservé, mais uniquement l'espace réservé lui-même. Cela vous donne l'illusion de changer la couleur du texte, mais c'est déjà le cas, juste avec le gris et le noir par défaut.
John Weisz
Tout le CSS est une illusion bon marché, vous ne changez que les apparences sans affecter le contenu réel :-)
vbraun
C'est exactement ce dont j'avais besoin. J'avais besoin de l'entrée pour changer les styles si elle contenait du texte car la conception de l'espace réservé diffère du style d'entrée. Parfait!
Christopher Marshall
Cela fonctionne pour les arrière-plans, mais pas pour les bordures. Je n'ai pas creusé trop profondément pour essayer de changer la frontière.
majinnaibu
5

Utilisation de JS et CSS: pas de 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="" />

   

Pavlo Kozachuk
la source
4

Vous pouvez profiter de l'espace réservé et utiliser:

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

Le sélecteur valide fera l'affaire.

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

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

Astuce simple avec jQuery et CSS Comme ceci:

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
la source
1

faites-le sur la partie HTML comme ceci:

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

Le paramètre requis exigera qu'il contienne du texte dans le champ de saisie pour être valide.

Xedret
la source
Cela n'aide pas à détecter si l'entrée contient du texte avec CSS, ce qui était la question.
Jukka K. Korpela
Désolé, ça aide vraiment ... Cela permet d'utiliser des pseudo-classes, comme expliqué dans ma réponse.
Jukka K. Korpela
1
C'est une question élégante - ce qui signifie que l'OP ne peut pas contrôler ou modifier la page cible. Il ne voit que la page côté client.
Brock Adams
3
Cela a été très utile, voici un exemple de ce dont Xedret parle: codepen.io/tolmark12/pen/LsBvf
tolmark
****** <entrée requise> && entrée: valide {...} ******
FremyCompany
0

Oui! vous pouvez le faire avec un attribut de base simple avec un sélecteur de valeur.

Utiliser le sélecteur d'attribut avec une valeur vide et appliquer des propriétés input[value='']

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

Ce n'est pas possible avec css. Pour implémenter cela, vous devrez utiliser JavaScript (par exemple $("#input").val() == "").

Logan
la source
2
Je sais comment faire cela, je dois le faire avec CSS. Veuillez lire les commentaires sur le message original. Je construis un style "Stylish", qui ne peut pas utiliser JavaScript, à ma connaissance.
JacobTheDev