Simplistic, single input view form.
http://tympanus.net/codrops/2014/04/01/minimal-form-interface/
Forked from Code Stuff's Pen Minimal Form Interface.
A Pen by Seth Calkins on CodePen.
| <div class="container"> | |
| <header class="codrops-header"> | |
| <h1>Minimal Form Interface <span>Simplistic, single input view form</span></h1> | |
| </header> | |
| <section> | |
| <form id="theForm" class="simform" autocomplete="off"> | |
| <div class="simform-inner"> | |
| <ol class="questions"> | |
| <li> | |
| <span><label for="q1">What's your favorite movie?</label></span> | |
| <input id="q1" name="q1" type="text"/> | |
| </li> | |
| <li> | |
| <span><label for="q2">Where do you live?</label></span> | |
| <input id="q2" name="q2" type="text"/> | |
| </li> | |
| <li> | |
| <span><label for="q3">What time do you got to work?</label></span> | |
| <input id="q3" name="q3" type="text"/> | |
| </li> | |
| <li> | |
| <span><label for="q4">How do you like your veggies?</label></span> | |
| <input id="q4" name="q4" type="text"/> | |
| </li> | |
| <li> | |
| <span><label for="q5">What book inspires you?</label></span> | |
| <input id="q5" name="q5" type="text"/> | |
| </li> | |
| <li> | |
| <span><label for="q6">What's your profession?</label></span> | |
| <input id="q6" name="q6" type="text"/> | |
| </li> | |
| </ol><!-- /questions --> | |
| <button class="submit" type="submit">Send answers</button> | |
| <div class="controls"> | |
| <button class="next fa fa-long-arrow-right""></button> | |
| <div class="progress"></div> | |
| <span class="number"> | |
| <span class="number-current"></span> | |
| <span class="number-total"></span> | |
| </span> | |
| <span class="error-message"></span> | |
| </div><!-- / controls --> | |
| </div><!-- /simform-inner --> | |
| <span class="final-message"></span> | |
| </form><!-- /simform --> | |
| </section> | |
| </div> |
Simplistic, single input view form.
http://tympanus.net/codrops/2014/04/01/minimal-form-interface/
Forked from Code Stuff's Pen Minimal Form Interface.
A Pen by Seth Calkins on CodePen.
| /*! | |
| * classie - class helper functions | |
| * from bonzo https://github.com/ded/bonzo | |
| * | |
| * classie.has( elem, 'my-class' ) -> true/false | |
| * classie.add( elem, 'my-new-class' ) | |
| * classie.remove( elem, 'my-unwanted-class' ) | |
| * classie.toggle( elem, 'my-class' ) | |
| */ | |
| /*jshint browser: true, strict: true, undef: true */ | |
| /*global define: false */ | |
| ( function( window ) { | |
| 'use strict'; | |
| // class helper functions from bonzo https://github.com/ded/bonzo | |
| function classReg( className ) { | |
| return new RegExp("(^|\\s+)" + className + "(\\s+|$)"); | |
| } | |
| // classList support for class management | |
| // altho to be fair, the api sucks because it won't accept multiple classes at once | |
| var hasClass, addClass, removeClass; | |
| if ( 'classList' in document.documentElement ) { | |
| hasClass = function( elem, c ) { | |
| return elem.classList.contains( c ); | |
| }; | |
| addClass = function( elem, c ) { | |
| elem.classList.add( c ); | |
| }; | |
| removeClass = function( elem, c ) { | |
| elem.classList.remove( c ); | |
| }; | |
| } | |
| else { | |
| hasClass = function( elem, c ) { | |
| return classReg( c ).test( elem.className ); | |
| }; | |
| addClass = function( elem, c ) { | |
| if ( !hasClass( elem, c ) ) { | |
| elem.className = elem.className + ' ' + c; | |
| } | |
| }; | |
| removeClass = function( elem, c ) { | |
| elem.className = elem.className.replace( classReg( c ), ' ' ); | |
| }; | |
| } | |
| function toggleClass( elem, c ) { | |
| var fn = hasClass( elem, c ) ? removeClass : addClass; | |
| fn( elem, c ); | |
| } | |
| var classie = { | |
| // full names | |
| hasClass: hasClass, | |
| addClass: addClass, | |
| removeClass: removeClass, | |
| toggleClass: toggleClass, | |
| // short names | |
| has: hasClass, | |
| add: addClass, | |
| remove: removeClass, | |
| toggle: toggleClass | |
| }; | |
| // transport | |
| if ( typeof define === 'function' && define.amd ) { | |
| // AMD | |
| define( classie ); | |
| } else { | |
| // browser global | |
| window.classie = classie; | |
| } | |
| })( window ); | |
| /** | |
| * stepsForm.js v1.0.0 | |
| * http://www.codrops.com | |
| * | |
| * Licensed under the MIT license. | |
| * http://www.opensource.org/licenses/mit-license.php | |
| * | |
| * Copyright 2014, Codrops | |
| * http://www.codrops.com | |
| */ | |
| ;( function( window ) { | |
| 'use strict'; | |
| var transEndEventNames = { | |
| 'WebkitTransition': 'webkitTransitionEnd', | |
| 'MozTransition': 'transitionend', | |
| 'OTransition': 'oTransitionEnd', | |
| 'msTransition': 'MSTransitionEnd', | |
| 'transition': 'transitionend' | |
| }, | |
| transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ], | |
| support = { transitions : Modernizr.csstransitions }; | |
| function extend( a, b ) { | |
| for( var key in b ) { | |
| if( b.hasOwnProperty( key ) ) { | |
| a[key] = b[key]; | |
| } | |
| } | |
| return a; | |
| } | |
| function stepsForm( el, options ) { | |
| this.el = el; | |
| this.options = extend( {}, this.options ); | |
| extend( this.options, options ); | |
| this._init(); | |
| } | |
| stepsForm.prototype.options = { | |
| onSubmit : function() { return false; } | |
| }; | |
| stepsForm.prototype._init = function() { | |
| // current question | |
| this.current = 0; | |
| // questions | |
| this.questions = [].slice.call( this.el.querySelectorAll( 'ol.questions > li' ) ); | |
| // total questions | |
| this.questionsCount = this.questions.length; | |
| // show first question | |
| classie.addClass( this.questions[0], 'current' ); | |
| // next question control | |
| this.ctrlNext = this.el.querySelector( 'button.next' ); | |
| // progress bar | |
| this.progress = this.el.querySelector( 'div.progress' ); | |
| // question number status | |
| this.questionStatus = this.el.querySelector( 'span.number' ); | |
| // current question placeholder | |
| this.currentNum = this.questionStatus.querySelector( 'span.number-current' ); | |
| this.currentNum.innerHTML = Number( this.current + 1 ); | |
| // total questions placeholder | |
| this.totalQuestionNum = this.questionStatus.querySelector( 'span.number-total' ); | |
| this.totalQuestionNum.innerHTML = this.questionsCount; | |
| // error message | |
| this.error = this.el.querySelector( 'span.error-message' ); | |
| // init events | |
| this._initEvents(); | |
| }; | |
| stepsForm.prototype._initEvents = function() { | |
| var self = this, | |
| // first input | |
| firstElInput = this.questions[ this.current ].querySelector( 'input' ), | |
| // focus | |
| onFocusStartFn = function() { | |
| firstElInput.removeEventListener( 'focus', onFocusStartFn ); | |
| classie.addClass( self.ctrlNext, 'show' ); | |
| }; | |
| // show the next question control first time the input gets focused | |
| firstElInput.addEventListener( 'focus', onFocusStartFn ); | |
| // show next question | |
| this.ctrlNext.addEventListener( 'click', function( ev ) { | |
| ev.preventDefault(); | |
| self._nextQuestion(); | |
| } ); | |
| // pressing enter will jump to next question | |
| document.addEventListener( 'keydown', function( ev ) { | |
| var keyCode = ev.keyCode || ev.which; | |
| // enter | |
| if( keyCode === 13 ) { | |
| ev.preventDefault(); | |
| self._nextQuestion(); | |
| } | |
| } ); | |
| // disable tab | |
| this.el.addEventListener( 'keydown', function( ev ) { | |
| var keyCode = ev.keyCode || ev.which; | |
| // tab | |
| if( keyCode === 9 ) { | |
| ev.preventDefault(); | |
| } | |
| } ); | |
| }; | |
| stepsForm.prototype._nextQuestion = function() { | |
| if( !this._validade() ) { | |
| return false; | |
| } | |
| // check if form is filled | |
| if( this.current === this.questionsCount - 1 ) { | |
| this.isFilled = true; | |
| } | |
| // clear any previous error messages | |
| this._clearError(); | |
| // current question | |
| var currentQuestion = this.questions[ this.current ]; | |
| // increment current question iterator | |
| ++this.current; | |
| // update progress bar | |
| this._progress(); | |
| if( !this.isFilled ) { | |
| // change the current question number/status | |
| this._updateQuestionNumber(); | |
| // add class "show-next" to form element (start animations) | |
| classie.addClass( this.el, 'show-next' ); | |
| // remove class "current" from current question and add it to the next one | |
| // current question | |
| var nextQuestion = this.questions[ this.current ]; | |
| classie.removeClass( currentQuestion, 'current' ); | |
| classie.addClass( nextQuestion, 'current' ); | |
| } | |
| // after animation ends, remove class "show-next" from form element and change current question placeholder | |
| var self = this, | |
| onEndTransitionFn = function( ev ) { | |
| if( support.transitions ) { | |
| this.removeEventListener( transEndEventName, onEndTransitionFn ); | |
| } | |
| if( self.isFilled ) { | |
| self._submit(); | |
| } | |
| else { | |
| classie.removeClass( self.el, 'show-next' ); | |
| self.currentNum.innerHTML = self.nextQuestionNum.innerHTML; | |
| self.questionStatus.removeChild( self.nextQuestionNum ); | |
| // force the focus on the next input | |
| nextQuestion.querySelector( 'input' ).focus(); | |
| } | |
| }; | |
| if( support.transitions ) { | |
| this.progress.addEventListener( transEndEventName, onEndTransitionFn ); | |
| } | |
| else { | |
| onEndTransitionFn(); | |
| } | |
| } | |
| // updates the progress bar by setting its width | |
| stepsForm.prototype._progress = function() { | |
| this.progress.style.width = this.current * ( 100 / this.questionsCount ) + '%'; | |
| } | |
| // changes the current question number | |
| stepsForm.prototype._updateQuestionNumber = function() { | |
| // first, create next question number placeholder | |
| this.nextQuestionNum = document.createElement( 'span' ); | |
| this.nextQuestionNum.className = 'number-next'; | |
| this.nextQuestionNum.innerHTML = Number( this.current + 1 ); | |
| // insert it in the DOM | |
| this.questionStatus.appendChild( this.nextQuestionNum ); | |
| } | |
| // submits the form | |
| stepsForm.prototype._submit = function() { | |
| this.options.onSubmit( this.el ); | |
| } | |
| // TODO (next version..) | |
| // the validation function | |
| stepsForm.prototype._validade = function() { | |
| // current questionВґs input | |
| var input = this.questions[ this.current ].querySelector( 'input' ).value; | |
| if( input === '' ) { | |
| this._showError( 'EMPTYSTR' ); | |
| return false; | |
| } | |
| return true; | |
| } | |
| // TODO (next version..) | |
| stepsForm.prototype._showError = function( err ) { | |
| var message = ''; | |
| switch( err ) { | |
| case 'EMPTYSTR' : | |
| message = 'Please fill the field before continuing'; | |
| break; | |
| case 'INVALIDEMAIL' : | |
| message = 'Please fill a valid email address'; | |
| break; | |
| // ... | |
| }; | |
| this.error.innerHTML = message; | |
| classie.addClass( this.error, 'show' ); | |
| } | |
| // clears/hides the current error message | |
| stepsForm.prototype._clearError = function() { | |
| classie.removeClass( this.error, 'show' ); | |
| } | |
| // add to global namespace | |
| window.stepsForm = stepsForm; | |
| })( window ); | |
| var theForm = document.getElementById( 'theForm' ); | |
| new stepsForm( theForm, { | |
| onSubmit : function( form ) { | |
| // hide form | |
| classie.addClass( theForm.querySelector( '.simform-inner' ), 'hide' ); | |
| /* | |
| form.submit() | |
| or | |
| AJAX request (maybe show loading indicator while we don't have an answer..) | |
| */ | |
| // let's just simulate something... | |
| var messageEl = theForm.querySelector( '.final-message' ); | |
| messageEl.innerHTML = 'Thank you! We\'ll be in touch.'; | |
| classie.addClass( messageEl, 'show' ); | |
| } | |
| } ); |
| @import url(http://fonts.googleapis.com/css?family=Lato:400,700,400italic); | |
| .simform { | |
| position: relative; | |
| margin: 0 auto; | |
| padding: 2em 0; | |
| max-width: 860px; | |
| width: 100%; | |
| text-align: left; | |
| font-size: 2.5em; | |
| } | |
| .simform .submit { | |
| display: none; | |
| } | |
| /* Question list style */ | |
| .simform ol { | |
| margin: 0; | |
| padding: 0; | |
| list-style: none; | |
| position: relative; | |
| -webkit-transition: height 0.4s; | |
| transition: height 0.4s; | |
| } | |
| .simform ol:before { | |
| content: ''; | |
| background-color: rgba(0,0,0,0.1); | |
| position: absolute; | |
| left: 0; | |
| bottom: 0; | |
| width: 100%; | |
| height: 2.35em; | |
| } | |
| .questions li { | |
| z-index: 100; | |
| position: relative; | |
| visibility: hidden; | |
| height: 0; | |
| -webkit-transition: visibility 0s 0.4s, height 0s 0.4s; | |
| transition: visibility 0s 0.4s, height 0s 0.4s; | |
| } | |
| .questions li.current, | |
| .no-js .questions li { | |
| visibility: visible; | |
| height: auto; | |
| -webkit-transition: none; | |
| transition: none; | |
| } | |
| /* Labels */ | |
| .questions li > span { | |
| display: block; | |
| overflow: hidden; | |
| } | |
| .questions li > span label { | |
| display: block; | |
| -webkit-transition: -webkit-transform 0.4s; | |
| transition: transform 0.4s; | |
| -webkit-transform: translateY(-100%); | |
| transform: translateY(-100%); | |
| } | |
| .questions li.current > span label, | |
| .no-js .questions li > span label { | |
| -webkit-transition: none; | |
| transition: none; | |
| -webkit-transform: translateY(0); | |
| transform: translateY(0); | |
| } | |
| .show-next .questions li.current > span label { | |
| -webkit-animation: moveUpFromDown 0.4s both; | |
| animation: moveUpFromDown 0.4s both; | |
| } | |
| @-webkit-keyframes moveUpFromDown { | |
| from { -webkit-transform: translateY(100%); } | |
| to { -webkit-transform: translateY(0); } | |
| } | |
| @keyframes moveUpFromDown { | |
| from { transform: translateY(100%); } | |
| to { transform: translateY(0); } | |
| } | |
| /* Input field */ | |
| .questions input { | |
| display: block; | |
| margin: 0.3em 0 0 0; | |
| padding: 0.5em 1em 0.5em 0.7em; | |
| width: calc(100% - 2em); | |
| border: none; | |
| background: transparent; | |
| color: rgba(0,0,0,0.8); | |
| font-size: 1em; | |
| line-height: 1; | |
| opacity: 0; | |
| -webkit-transition: opacity 0.3s; | |
| transition: opacity 0.3s; | |
| } | |
| .questions .current input, | |
| .no-js .questions input { | |
| opacity: 1; | |
| } | |
| .questions input:focus, | |
| .simform button:focus { | |
| outline: none; | |
| } | |
| /* Next question button */ | |
| .next { | |
| position: absolute; | |
| right: 0; | |
| bottom: 2.15em; /* padding-bottom of form plus progress bar height */ | |
| display: block; | |
| padding: 0; | |
| width: 2em; | |
| height: 2em; | |
| border: none; | |
| background: none; | |
| color: rgba(0,0,0,0.4); | |
| text-align: center; | |
| opacity: 0; | |
| z-index: 100; | |
| cursor: pointer; | |
| -webkit-transition: -webkit-transform 0.3s, opacity 0.3s; | |
| transition: transform 0.3s, opacity 0.3s; | |
| -webkit-transform: translateX(-20%); | |
| transform: translateX(-20%); | |
| pointer-events: none; | |
| -webkit-tap-highlight-color: rgba(0, 0, 0, 0); | |
| } | |
| .next:hover { | |
| color: rgba(0,0,0,0.5); | |
| } | |
| .next::after { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| text-transform: none; | |
| font-weight: normal; | |
| font-style: normal; | |
| font-variant: normal; | |
| line-height: 2; | |
| speak: none; | |
| -webkit-font-smoothing: antialiased; | |
| -moz-osx-font-smoothing: grayscale; | |
| } | |
| .next.show { | |
| opacity: 1; | |
| -webkit-transform: translateX(0); | |
| transform: translateX(0); | |
| pointer-events: auto; | |
| } | |
| /* Progress bar */ | |
| .simform .progress { | |
| width: 0%; | |
| height: 0.15em; | |
| background: rgba(0,0,0,0.3); | |
| -webkit-transition: width 0.4s ease-in-out; | |
| transition: width 0.4s ease-in-out; | |
| } | |
| .simform .progress::before { | |
| position: absolute; | |
| top: auto; | |
| width: 100%; | |
| height: inherit; | |
| background: rgba(0,0,0,0.05); | |
| content: ''; | |
| } | |
| /* Number indicator */ | |
| .simform .number { | |
| position: absolute; | |
| right: 0; | |
| overflow: hidden; | |
| margin: 0.4em 0; | |
| width: 3em; | |
| font-weight: 700; | |
| font-size: 0.4em; | |
| } | |
| .simform .number:after { | |
| position: absolute; | |
| left: 50%; | |
| content: '/'; | |
| opacity: 0.4; | |
| -webkit-transform: translateX(-50%); | |
| transform: translateX(-50%); | |
| } | |
| .simform .number span { | |
| float: right; | |
| width: 40%; | |
| text-align: center; | |
| } | |
| .simform .number .number-current { | |
| float: left; | |
| } | |
| .simform .number-next { | |
| position: absolute; | |
| left: 0; | |
| } | |
| .simform.show-next .number-current { | |
| -webkit-transition: -webkit-transform 0.4s; | |
| transition: transform 0.4s; | |
| -webkit-transform: translateY(-100%); | |
| transform: translateY(-100%); | |
| } | |
| .simform.show-next .number-next { | |
| -webkit-animation: moveUpFromDown 0.4s both; | |
| animation: moveUpFromDown 0.4s both; | |
| } | |
| /* Error and final message */ | |
| .simform .error-message, | |
| .simform .final-message { | |
| position: absolute; | |
| visibility: hidden; | |
| opacity: 0; | |
| -webkit-transition: opacity 0.4s; | |
| transition: opacity 0.4s; | |
| } | |
| .simform .error-message { | |
| padding: 0.4em 3.5em 0 0; | |
| width: 100%; | |
| color: rgba(0,0,0,0.7); | |
| font-style: italic; | |
| font-size: 0.4em; | |
| } | |
| .final-message { | |
| top: 50%; | |
| left: 0; | |
| padding: 0.5em; | |
| width: 100%; | |
| text-align: center; | |
| -webkit-transform: translateY(-50%); | |
| transform: translateY(-50%); | |
| } | |
| .error-message.show, | |
| .final-message.show { | |
| visibility: visible; | |
| opacity: 1; | |
| } | |
| .final-message.show { | |
| -webkit-transition-delay: 0.5s; | |
| transition-delay: 0.5s; | |
| } | |
| /* Final hiding of form / showing message */ | |
| .simform-inner.hide { | |
| visibility: hidden; | |
| opacity: 0; | |
| -webkit-transition: opacity 0.3s, visibility 0s 0.3s; | |
| transition: opacity 0.3s, visibility 0s 0.3s; | |
| } | |
| /* No JS Fallback */ | |
| .no-js .simform { | |
| font-size: 1.75em; | |
| } | |
| .no-js .questions li { | |
| padding: 0 0 2em; | |
| } | |
| .no-js .simform .submit { | |
| display: block; | |
| float: right; | |
| padding: 10px 20px; | |
| border: none; | |
| background: rgba(0,0,0,0.3); | |
| color: rgba(0,0,0,0.4); | |
| } | |
| .no-js .simform .controls { | |
| display: none; | |
| } | |
| /* Remove IE clear cross */ | |
| input[type=text]::-ms-clear { | |
| display: none; | |
| } | |
| /* Adjust form for smaller screens */ | |
| @media screen and (max-width: 44.75em) { | |
| .simform { | |
| font-size: 1.8em; | |
| } | |
| } | |
| @media screen and (max-width: 33.5625em) { | |
| .simform { | |
| font-size: 1.2em; | |
| } | |
| } | |
| *, *:after, *:before { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } | |
| .clearfix:before, .clearfix:after { content: ''; display: table; } | |
| .clearfix:after { clear: both; } | |
| body { | |
| background: #26C281; | |
| color: rgba(0,0,0,0.45); | |
| font-size: 100%; | |
| line-height: 1.25; | |
| font-family: 'Lato', Arial, sans-serif; | |
| } | |
| a { | |
| color: rgba(0,0,0,0.25); | |
| text-decoration: none; | |
| outline: none; | |
| } | |
| a:hover, a:focus { | |
| color: rgba(0,0,0,0.6); | |
| } | |
| .codrops-header { | |
| margin: 0 auto; | |
| padding: 3em 1em; | |
| text-align: center; | |
| color: rgba(0,0,0,0.35); | |
| } | |
| .codrops-header h1 { | |
| margin: 0; | |
| font-weight: 400; | |
| font-size: 2.5em; | |
| } | |
| .codrops-header h1 span { | |
| display: block; | |
| padding: 0 0 0.6em 0.1em; | |
| font-size: 0.6em; | |
| opacity: 0.7; | |
| } | |
| /* To Navigation Style */ | |
| .codrops-top { | |
| width: 100%; | |
| text-transform: uppercase; | |
| font-weight: 700; | |
| font-size: 0.69em; | |
| line-height: 2.2; | |
| } | |
| .codrops-top a { | |
| display: inline-block; | |
| padding: 0 1em; | |
| text-decoration: none; | |
| letter-spacing: 1px; | |
| } | |
| .codrops-top span.right { | |
| float: right; | |
| } | |
| .codrops-top span.right a { | |
| display: block; | |
| float: left; | |
| } | |
| section { | |
| padding: 5em 2em 10em; | |
| background: #2dcb89; | |
| text-align: center; | |
| } | |
| section.related { | |
| padding: 3em 1em 4em; | |
| background: #465650; | |
| color: rgba(0,0,0,0.4); | |
| font-size: 1.5em; | |
| } | |
| .related > a { | |
| max-width: 80%; | |
| border: 2px solid rgba(0,0,0,0.3); | |
| display: inline-block; | |
| text-align: center; | |
| margin: 20px 10px; | |
| padding: 25px; | |
| -webkit-transition: color 0.3s, border-color 0.3s; | |
| transition: color 0.3s, border-color 0.3s; | |
| } | |
| .related a:hover { | |
| border-color: rgba(0,0,0,0.6); | |
| } | |
| .related a img { | |
| max-width: 100%; | |
| opacity: 0.4; | |
| -webkit-transition: opacity 0.3s; | |
| transition: opacity 0.3s; | |
| } | |
| .related a:hover img, | |
| .related a:active img { | |
| opacity: 1; | |
| } | |
| .related a h3 { | |
| margin: 0; | |
| padding: 0.5em 0 0.3em; | |
| max-width: 300px; | |
| font-weight: 400; | |
| font-size: 0.75em; | |
| text-align: left; | |
| } | |
| @media screen and (max-width: 44.75em) { | |
| section { padding: 1em 2em; } | |
| } | |
| @media screen and (max-width: 25em) { | |
| .codrops-header { font-size: 0.8em; } | |
| section.related { font-size: 1.2em; } | |
| .codrops-icon span { display: none; } | |
| } |