JacobTheDev
JacobTheDev

Reputation: 18530

Detect if an input has text in it using CSS -- on a page I am visiting and do not control?

Is there a way to detect whether or not an input has text in it via CSS? I've tried using the :empty pseudo-class, and I've tried using [value=""], neither of which worked. I can't seem to find a single solution to this.

I imagine this must be possible, considering we have pseudo-classes for :checked, and :indeterminate, both of which are kind of similar thing.

Please note: I'm doing this for a "Stylish" style, which can't utilize JavaScript.

Also note, that Stylish is used, client-side, on pages that the user does not control.

Upvotes: 287

Views: 382951

Answers (19)

Errol Francois
Errol Francois

Reputation: 19

If you guys are not looking for just pure css, then just add this to your script to add a class to the inputs with values in them.`

// add a field filled class
  const inputs = document.querySelectorAll("input");
  inputs.forEach((el) => {
    el.addEventListener("blur", (e) => {
      const element = e.target;
      const { value } = element;
      if (value.length > 0) {
        element.classList.add("hasValue");
      } else {
        element.classList.remove("hasValue");
      }
    });
  });

`

Upvotes: 0

ngryman
ngryman

Reputation: 7672

If your element has a placeholder attribute, you can use the :placeholder-shown pseudo class.

The placeholder attribute is required and can't be blank, but you can use a single space.

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

The :placeholder-shown property is supported in 97% of browsers and generally safe to use. With the right prefixes, it can even work in IE10.

Upvotes: 422

Eduardo Moreira
Eduardo Moreira

Reputation: 1

It's here, .fase is a class of input in html code.

div.fase > input:focus:required:invalid { 
    color: red;
    border-color: red; 
    box-shadow: 0 0 6px red;
}

div.fase input:focus:required:valid,
input:focus:required:placeholder-shown {
    border-color: rgb(22, 172, 22);
    box-shadow: 0 0 8px rgb(28, 150, 28);
}

div.fase input:valid {
    border-color: rgb(47, 148, 49);
}

Upvotes: 0

Kos
Kos

Reputation: 1778

Using attribute placeholder and pseudo class placeholder-shown is proper way of detecting does input has text.

Example:

<input type="email" placeholder=" " required>
<label>Email</label>
input:focus ~ label,
input:not(:placeholder-shown) ~ label
{
  top : -4em
  left : -0.2em
  font-size : 0.9em
}

Upvotes: 26

benhatsor
benhatsor

Reputation: 2033

There's actually a way to do this without JavaScript.

If you set an <input>'s required selector to true, you can check if there's text in it with the CSS :valid tag.

References:

MDN Docs
CSS Tricks

input {
  background: red;
}

input:valid {
  background: lightgreen;
}
<input type="text" required>

Upvotes: 16

Breno Teixeira
Breno Teixeira

Reputation: 4029

Simple css:

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

This code is going to apply the given css on page load if the input is filled up.

Upvotes: 16

Scottyzen
Scottyzen

Reputation: 331

You can take advantage of the placeholder and use:

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

Upvotes: 33

Ricky Levi
Ricky Levi

Reputation: 7997

You can use the placeholder trick as written above w/o required field.

The problem with required is that when you wrote something, then deleted it - the input will now always be red as part of the HTML5 spec - then you'll need a CSS as written above to fix/override it.

You can simple do thing w/o 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;
}

Code pen:https://codepen.io/arlevi/pen/LBgXjZ

Upvotes: 30

Xedret
Xedret

Reputation: 1901

do it on the HTML part like this:

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

The required parameter will require it to have text in the input field in order to be valid.

Upvotes: 1

Hidayt Rahman
Hidayt Rahman

Reputation: 2678

Yes! you can do it with simple basic attribute with value selector.

Use attribute selector with blank value and apply properties input[value='']

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

Upvotes: 0

Brock Adams
Brock Adams

Reputation: 93493

Stylish cannot do this because CSS cannot do this. CSS has no (pseudo) selectors for <input> value(s). See:

The :empty selector refers only to child nodes, not input values.
[value=""] does work; but only for the initial state. This is because a node's value attribute (that CSS sees), is not the same as the node's value property (Changed by the user or DOM javascript, and submitted as form data).

Unless you care only about the initial state, you must use a userscript or Greasemonkey script. Fortunately this is not hard. The following script will work in Chrome, or Firefox with Greasemonkey or Scriptish installed, or in any browser that supports userscripts (i.e. most browsers, except IE).

See a demo of the limits of CSS plus the javascript solution at this jsBin page.

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

Upvotes: 74

F&#225;bio ZC
F&#225;bio ZC

Reputation: 828

Basically what everybody is looking for is:

LESS:

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

Pure CSS:

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

Upvotes: 43

Niels Steenbeek
Niels Steenbeek

Reputation: 4834

The valid selector will do the trick.

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

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

Upvotes: 4

Pavlo Kozachuk
Pavlo Kozachuk

Reputation: 283

Using JS and CSS :not pseudoclass

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

   

Upvotes: 6

vbraun
vbraun

Reputation: 1987

You can style input[type=text] differently depending on whether or not the input has text by styling the placeholder. This is not an official standard at this point but has wide browser support, though with different prefixes:

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

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

Upvotes: 6

Tom D.
Tom D.

Reputation: 377

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

and

input[value=""]

will work :-)

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

Upvotes: 32

Bren1818
Bren1818

Reputation: 2752

Simple Trick with jQuery and CSS Like so:

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

Upvotes: 2

Jukka K. Korpela
Jukka K. Korpela

Reputation: 201618

It is possible, with the usual CSS caveats and if the HTML code can be modified. If you add the required attribute to the element, then the element will match :invalid or :valid according to whether the value of the control is empty or not. If the element has no value attribute (or it has value=""), the value of the control is initially empty and becomes nonempty when any character (even a space) is entered.

Example:

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

The pseudo-classed :valid and :invalid are defined in Working Draft level CSS documents only, but support is rather widespread in browsers, except that in IE, it came with IE 10.

If you would like to make “empty” include values that consist of spaces only, you can add the attribute pattern=.*\S.*.

There is (currently) no CSS selector for detecting directly whether an input control has a nonempty value, so we need to do it indirectly, as described above.

Generally, CSS selectors refer to markup or, in some cases, to element properties as set with scripting (client-side JavaScript), rather than user actions. For example, :empty matches element with empty content in markup; all input elements are unavoidably empty in this sense. The selector [value=""] tests whether the element has the value attribute in markup and has the empty string as its value. And :checked and :indeterminate are similar things. They are not affected by actual user input.

Upvotes: 310

Logan
Logan

Reputation: 21

This is not possible with css. To implement this you will have to use JavaScript (e.g. $("#input").val() == "").

Upvotes: -8

Related Questions