I’ve always tried to push the limits of what I can do with pure CSS solutions before jumping to a JavaScript implementation. Not because I think that all problems should be solved by CSS alone, I’ve actually run into many examples where a CSS only solution negatively impacts accessibility.

However, I wanted to share a quick CSS only form demo that doesn’t require any JavaScript to function.

Simple URL Validation Messaging

This demo displays a message explaining that a URL must start with either http:// or https://.

The markup:

<form class="form">
  <div class="container">
    <label for="url">Enter Your Website:</label>
    <input type="url" id="url" pattern="https?://.+" placeholder="http://www.your-website.com" aria-describedby="message">

    <div class="invalid-message" id="message">
      <p>
        Error: urls must begin with either http:// or https://
      </p>
    </div>
  </div>
</form>

To make sure that someone types in the URL correctly, a pattern attribute was added to the input, asking for a regex: "https?://.+". When the input is focused and text is entered, the message will appear to inform how to meet the field’s requirements, and then visually disappear once the requirements have been met.

To ensure the message can be conveyed to people using screen readers, an aria-describedby="message" attribute was added to the input, pointing to the <div> with an id="message".

The CSS:

Note: I’ve only included the CSS necessary to make the form function properly. The rest is all specifically for the demo’s styling.

The first rule sets up the styling for the message, but also hides it by default.

To get a fade-in effect for the message, I’m using a CSS transition on the opacity.

Pointer Events are turned off because even though the <div> is invisible, it still exists as an element in the DOM, and could potentially make content underneath it not clickable. By setting pointer-events: none; we remove this potential UX issue.

.invalid-message {
  background: rgba(255,0,0,.2);
  left: 0;
  opacity: 0;
  padding: 8px;
  pointer-events: none;
  position: fixed;
  top: 0;
  transition: opacity .2s;
  width: 100%;
}

Next, in the instance of an invalid entry, we use the general sibling selector to find the .invalid-message and set it’s opacity to 1, and pointer-events to auto, to make it visible and blocking clicks.

:invalid ~ .invalid-message {
  opacity: 1;
  pointer-events: auto;
}

In Closing…

While this example focuses on a CSS only method to display a message when filling out a text field, I hope it inspires you to play around with other ways to create CSS only alternatives for what you may otherwise default to JavaScript.