The username is required. Must be a series of alpha characters only (min 5, max 30).
An email address is required. Special characters are not allowed.
<form id="change-email-form">

  <input type="text" 
    name="username" 
    id="username"
    placeholder="username"
    pattern="[a-zA-Z ]{5,}"
    maxlength="30"
    required
    class="form-control">
          
  <div class="validation-messages">
    <span data-rule="valueMissing" class="hide">The username is required.</span>
    <span data-rule="patternMismatch" class="hide">Must be a series of alpha 
      characters only (min 5, max 30).</span>
  </div>

  <input type="email" 
    id="email" 
    placeholder="email address"
    title="Email address is required"
    required
    class="form-control">

  <div class="validation-messages">
    <span data-rule="valueMissing" class="hide">
      An email address is required.</span>
    <span data-rule="typeMismatch" class="hide">
      Special characters are not allowed.</span>
  </div>

  <div class="push-down-top">
    <button type="button" class="btn btn-link">Cancel</button>
    <button type="button" id="login-button" class="btn">Login</button>
  </div>

</form>
input:focus:invalid,
textarea:focus:invalid,
select:focus:invalid {
  color: #c33;
  border-color: #c33;
}

input:focus:invalid:focus,
textarea:focus:invalid:focus,
select:focus:invalid:focus {
  border-color: #c33;
  -webkit-box-shadow: 0 0 6px #fcc;
     -moz-box-shadow: 0 0 6px #fcc;
          box-shadow: 0 0 6px #fcc;
}

input:invalid,
textarea:invalid,
select:invalid {
  border-bottom: 1px solid #c33;
}

input:valid + .invalid /* Adjacent sibling selector */ {
  visibility: hidden;
}

input:invalid + .invalid {
  visibility: visible;
}

input:required {
  border-left: 4px solid #c33;
}

input:valid {
  border-bottom: transparent;
}

.invalid {
  color: #999;
}
document.addEventListener('DOMContentLoaded', function(e) {
  // Create a container for 
  // validation rule names.
  var ruleNames = [];
  var forEach = Array.prototype.forEach;
  
  // Fills array with rule names. 
  // Looks for all SPANs with the data-rule 
  // attribute and then adds the rule 
  // name to the array.
  var ruleElements = document.querySelectorAll('span[data-rule]'); 
  forEach.call(ruleElements, function(element) {
    var ruleName = element.getAttribute('data-rule');
    if (ruleNames.indexOf(ruleNames) < 0) {
      ruleNames.push(ruleName);
    }
  });
  
  // First clear the UI by hiding all 
  // validation messages. Then run 
  // validation rules on the selected form.
  var validate = function() {
    var messages = document.querySelectorAll(".validation-messages span");
    forEach.call(messages, function(message){
      message.classList.add('hide')
    });
    document.getElementById('change-email-form').checkValidity();
  };
  
  // Check each input element to determine 
  // which element is invalid. Once an 
  // invalid state is detected, then loop 
  // through the validation rules to find 
  // out which is broken and therefore 
  // which message to display to the user.
  var validationFail = function(e) {
    var element, validity;
    
    element = e.currentTarget;
    validity = element.validity;
  
    if (!validity.valid) {
      ruleNames.forEach(function(ruleName) {
        checkRule(validity,ruleName,element);
      });
      e.preventDefault();
    }
  };
  
  // Uses the instance of the input element's 
  // ValidityState object to run a validation 
  // rule. If the validation rule returns 
  // 'true' then the rule is broken and 
  // the appropriate validation message 
  //is exposed to the user. 
  var checkRule = function(state, ruleName, element) {
    if (state[ruleName]) {
      
      var rules = element
                   .nextElementSibling
                   .querySelectorAll('[data-rule="' + ruleName + '"]');
      
      forEach.call(rules, function(rule){
        rule.classList.remove('hide');
      });
    }
  };
  
  // Attaches validation event handlers to 
  // all input elements that are NOT buttons.
  var inputElements = document.querySelectorAll('input:not(button)');
  forEach.call(inputElements, function(input) {
      input.oninvalid = validationFail;
      input.onblur = validate;
  });
  
  document.getElementById('login-button').addEventListener('click', validate, false);
});