:invalid & :valid - Only Take Effect after Interaction

By default the :invalid & :valid pseudoselectors take affect immediately. This solution shows one way of not changing the UI until fields have been interacted with.

by TJ VanToll

HTML

<form>
    <input type="text" required />
    <input type="text" />
    <input type="submit" />
</form>

CSS

.interacted:invalid {
    border: 1px solid red;
}
.interacted:valid {
    border: 1px solid green;
}

JavaScript

var inputs = document.querySelectorAll('input[type=text]');
for (var i = 0; i < inputs.length; i++) {
    inputs[i].addEventListener('blur', function(event) {
        event.target.classList.add('interacted');
    }, false);
}