The form element

After learning about the form attribute, it is now time to have a look at the form element. While most web developers know how to use the form element, I am pretty sure you will learn something new today. In this article you will learn how to use the form element, what attributes are available and how to style it.

Basics #

<label for="name">Name</label>
<input name="name" id="name">


For the most basic form you don't need to set any attributes. This form will send a GET request to the current URL. As you rarely want this default behaviour, let's see what attributes are available to change it.

Attributes #

In addition to the global attributes there are various other attributes available for the form element.

action #

<form action="/whatever">


By default, the form will be sent to the current URL. By using the action attribute you can specify the URL which should be used instead.

Default value: current URL

method #

<form method="post">


The three possible values for method are get, post and surprisingly not put or delete, but dialog. Using post will send the form data as the request body. Using the get method will append the form data to the URL with a ? separator.

The dialog method will close the dialog containing the form.

<dialog open>
<p>Never show dialogs on page load!</p>
<form method="dialog">

Default value: GET

autocomplete #

By default, modern browsers try to be helpful and offer autocomplete.

<label for="email">Email</label>
<input id="email" type="email">

For this form, most browser will automatically offer autofill for your email address. You can however disable this by using the autocomplete attribute.

<form autocomplete="off">
<label for="email">test</label>
<input id="email" type="email">

Now, the user won't get autofill for the email input.

There is however one exception, most browsers ignore this for suspected login forms.

Default value: on

enctype #

<form enctype="multipart/form-data">


enctype is the MIME type of the form submission. If the form contains an input with type="file", you should set this to multipart/form-data, in other cases the default one is what you want. As a third possible value there is text/plain, which should however only be used for debugging purposes.

Default value: application/x-www-form-urlencoded

accept-charset #

<form accept-charset="utf-8 iso-8859-1">


By using accept-charset you can define space-separated character encodings the server accepts. Not sure how this can ever be helpful, but I don't know about any use case, so some probably make good use of it.

Default value: same as the current page

novalidate #

Next is the novalidate attribute, which is a Boolean attribute. By setting it you instruct the browser to always submit the form, regardless if all form elements are valid or not.

<form novalidate>
<label for="name">Name</label>
<input name="name" id="name" required>

By default, you won't be able to submit this form if you leave the name input empty, but by setting novalidate the browser ignores the validation and will let you submit the form nevertheless.

Default value: not set

rel #

There are various values you can use for the rel attribute for the form element.

<form rel="search">


Default value: not set

target #

<form target="_blank">


You can specify where to display the response after submitting the form. As with target used on links you should also stick with the default here if you don't have a very good reason to not.

Default value: _self

autocapitalize #

<form autocapitalize="words">


The last attribute in our list is the non-standard autocapitalize attribute. It is currently only supported by iOS Safari and controls how textual form elements should be automatically capitalized. As it is not in any specification I would avoid using it for now.

Styling #

Now that we learned about all the attributes, let's see how we can style the form attribute.

Defaults #

The default browser styles for the form element are the same as for the div element. You can position it however you want, all inheritable properties will get inherit from child elements and you can use pseudo elements (::before/::after).

In addition to this you can use :valid and :invalid CSS pseudo-classes.

:valid/:invalid #

<label for="name">Name</label>
<input id="name" required type="text">
form:invalid {
border: 2px solid red;

Here the name input is required, so the form will be invalid if the input is empty and the form will get a red border. Once you fill in the input, it will be valid and :invalid won't apply any more.

JavaScript #

An article about the frontend without mentioning JavaScript? Yes, this article is about HTML and CSS, but worry not, in part two we will talk about the form element and JavaScript. Subscribe to the RSS feed so you don't miss it.

Resources #


HTML Living Standard:

Autofill: What web devs should know, but don’t: