How to style forms with CSS: A beginner’s guide
Tags: css, tutorial
Published: 2020-04-15 13:51:32

---
title: How to style forms with CSS: A beginner’s guide
published: true
date: 2020-03-23 16:00:30 UTC
tags: css, tutorial
canonical_url: https://blog.logrocket.com/how-to-style-forms-with-css-a-beginners-guide/
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/eovw1sezwhviumgl2smt.png
---
**Written by [Supun Kavinda](https://blog.logrocket.com/author/supunkavinda/)**✏️

Apps primarily collect data via forms. Take a generic sign-up form, for example: there are several fields for users to input information such as their name, email, etc.

In the old days, websites just had plain, boring HTML forms with no styles. That was before CSS changed everything. Now we can create more interesting, lively forms using the latest features of CSS.

Don’t just take my word for it. Below is what a typical HTML form looks like without any CSS.

![Simple HTML Form](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2020/03/html-form.png?resize=441%2C58&ssl=1)

Here’s that same form jazzed up with a bit of CSS.

![Form Styled With CSS](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2020/03/form-styled-with-css.png?resize=539%2C179&ssl=1)

In this tutorial, we’ll show you how to recreate the form shown above as well as a few other amazing modifications you can implement to create visually impressive, user-friendly forms.

We’ll demonstrate how to style forms with CSS in six steps:

1. Setting [`box-sizing`](https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing)
2. CSS selectors for input elements
3. Basic styling methods for text input fields
4. Styling other input types
5. UI pseudo-classes
6. Noncustomizable inputs

Before we dive in, it’s important to understand that there is no specific style for forms. The possibilities are limited only by your imagination. This guide is meant to help you get started on the path to creating your own unique designs with CSS.

Let’s get started!

[![LogRocket Free Trial Banner](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/f760c-1gpjapknnuyhu8esa3z0jga.png?resize=1200%2C280&ssl=1)](https://logrocket.com/signup/)

## 1. Setting `box-sizing`

I usually set `* {box-sizing:border-box;}` not only for forms, but also webpages. When you set it, the width of all the elements will contain the padding.

For example, set the width and padding as follows.

```jsx
.some-class {
  width:200px;
  padding:20px;
}
```

The `.some-class` without `box-sizing:border-box` will have a width of more than `200px`, which can be an issue. That’s why most developers use `border-box` for all elements.

Below is a better version of the code. It also supports the `:before` and `:after` pseudo-elements.

```jsx
*, *:before, *:after {
  box-sizing: border-box;
}
```

Tip: The `*` selector selects all the elements in the document.

## 2. CSS selectors for input elements

The easiest way to select input elements is to use [CSS attribute selectors](https://dev.to/bnevilleoneill/advanced-css-selectors-for-common-scenarios-3gl6).

```jsx
input[type=text] {
  // input elements with type="text" attribute
}
input[type=password] {
  // input elements with type="password" attribute
}
```

These selectors will select all the input elements in the document. If you need to specify any selectors, you’ll need to add classes to the elements.

```jsx
<input type="text" class="signup-text-input" />
```

Then:

```jsx
.signup-text-input {
   // styles here
}
```

## 3. Basic styling methods for single-line text input fields

Single-line fields are the most common input fields used in forms. Usually, a single-line text input is a simple box with a border (this depends on the browser).

Here’s the HTML markup for a single-line field with a placeholder.

```jsx
<input type="text" placeholder="Name" />
```

It will look like this:

![Default HTML Input Field](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2020/03/default-html-input-field.png?resize=214%2C59&ssl=1)

You can use the following CSS properties to make this input field more attractive.

- Padding (to add inner spacing)
- Margin (to add a margin around the input field)
- Border
- Box shadow
- Border radius
- Width
- Font

Let’s zoom in on each of these properties.

### Padding

Adding some inner space to the input field can help improve clarity. You can accomplish this with the `padding` property.

```jsx
input[type=text] {
  padding: 10px;
}
```

![Input Field With Padding](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2020/03/input-field-padding.png?resize=200%2C53&ssl=1)

### Margin

If there are other elements near your input field, you may want to add a margin around it to prevent clustering.

```jsx
input[type=text] {
  padding:10px;
  margin:10px 0; // add top and bottom margin
}
```

![Input Field With and Without Margins](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2020/03/input-field-margin.jpeg?resize=700%2C400&ssl=1)

### Border

In most browsers, text input fields have borders, which you can customize.

```jsx
.border-customized-input {
   border: 2px solid #eee;
}
```

You can also remove a border altogether.

```jsx
.border-removed-input {
  border: 0;
}
```

Tip: Be sure to add a background color or `box-shadow` when the border is removed. Otherwise, users won’t see the input.

Some web designers prefer to display only the bottom border because feels a bit like writing on a line in a notebook.

```jsx
.border-bottom-input {
  border:0; // remove default border
  border-bottom:1px solid #eee; // add only bottom border
}
```

### Box shadow

You can use the CSS [`box-shadow`](https://www.w3schools.com/cssref/css3_pr_box-shadow.asp) property to add a drop shadow. You can achieve a range of effects by playing around with the property’s five values.

```jsx
input[type=text] {
  padding:10px;
  border:0;
  box-shadow:0 0 15px 4px rgba(0,0,0,0.06);
}
```

![Input Field With Box Shadow](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2020/03/input-field-box-shadow.png?resize=251%2C142&ssl=1)

### Border radius

The `border-radius` property can have a massive impact on the feel of your forms. By curving the edges of the boxes, you can significantly alter the appearance of your input fields.

```jsx
.rounded-input {
  padding:10px;
  border-radius:10px;
}
```

![Input Field With Border Radius](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2020/03/input-field-border-radius.png?resize=356%2C122&ssl=1)

You can achieve another look and feel altogether by using `box-shadow` and `border-radius` together.

![Input Field With Border Radius and Box Shadow](https://i1.wp.com/blog.logrocket.com/wp-content/uploads/2020/03/input-field-border-radius-box-shadow.png?resize=388%2C79&ssl=1)

### Width

Use the `width` property to set the width of inputs.

```jsx
input {
  width:100%;
}
```

### Fonts

Most browsers use a different font family and size for form elements. If necessary, we can inherit the font from the document.

```jsx
input, textarea {
  font-family:inherit;
  font-size: inherit;
}
```

## 4. Styling other input types

You can style other input types such as text area, radio button, checkbox, and more. Let’s take a closer look.

### Text areas

Text areas are similar to text inputs except that they allow multiline inputs. You’d typically use these when you want to collect longer-form data from users, such as comments, messages, etc. You can use all the basic CSS properties we discussed previously to style text areas.

The [`resize`](https://www.w3schools.com/cssref/css3_pr_resize.asp) property is also very useful in text areas. In most browsers, text areas are resizable along both the x and y axes (value: `both`) by default. You can set it to `both`, `horizontal`, or `vertical`.

Check out this text area I styled:

{% codepen https://codepen.io/SupunKavinda/pen/dyomzez %}

<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

In this example, I used `resize:vertical` to allow only vertical resizing. This practice is used in most forms because it prevents annoying horizontal scrollbars.

Note: If you need to create auto-resizing text areas, you’ll need to use a [JavaScript approach](https://stackoverflow.com/questions/454202/creating-a-textarea-with-auto-resize), which is outside the scope of this article.

### Checkboxes and radio buttons

The default checkbox and radio buttons are hard to style and require more complex CSS (and HTML).

To style a checkbox, use the following HTML code.

```jsx
<label>Name
  <input type="checkbox" />
  <span></span>
</label>
```

A few things to note:

- Since we’re using `<label>` to wrap the `<input>`, if you click any element inside `<``label``>`, the `<input>` will be clicked
- We’ll hide the `<input>` because browsers don’t allow us to modify it much
- `<span>` creates a custom checkbox
- We’ll use the `input:checked` [pseudo-class selector](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Selectors/Pseudo-classes_and_pseudo-elements) to get the checked status and style the custom checkbox

Here’s a custom checkbox (see the comments in the CSS for more explanations):

{% codepen https://codepen.io/SupunKavinda/pen/yLNKQBo %}

Here’s a custom radio button:

{% codepen https://codepen.io/SupunKavinda/pen/eYNMQNM %}
 
We used the same concept (`input:checked`) to create custom elements in both examples.

In browsers, checkboxes are box-shaped while radio buttons are round. It’s best to keep this convention in custom inputs to avoid confusing the user.

### Select menus

Select menus enable users to select an item from multiple choices.

```jsx
<select name="animal">
    <option value="lion">Lion</option>
    <option value="tiger">Tiger</option>
    <option value="leopard">Leopard</option>
</select>
```

You can style the `<select>` element to look more engaging.

```jsx
select {
  width: 100%;
  padding:10px;
  border-radius:10px;
}
```

![Styled Select Element](https://i1.wp.com/blog.logrocket.com/wp-content/uploads/2020/03/select-element-styled.png?resize=465%2C156&ssl=1)

However, you cannot style the dropdown (or `<option>` elements) because they are styled by default depending on the OS. The only way to style those elements is to use [custom dropdowns with JavaScript](https://medium.com/@kyleducharme/developing-custom-dropdowns-with-vanilla-js-css-in-under-5-minutes-e94a953cee75).

### Buttons

Like most elements, buttons have default styles.

![Default Button](https://i1.wp.com/blog.logrocket.com/wp-content/uploads/2020/03/default-button.png?resize=88%2C45&ssl=1)

```jsx
<button>Click Me</button>
```

Let’s spice this up a bit.

```jsx
button {

  /* remove default behavior */
  appearance:none;
  -webkit-appearance:none;

  /* usual styles */
  padding:10px;
  border:none;
  background-color:#3F51B5;
  color:#fff;
  font-weight:600;
  border-radius:5px;
  width:100%;

}
```

![Button Customized With CSS](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2020/03/customized-button.png?resize=601%2C75&ssl=1)

## 5. UI pseudo-classes

Below are some [UI pseudo-classes](https://developer.mozilla.org/en-US/docs/Learn/Forms/UI_pseudo-classes) that are commonly used with form elements.

These can be used to show notices based on an element’s attributes:

- `:required`
- `:valid` and `:invalid`
- `:checked` (we already used this)

These can be used to create effects on each state:

- `:hover`
- `:focus`
- `:active`

### Generated messages with `:required`

To show a message that input is required:

```jsx
<label>Name
  <input type="text">
  <span></span>
</label>
<label>Email
  <input type="text" required>
  <span></span>
</label>


label {
  display:block;
}
input:required + span:after {
  content: "Required";
}
```

![CSS-Generated Content Alerting the User of a Required Input Field](https://i1.wp.com/blog.logrocket.com/wp-content/uploads/2020/03/css-generated-content-input-required.png?resize=286%2C62&ssl=1)

If you remove the `required` attribute with JavaScript, the `"Required"` message will be removed automatically.

Note: `<input>` cannot contain other elements. Therefore, it cannot contain the `:after` or `:before` pseudo-elements. Hence, we need to use another `<span>` element.

We can do the same thing with the `:valid` and `:invalid` pseudo-classes.

### `:hover` and `:focus`

`:hover` selects an element when the mouse pointer hovers over it. `:focus` selects an element when it is focused.

These pseudo-classes are often used to create transitions and slight visual changes. For example, you can change the width, background color, border color, shadow strength, etc. Using the `transition` property with these properties makes those changes much smoother.

Here are some hover effects on form elements (try hovering over the elements).

{% codepen https://codepen.io/SupunKavinda/pen/yLNKZqg %}
  
When users see elements subtly change when they hover over them, they get the sense that the element is actionable. This is an important consideration when designing form elements.

Did you notice that (in some browsers) a blue outline appears when focusing on form elements? You can use the `:focus` pseudo-class to remove it and add more effects when the element is focused.

The following code removes the focus outline for all elements.

```jsx
*:focus {outline:none !important}
```

To add a focus outline:

```jsx
input[type=text]:focus {
  background-color: #ffd969;
  border-color: #000;
  // and any other style
}
```

Have you seen search inputs that scale when focused? Try this input.

{% codepen https://codepen.io/SupunKavinda/pen/KKpoJJa %}

## 6. Noncustomizable inputs

Styling form elements has historically been a tall order. There are some form elements that we don’t have much control over styling. For example:

- `<input type="color">`
- `<input type="file">`
- `<progress>`
- `<option>`, `<optgroup>`, `<datalist>`

These elements are provided by the browser and styled based on the OS. The only way to style these elements is to use custom controls, which are created using stylable HTML elements such as `div`, `span`, etc.

For example, when styling `<input type="file">`, we can hide the default input and use a custom button.

Custom controls for form elements are developed for most major JavaScript libraries. You can find them on [GitHub](https://github.com/).

## Conclusion

You should now understand how to style simple form elements and how to use custom controls when browser input fields are difficult to style. As I stated at the beginning of this post, these are only the basic building blocks of CSS form styling. You should use these tips as a foundation to let your imagination run wild.

As a closing tip, remember to make all your forms [responsive](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Responsive_Design).

Looking for more form design inspiration? Check out this [CodePen collection](https://codepen.io/collection/KuDsH/).

* * *
## Is your frontend hogging your users' CPU?

As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, [try LogRocket.](https://logrocket.com/signup/) 

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/403rye2ptzx994uhktk1.png)

[LogRocket](https://logrocket.com/signup/) is like a DVR for web apps, recording everything that happens in your web app or site. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.

Modernize how you debug web apps — [Start monitoring for free.](https://logrocket.com/signup/)
* * *

The post [How to style forms with CSS: A beginner’s guide](https://blog.logrocket.com/how-to-style-forms-with-css-a-beginners-guide/) appeared first on [LogRocket Blog](https://blog.logrocket.com).