Abide is an HTML5 form validation library that supports the native API by using patterns and required attributes.

Passwords must be at least 8 characters with 1 capital letter, 1 number, and one special character.
Please enter a properly formatted telephone number.
Valid email required.
Valid URL required.

Setting up validation

To enable validation with Abide add the data-abide attribute to your <form> element. Then add the required attribute to each input that you want to require. Additionaly, you can define a pattern to define restraints on what users can input.

<form data-abide>
  <div class="name-field">
    <label>Your name <small>required</small></label>
    <input type="text" required pattern="[a-zA-Z]+">
    <small class="error">Name is required and must be a string.</small>
  <div class="email-field">
    <label>Email <small>required</small></label>
    <input type="email" required>
    <small class="error">An email address is required.</small>
  <button type="submit">Submit</button>

Predefined patterns

Abide has several patterns common validation patterns built into the library:

Name Valid Example or Format
alpha Foundation
alpha_numeric A1 Sauce
integer -1
number 2937
password LittleW0men.
card visa, amex, mastercard
cvv 384 or 3284
email foundation@zurb.com
url http://zurb.com
domain zurb.com
datetime YYYY-MM-DDThh:mm:ssTZD
time HH:MM:SS
dateISO not sure yet
month_day_year MM/DD/YYYY
color #FFF or #FFFFFF

You can also use these patterns by settings the input's type to the name of the pattern instead of using the pattern attribute:

<input type="password" required>
<input type="email">
<input type="url">

There is a good list of valid HTML5 input types on the Mozilla Developer Network. Try to avoid using patterns defined by type that do not match the specification.

For named patterns that are not valid input types you can use the following shortcut:

<input type="text" pattern="integer">

Custom named patterns

By overriding Abide during Foundation initilization, you can define your own custom patterns or override the default patterns to validate against.

  .foundation('abide', {
    patterns: {
      dashes_only: /^[0-9-]*$/,
      ip_address: /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9]).){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/

You can then use these custom patterns like you would the predfined patterns in your markup:

<form class="custom" data-abide>
  <label>Serial Number</label>
  <input type="text" pattern="dashes_only" required>

Error messages

To display an error message for your invalid form element include a <small> tag with an error class as a sibling of your input.

<div class="input-wrapper">
  <label>Email Address <small>required</small></label>
  <input type="email" required>
  <small class="error">A valid email address is required.</small>

In the above example we have wrapped our input in a div. This div will receive an error class when the input is invalid. This class will show our error message and style the label and input accordingly.

Invalid inputs inherit a data-invalid attribute.


If a submit event is fired, a valid event is triggered if the form is valid and an invalid event is triggered if the form is invalid.

You can bind to these events and fire your own callback:

  .on('invalid', function () {
    var invalid_fields = $(this).find('[data-invalid]');
  .on('valid', function () {

Using the JavaScript

Before you can use Abide you'll want to verify that both jQuery (or Zepto) and foundation.js are available on your page. You can refer to the javascript documentation on setting that up.

Just add foundation.abide.js AFTER the foundation.js file. Your markup should look something like this:



      document.write('<script src=/js/vendor/'
        + ('__proto__' in {} ? 'zepto' : 'jquery')
        + '.js><\/script>');

  <script src="js/foundation/foundation.js"></script>
  <script src="js/foundation/foundation.abide.js"></script>
  <!-- Other JS plugins can be included here -->



Required Foundation Library: foundation.abide.js

Optional JavaScript Configuration
  live_validate : true,
  focus_on_invalid : true,
  timeout : 1000,
  patterns : {
    alpha: /[a-zA-Z]+/,
    alpha_numeric : /[a-zA-Z0-9]+/,
    integer: /-?\d+/,
    number: /-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?/,

    // generic password: upper-case, lower-case, number/special character, and min 8 characters
    password : /(?=^.{8,}$)((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/,

    // amex, visa, diners
    card : /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/,
    cvv : /^([0-9]){3,4}$/,

    // http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#valid-e-mail-address
    email : /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,

    url: /(https?|ftp|file|ssh):\/\/(((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?/,
    // abc.de
    domain: /^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$/,

    datetime: /([0-2][0-9]{3})\-([0-1][0-9])\-([0-3][0-9])T([0-5][0-9])\:([0-5][0-9])\:([0-5][0-9])(Z|([\-\+]([0-1][0-9])\:00))/,
    // YYYY-MM-DD
    date: /(?:19|20)[0-9]{2}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9])|(?:(?!02)(?:0[1-9]|1[0-2])-(?:30))|(?:(?:0[13578]|1[02])-31))/,
    // HH:MM:SS
    time : /(0[0-9]|1[0-9]|2[0-3])(:[0-5][0-9]){2}/,
    dateISO: /\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}/,
    // MM/DD/YYYY
    month_day_year : /(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.](19|20)\d\d/,

    // #FFF or #FFFFFF
    color: /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/

This is a modal.

Reveal makes these very easy to summon and dismiss. The close button is simply an anchor with a unicode character icon and a class of close-reveal-modal. Clicking anywhere outside the modal will also dismiss it.

Finally, if your modal summons another Reveal modal, the plugin will handle that for you gracefully.

Second Modal...


This is a second modal.

See? It just slides into place after the other first modal. Very handy when you need subsequent dialogs, or when a modal option impacts or requires another decision.


This modal has video