CSS Tips and Tricks for Customizing Error Messages!

Error: Your validation needs spicing up! In this post, we’re going to completely customize the look of our form’s error messages with just a sprinkling of CSS. CSS is simply a set of text rules that you can write to tell browsers how to style websites. This post assumes no knowledge of CSS, but if you are a super thorough type of person, check out my general introduction to CSS.

In order to have error messages to style, we need to have errors; and in order to have errors, we need rules. Below, I’ve set up a simple form that requires everything except for the Name field. So, if someone tries to submit this form without filling out the required fields, they’ll see a bunch of pre-customized error messages with bright red backgrounds:

Before

See the Pen OvdZOO by Cognito Forms (@CognitoForms) on CodePen.

After

This is the same form, but with that sprinkling of CSS that I mentioned earlier. When you try to submit this form, you’ll notice that the error messages look a little different:

See the Pen mxvdGV by Cognito Forms (@CognitoForms) on CodePen.

Groundwork

A few things we need to cover before getting into the styling:

No Iframes

The CSS we’re writing will only affect the form if it’s seamlessly embedded on the page, and not in an iframe. Iframes are like tall fortress walls that keep out things like hoards of CSS lines; sometimes that’s great, but not in this case.

This CSS Can Go Anywhere

You can put this CSS anywhere on the webpage that hosts the form, either through a reference to an external CSS doc, or by placing the style rules directly on the same page (learn more about the mechanics of these options here). Normally, the order of CSS does matter, with rules that come later on the page tending to override earlier rules. But I’ll write this example in a way that will force our custom rules to be applied no matter where they are.

Selecting Elements

The Class Names

HTML elements can have class names for CSS rules to hook onto. Cognito Forms have several class names that allow you to do this very thing. The ones we’ll be making use of are:

  • c-error - This class name is added to all field containers if that field has an error. In our example, this class will get applied to the parent container after the user tries to submit an invalid email address.
  • c-validation - This class name is on the container of the error message. It isn’t visible until an error has been made. The validation message is contained by the element that will have the c-error class.
  • c-label - This is the container of the field label (which is “Email” in this case). Labels are also contained by the element that will have the c-error class.

    Selectors

An email field with an error message underneath. In my example, I’m styling four different things: the c-validation container, a triangle/arrow extending from that container, the asterisk next to “Email” that indicates the field is required, and the text field itself. These are the selectors we’re going to be using:

  • .c-error .c-validation The dot in front of each class name just denotes that c-error and c-validation are class names. The order of the class names and how they are separated by a space mean that c-validation is contained by an element that has the class name c-error. All styles that we only want to take effect when there is an error will be prefaced with .c-error. Since this class is only on fields when they have errors, our styles won’t appear by default.
  • .c-error .c-validation:before This is where the arrow/triangle is going to be. If you don’t want an arrow like this, then you don’t need the equivalent in your CSS. The “:before” means something like, “Create a pseudo-element that doesn’t really exist at the very beginning of c-validation.” The pseudo-element can be styled just like a real element, even though it doesn’t appear anywhere in the HTML.
  • .c-label:after This is just like the “:before” pseudo-element, but it comes at the end of .c-label. This is how Cognito places the asterisks at the end of required labels. All we’re going to do with this is change the color of the asterisk. Since this asterisk shows up all the time on required fields, whether they have errors or not, we don’t want to qualify this by prefacing with the c-error class.
  • .c-error input, .c-error select, .c-error .c-choice-option The commas here separate what are really three different selectors, all to only take effect with an error. “input” selects things like text inputs, “select” selects dropdown menus, and “.c-choice-option” selects the container of check boxes and radio buttons in Cognito Forms. We’re going to color the text and background color of all these things, as well as the border of inputs and selects.

The CSS

Here’s the CSS to style the error message itself:

.c-error .c-validation{
  background: #c51244 !important;
  padding: 10px !important;
  border-radius: 0 !important;
  position: relative; 
  display: inline-block !important;
  box-shadow: 1px 1px 1px #aaaaaa;
  margin-top: 10px;
}

We’ve already talked about the class “c-validation”. Every element that has that class name inside of an element with the c-error class will get the style rules inside the curly braces. I’ll go through them in order (the order doesn’t matter to the browser):

  • background #c51244 is the code for the dark red I’ve chosen. Usually you don’t just know these codes off the top of your head; you can get them from a good color picker (like in Photoshop), or a website like this one. The “!important” at the end of this line means, “Hey, I don’t care what color Cognito Forms set as the background color, my color is more important!” Lines that need to override Cognito’s CSS will have this.
  • padding This line just indicates that there should be a space of 10 pixels all the way around the error text and the edge of the box.
  • border-radius By default, error messages have rounded corners on the bottom. By setting border-radius to 0, we are setting sharp corners instead.
  • position This will help us when we place the arrow/triangle. I’ll explain this further below.
  • box-shadow This adds a shadow to the box. I’ve set it to be the color #aaaaaa (gray), with 1 pixel on the right, 1 pixel on the bottom, and 1 pixel of blurriness. Learn more about the box-shadow property.
  • margin-top This gives 10 pixels of space above the box. This is leaving room for the arrow we’ll talk about next.

Here’s the CSS for the arrow/triangle:

.c-validation:before{
  content: '';  
  width: 0;  
  height: 0;  
  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
  border-bottom: 10px solid #c51244;
  position: absolute;  
  top: -10px; 
}

If you are curious about the first 6 properties of this, check out this classic explanation. Suffice it to say, the first 6 lines are for making a triangle.

position: absolute” takes the triangle out of the flow of the document and layers it on top, preventing it from taking up space and pushing other elements around. “top: -10px” nudges it up 10 pixels. We needed the parent container to have “position: relative” for this to work right—that’s why we added it above.

The CSS to change the color of the required asterisk to match the c-validation box color is simply:

.c-label:after{
  color: #c51244 !important;
}

Note that since the color of the asterisk isn’t conditioned on whether there is an asterisk or not, we didn’t include the c-error class.

And finally, to color the background and text of the inputs, selects, and check box containers:

.c-error input, .c-error select, .c-error .c-choice-option{ 
  background: #fff0f4; 
  color: #c51244;
}

Plus, we can also color the border of just inputs and selects with:

.c-error input, .c-error select{ 
  border: 1px solid #c51244 !important; 
}

And that’s it! Obviously you can copy what I did here exactly, but that’s boring. I hope you’ll take what you learned here and put your own spin on it. If you come up with something interesting, why not post it in the comments for others to see? If you have questions, feel free to post those in the comments too and I’ll be happy to help!