Input with immediate feedback
by Konstantin Rouda
HTML
<form method="POST">
<div class="input-container">
<input type="text" name="name" id="name" maxlength="40" class="input">
<label class="indicator"></label>
<label for="name" class="input-label">name</label>
<label class="error-label">this field is required</label>
</div>
<div class="input-container">
<button type="submit" class="submit-btn">submit</button>
</div>
</form>
CSS
BODY {
background: #fff;
font-family: Helvetica;
font-size: 16px;
}
FORM {
max-width: 800px;
margin: 1em auto 0;
padding: 1em;
}
.input-container {
position: relative;
text-align: center;
padding: 1em 1px;
margin-bottom: 2em;
overflow: hidden;
border-radius: 0.3125em;
}
.indicator:before {
content: "";
position: absolute;
top: .75em;
left: .4em;
width: 40px;
height: 40px;
color: #000;
font-size: 1.8em;
border-radius: 5px;
display: none;
}
.input-container .input:focus + .indicator:before {
display: block;
content: "\27A4"; /*arrow sign*/
background: #959595;
}
.input.valid + .indicator:before {
content: "\2714"; /*V sign*/
background: rgb(149, 193, 147);
display: block;
}
.input.invalid + .indicator:before {
content: "\2715"; /*X sign*/
background: rgb(202, 70, 70);
display: block;
}
.input {
border: none;
border-bottom: 2px solid #f3f3f3;
width: 100%;
transform: scale(.93);
transform-origin: right;
background: #e2e2e2;
min-height: 50px;
color: #000;
font-weight: 600;
letter-spacing: 1px;
border-radius: 3px;
outline: 0;
}
.input:focus {
box-shadow: 0 0 0 5.5em rgba(0, 0, 0, .04);
}
.input-label {
position: absolute;
top: 0;
left: 3.5em;
-moz-transform: translate(0,.8em);
-ms-transform: translate(0,.8em);
-o-transform: translate(0,.8em);
-webkit-transform: translate(0,.8em);
transform: translate(0,.8em);
font-size: 1.2em;
color: #919191;
-moz-transition: transform .3s ease;
-o-transition: transform .3s ease;
-webkit-transition: transform .3s ease;
transition: transform .3s ease;
}
.input:focus ~ .input-label {
font-size: 1.2em;
-moz-transform: translate(0,-.15em);
-ms-transform: translate(0,-.15em);
-o-transform: translate(0,-.15em);
-webkit-transform: translate(0,-.15em);
transform: translate(0,-.15em);
color: #989898;
...
JavaScript
/// By Konstantin Rouda
/// LinkedIn: https://il.linkedin.com/pub/konstantin-rouda/8a/2a9/262
/// Twitter: https://twitter.com/KonstantinRouda
/// Inspired by sketch of Jakub Linowski
//// https://www.instagram.com/p/BDEqJ_bS4AG/
/*simple 'required' validation*/
var inputs = document.getElementsByClassName("input");
var form = document.forms[0];
var canSendForm = false;
for(var i = 0, len = inputs.length; i < len; i++) {
inputs[i].onblur = validateInput;
}
function validateInput(e) {
var self = this;
var inputVal = self.value.trim();
var isInvalid = /\binvalid\b/.test(self.className);
var isValid = /\bvalid\b/.test(self.className);
if(inputVal === "" && !isInvalid) {
removeClass(self, "valid");
self.className += " invalid";
canSendForm = false;
} else if(inputVal !== "" && !isValid) {
removeClass(self, "invalid");
self.className += " valid";
canSendForm = true;
}
};
function removeClass(elem, classToRemove) {
var regExp = new RegExp("\\b" + classToRemove + "\\b");
elem.className = elem.className.replace(regExp, "").trim();
};
form.onsubmit = function(e) {
var blurEvent;
if(typeof window.Event === "function") {
blurEvent = new Event("blur");
} else {
blurEvent = document.createEvent("Event");
blurtEvent.initEvent("blur", true, true);
}
var triggerEventMethod = document.dispatchEvent ? "dispatchEvent" : "fireEvent";
var formElements = this.elements;
for(var i = 0, len = formElements.length; i < len; i++) {
formElements[i][triggerEventMethod](blurEvent);
}
return canSendForm;
};