Example
<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width, initial-scale=1">
<head>
<style>
* { box-sizing: border-box; }
body {
font-size: 1.2em;
}
body input, body button {
font-size: 1.2em;
}
form > div {
margin: 1em;
}
form button {
width: 100%;
}
label { display: block; }
input {
width: 100%;
padding: 0.2em;
}
button {
padding: 0.2em;
}
.invalid {
background: red;
color: white;
}
.error {
color: red;
}
</style>
<script>
function validate() {
var errorNode = this.parentNode.querySelector( ".error" ),
span = document.createElement( "span" )
this.classList.remove( "invalid" );
if ( errorNode ) {
errorNode.parentNode.removeChild( errorNode );
}
if ( !this.validity.valid ) {
this.classList.add( "invalid" );
this.parentNode.appendChild( span );
span.classList.add( "error" );
span.innerHTML = this.getAttribute(
this.validity.valueMissing ? "data-required-message" : "data-type-message" );
}
};
var form = document.querySelector( "form" ),
inputs = form.querySelectorAll( "input" );
for ( var i = 0; i < inputs.length; i++ ) {
inputs[ i ].addEventListener( "blur", validate );
inputs[ i ].addEventListener( "invalid", validate );
};
// Turn off the bubbles
form.addEventListener( "invalid", function( event ) {
event.preventDefault();
}, true );
// Support: Safari, iOS Safari, default Android browser
document.querySelector( "form" ).addEventListener( "submit", function( event ) {
if ( this.checkValidity() ) {
alert( "Successful submission" );
} else {
event.preventDefault();
}
});
</script>
</head>
<body>
<form>
<div>
<label for="name">Name:</label>
<input type="text" name="name" id="name" required data-required-message="Name is required.">
</div>
<div>
<label for="email">Email:</label>
<input type="email" name="email" id="email" required data-required-message="Email is required." data-type-message="You must provide a valid email address.">
</div>
<div>
<button>Submit</button>
</div>
</form>
</body>
</html>