Flash messages with :target

Keep Ruby Weird uses Jekyll to build a static website. This saves us a lot of worries with speed, and is faster to develop, but is potentially limiting when it comes to functionality. This provides an interesting usability challenge.

We’ll look specifically at a simple email form. The form POSTs to FormKeep to collect submissions. This means we don’t have to run a server to gather email addresses, but also limits what we can do. For example, if this were a Rails app, we might use the flash to display a confirmation message. This is a little harder with a static page, but let’s see what we can come up with.

email form

The email form from keeprubyweird.com

Originally, we didn’t have any sort of confirmation for the email form. This led to several duplicate submissions, and to a few people asking about it on Twitter.

A solution eluded us for a while. One option was to provide a second page with a confirmation, but that wouldn’t be ideal. We could also have duplicated the content of the page with an added confirmation section, but again that’s less than a perfect solution.

An answer presented itself in the form of the :target pseudo-class. From the Mozilla Developer Network page on :target:

URIs with fragment identifiers link to a certain element within the document, known as the target element.

For instance, here is a URI pointing to an anchor named section2: http://example.com/folder/document.html#section2

Bringing it all together, we can add a confirmation paragraph right next to the email form:

<section id="got-your-email">
  <h2>Eventually we'll tell you more.</h2>
  <form ...>
    <label for="email">Enter your email address</label>
    <input type="text" id="email">
    <input type="submit" class="align-center">
  </form>
  <p class="confirmation">
    Thank you! We'll let you know when we have news about tickets, etc.
  </p>
</section>

Using CSS, we can target the form section, select the confirmation, and hide it using display: none. We can then add a selector for the section element with the :target pseudo-class to display the confirmation again.

#got-your-email .confirmation {
  display: none;
  color: #b11a29;
}

#got-your-email:target .confirmation {
  display: inherit;
}

So on most page loads, the confirmation is hidden. We change the redirect URL on FormKeep to add the fragment #got-your-email and we have a cheap confirmation page!

email form with visible confirmation

Our static page now has dynamic content, with no JavaScript in sight.