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