Why is the initial state of an input with required invalid?

4

When I place one or more constraints on a <input> , its status initially appears as invalid . As in the example below:

input {
    border: 2px solid #ccc;
    padding: 8px;
}

input:invalid {
    border-color: red;
}

input:valid {
    border-color:green;
}
<input required type="text" pattern="\d*" placeholder="Somente Digitos" min="1"/>

Note that as soon as the code is loaded the border of <input> appears in red because it is a required field (defined in CSS to display it in this way when the value in input is incorrect).

My question is: How do I input be neutral when I load the page? That is, without displaying the green / red defined in CSS. (or better: How do I not start it in the :invalid state?).

    
asked by anonymous 02.12.2014 / 23:04

2 answers

3

If you have both a required field and an empty field, it is an invalid field - after all, a required field, to be valid, must have data:)

What you can do in this case, to improve the initial user experience, is to "delay" the CSS to appear only after there is interaction with the form.

In this intention, two intermediate solutions follow. One is based on autofocus , and it's pure CSS. The other has some similarity to the @Sergio response, but for cases where the submit button (or another equivalent procedure) is present.


For a single field: CSS

If you have a single field, you can solve it without JS:

  • Set the field to autofocus ;

  • stylize with CSS so that while the field has focus, stay "neutral."

input             { border: 2px solid #ccc; padding: 8px; }
input:invalid     { border-color: red; }
input:valid,
input:focus:valid { border-color:green; }
input:focus       { border-color: #ccc; !important; }
<input required type="text" pattern="\d*" placeholder="Somente Digitos" min="1" autofocus />


For multiple fields: JS

The following JS function causes the field to respond visually to the requirements in the loss of focus, in a possible send attempt, that all fields will receive the CSS indicating their status.

In this way, feedback happens in the form all even without a particular field being visited.

var hi = document.querySelectorAll('input.off');
for (var i = 0; i < hi.length; i++) hi[i].onblur = function(){ this.classList.add('hl'); }
function highlightAll() { for (var i = 0; i < hi.length; i++) hi[i].classList.add('hl'); }
input            { border: 2px solid #ccc; padding: 8px; }
input.hl:invalid { border-color: red; }
input.hl:valid   { border-color:green; }
<input class="off" type="text" required pattern="\d*" placeholder="Somente Digitos" min="1" /><br>
<input class="off" type="text" required placeholder="Qualquer coisa" /><br>
<input class="off" type="text" placeholder="Campo não obrigatório" /><br>
<button onClick="highlightAll()">enviar</button>
    
07.12.2014 / 10:31
3

What causes this behavior is the required property. In other words, having input with required and without value defined (or inserted) causes the input not to validate . In other words, the browser knows that this field is mandatory and that it is empty, so its status is invalid and the CSS reflects this.

Giving value="0" or taking required (as in the example below) works as expected.

input {
    border: 2px solid #ccc;
    padding: 8px;
}

input:invalid {
    border-color: red;
}

input:valid {
    border-color:green;
}
<input type="text" pattern="\d*" placeholder="Somente Digitos"  min="1"/>

To work around this problem you must use JavaScript. For example:

var required = document.querySelector('input[required]');
required.onblur = function(){ this.classList.add('visitado'); };
input {
    border: 2px solid #ccc;
    padding: 8px;
}

input.visitado:invalid {
    border-color: red;
}

input:valid {
    border-color:green;
}
<input required type="text" pattern="\d*" placeholder="Somente Digitos" min="1"/>
    
02.12.2014 / 23:11