Minimalist Newsletter Subscription Form

Subtle, minimalist and intuitive UI is what I like most about web design, having the visual part of it in mind. The design is in details. Refine each of them in the context of user experience and you’re almost perfect.

Newsletter subscription form is the detail that can easily get you one step closer to the perfection. But it’s probably the most simple web form with just an input field and a submit button. "What more can you do with it?" you may ask. The first impression can be deceptive: there are quite a few things you can do with it, such as floating label, unusual visual approach, etc. But there’s one thing we’ll surely do now: hide the submit button by default and only show it if user enters the correct email address.

Minimalist Newsletter Subscription Form


Traditionally, let’s start with the minimalist markup for minimalist form:

<form class="newsletter">
  <input type="email" value="" placeholder="Enter your email address" />
  <input type="submit" value="OK" />


This sets a “trap” on the input field to check with a little help from RegExp if the typed text has “symptoms” of an actual email address. The check is performed with each symbol typed. In case of success a custom class name is added, else – removed. Just that. The rest will be handled using CSS.

With jQuery dependency

;(function( $, window, document, undefined) {
  'use strict';

  var form        = '.newsletter',
      className   = 'newsletter--active',
      email       = 'input[type="email"]';

  $(form).each(function() {
    var $form   = $(this),
        $email  = $form.find(email),
        val     = '';

    $email.on('keyup.addClassWhenEmail', function() {
      val = $email.val();
      $form.toggleClass(className, val != '' && /^([\w-\.]+@([\w-]+\.)+[\w-]{2,12})?$/.test(val));
})(jQuery, window, document);

The code is compatible with both 1.x (IE6+) and 2.x (IE9+) library branches. The namespace addClassWhenEmail for keyup event provides a possibility to remove the functionality whenever you need this, for example:

$('.newsletter input[type="email"]').off('.addClassWhenEmail');

Without dependencies JavaScript code

;(function(window, document, undefined) {
  'use strict';

  var form        = '.newsletter',
      className   = 'newsletter--active',
      email       = 'input[type="email"]',

      addEventListener = function(element, event, handler) {
        element.addEventListener ? element.addEventListener(event, handler) : element.attachEvent('on' + event, function(){; });
      forEach = function(elements, fn) {
        for(var i = 0; i < elements.length; i++) fn(elements[i], i);
      addClass = function(element, className) {
        element.classList ? element.classList.add(className) : element.className += ' ' + className;
      removeClass = function(element, className) {
        element.classList ? element.classList.remove(className) : element.className += element.className.replace(new RegExp( '(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi' ), ' ');

  forEach(document.querySelectorAll(form), function($form) {
    var $email = $form.querySelectorAll(email);

    if($email.length) {
      $email = $email[0];
      addEventListener($email, 'keyup', function() {
        $email.value != '' && /^([\w-\.]+@([\w-]+\.)+[\w-]{2,12})?$/.test($email.value) ? addClass($form, className) : removeClass($form, className);
})(window, document);

The code functions in Internet Explorer 8+. All fine with the other browsers.

If you paid attention, you saw I was using a loop. This means you can have multiple newsletter subscription forms on the page and each of them will be served. If you need different configurations for each form, check the end of the post for plugin version.


There are three variable values that you might want to change accordingly to your selectors eco-system:

var form        = '.newsletter',            // form selector
    className   = 'newsletter--active',     // class name for form when correct email is entered
    email       = 'input[type="email"]',    // email input field selector


The JavaScript part provides us with a full control of form management when there is a correct email address entered. In my case the button hidden or displayed.

.newsletter:not(.newsletter--active) input[type='submit'] {
  display: none;

I’m also using a simple CSS animation to display the button in style. Check it!

See the demo.

Plugin version

For your convenience, I wrapped the JavaScript code into a form of a plugin, so that you can have multiple instances with different options if you wish. The same settings and browser compatibility applies.

// jQuery
$('.newsletter').addClassWhenEmail( {
  className:  'newsletter--active',
  email:      'input[type="email"]'
// non-jQuery
addClassWhenEmail('.newsletter', {
  className:  'newsletter--active',
  email:      'input[type="email"]'

A thought

It’s not an absolute truth that you should always hide the button by default. The decision should be dictated by the situation: importance and context.


After publishing this post, I submitted it to Designer News and received some well-aimed feedback. Dan Klammer observed that we can control the button without JavaScript by using CSS’s pseudo-class :valid. However it’s quite poorly supported today. IE supports it from the version 10, Android from 4.4.3, not supported in Mobile Safari at all. Also, this method does not give control for the whole form, only for the button.