#	Self Validating Forms

HTML5 includes additional features for Forms. These include:

-	Making Forms friendlier
-	Validating Form data.

Form friendliness includes:

-	The `placeholder` attribute to offer hints or explanations of requested data.
-	Specialised input types, such as dates and numbers, which offer specialised interfaces.

In a sense, data validation is also an improvement in friendliness in that it offers immediate feedback rather than requiring the user to wait until the form has been submitted and, possibly, rejected.

##	Validation

Checking the data is always an important requirement. This ensures that the data is:

-	Complete
-	Valid
-	Safe

___Note:___ _The data should always be checked at the server, as it is possible to bypass browser validation. Browser validation is purely a convenience to the user._

Traditionally, browser validation has been provided by JavaScript. Today, it is largely built in to browser in the form of HTML5 features.

JavaScript may still be required to check things that are not currently possible in HTML5 validation. For example:

-	Check whether a new email address already exists in the database
-	Check how the value in one field compares with the value of another field

What follows is a discussion of how HTML5 validation, together with CSS, can be used to make a more friendly form.
___
##	The Form

For our purposes, we will use the following sample form:

```html
<form id="contact" action="" method="post">
	<fieldset>
		<p><label>From:<br>
			<input type="email" name="from"
				placeholder="Email Address" maxlength="60" required>
			<span>Please enter a valid email address</span>
		</label></p>
		<p><label>Name:<br>
				<input type="text" name="name"
					placeholder="Full Name" maxlength="60" required
					pattern="\S+\s+\S+.*">
				<span>Please enter your full name</span>
			</label></p>
		<p><label>Phone:<br>
			<input type="text" name="phone"
				maxlength="30" placeholder="Phone (Optional)"></label></p>
		<p><label for="contact-subject">Subject:<br>
				<input type="text" name="subject"
					maxlength="60" placeholder="Subject" required>
				<span>Please enter a subject</span>
			</label></p>
		<p><label>Message:<br>
			<textarea name="message" placeholder="Message" required></textarea>
			<span>Please enter a message</span>
		</label></p>
	</fieldset>
	<fieldset id="buttons">
		<p><button type="submit" name="send">send message</button></p>
	</fieldset>
</form>
```

The `id` attribute is not of itself important for the form. However it will be used to identify this from for CSS and JavaScript.
___
###	Attributes

The form above uses the following features.

-	`type="email"`

	This actually achieves two things:
	
	-	The value will be checked whether it matches the pattern for an email address.
	-	On a mobile device, it will often show the specialised email keyboard.

-	`placeholder="…"`

	This is ghostly text which will appear when the value is empty.
	
-	`maxlength="…"` / `minlength="…"`

	Sets limits on the acceptable length of the value
	
-	`required`

	Indicates that the value cannot be empty.
	
-	`pattern="…"`

	A regular expression against which the value is checked.
	
Form elements would also include the following standard attributes:

-	`name="…"`

	The `name` attribute will be associated with the data when the form is submitted to the server, so it is essential for submitting the data. It is also possible to use this attribute locally in CSS and JavaScript.
	
-	`id="…"`

	The `id` attribute never leaves the browser, so is only used locally. Apart from its use in CSS and JavaScript, it can also be used to associate a `label` using the `for` attribute. It is not used in this example.

___

###	Constraint Validation

In modern browsers, the form data will be checked against any validation requirements. In the above list, this includes:

-	`type="email"`
-	`maxlength="…"` / `minlength="…"`
-	`required`
-	`pattern="…"`

Constraint Validation ignores empty fields, unless they are also required. Validation only applies after the user has edited the field value.

The browser will _not_ prevent the user from entering invalid data. However,

-	The browser will highlight invalid fields. Using CSS, you can change how this occurs.
-	The browser will not submit a form which is not completely valid.

####	CSS

Two pseudo classes, `:valid` and `:invalid` are available for styling:

-	All validated elements can be selected using the pseudo class
- In some browsers, you can also use the pseudo class on `fieldset` and `form` elements, but not all of them.

In addition to this you can use attribute selectors. For example:

```css
… [required] {}		/* Required fields */
… [type="email"] {}	/* Email fields */
… [name="…"] {} 	/* One specific field */
```

___
##	The CSS

CSS can be used to highlight elements, as well as help the user with validation.

###	Invalid Elements

By default, invalid elements are highlighted with a red fuzzy outline. The following CSS will remove this highlight.

Browsers vary in whether the highlight is implemented as an outline or a box shadow.

```css
/*	Validation
	================================================ */

	form#contact input:invalid,
	form#contact textarea:invalid {
		outline: none;
		box-shadow: none;
		outline-width: 0;
		/*	you may wish to add a different style instead … */
	}
```

___

###	Required Fields

Naturally, required fields should be marked as such. The following CSS creates a strong border around them.

```css
/*	Highlight Required Fields
	================================================ */

	form#contact input[required],
	form#contact textarea[required]  {
		border: medium solid #999;
	}

```

###	Validation Message

The default message for validated inputs isn’t very useful. For this reason we include a `span` element.

-	The `span` element needs to be associated with the input. The most reliable way is:
	-	Put the `span` immediately _after_ the input.
	-	Select the `span` by using the sibling selector (`+`).

All of this will take place inside the `label` element which wraps around the `input` and the `span`.

-	To position the `span`:
	-	set the containing `label` to `position: relative`; this will contain the absolute positioning inside.
	-	set the `span` to `position: absolute`, and adjust the position relative to the `label` element

We only want to display the validation message at the right time, so we hide it otherwise.

Normally, to hide an element you can use `display: none` which virtually removes the element from the layout. However, this will complicate things later, so it is easier to use `visibility: hidden`, which will simply hide it without removing it.

-	Set the `span` to `visibility: hidden`.

___

```css

/*	Validation Message Box
	================================================ */

	form#contact label {
		position: relative;
	}
	form#contact textarea+span,
	form#contact input+span {
		box-sizing: border-box;
		font-size: .8em;
		font-weight: bold;
		position: absolute;
		right: 0;
		top: .375em;
		padding: .25em .75em;
		visibility: hidden;
	}
```

###	Showing the Message

Showing the message all the time can be overwhelming. For that reason, we will show the message when the text box is in focus, or when there is an error.

-	To select for an input in focus, use `input:focus`
-	To select for an invalid input, use `input:invalid`

In both cases, we select the span using the sibling selector:

-	`input:focus+span`
-	`input:invalid+span`

When selected, the message will be displayed by setting the `visibility` property:

-	`visibility: visible`

The span will be visible when the element is in focus, or, if there is an error, always.

```css
/*	Validation Message
	================================================ */

	form#contact textarea:invalid+span,
	form#contact input:invalid+span,
	form#contact textarea:focus+span,
	form#contact input:focus+span {
		visibility: visible;
	}
```

###	Displaying Validity

If an element is invalid, we will change the message `span` to white text on a red background. Otherwise, it will remain with the default styling.

```css

/*	Correctness
	================================================ */

	form#contact textarea:invalid+span,
	form#contact input:invalid+span {
		background-color: red;
		color: white;
		border: thin solid red;
	}
```

____

####	Displaying the Status

Apart from the stark error message, we will also display a more subtle status by adding a symbol after the message. This will be regardless of whether the actual message span is visible.

The `:after` pseudo element can be used to append content to an element.

-	Refer to the pseudo element using `span:after`
-	Since the `span` itself may not be visible, make sure that the `:after` pseudo element by setting `visibility: visible`
-	Add some room with the `margin-left` property.

The status only applies when the data is valid or invalid. This does not include empty data (unless it is `required`).

The actual status will be set by setting the `content` property to something suitable.

-	Select the validated element using `:valid+span:after` or `:invalid+span:after`
-	Set the `content` to something suitable.


```css
/*	Satus
	================================================
	Possible Symbols: ✓ ⁉︎ ☹︎ ☺︎ ‼︎
	================================================ */

	form#contact :valid+span:after,
	form#contact :invalid+span:after {
		visibility: visible;
		margin-left: 1em;
	}
	form#contact :valid+span:after {
		content: "✓";
		color: green;
	}
	form#contact :invalid+span:after {
		content: "⁉︎";
		color: white;
		font-weight: bold;
	}
```
<hr class="page">

###	Disabling the Submit Button

In modern browsers, the form will not submit if there are any validation errors. However, it would be better if the actual Submit button makes the point clear.

-	To select the invalid submit button, use the `form:invalid` pseudo class.
-	Change the appearance of the button with the `opacity` property.

This changes the appearance of the button, but it is still active. To actually deactivate the button, use the `pointer-events` property, which will disable clicking:

-	Disable the button by setting `pointer-events: none`

The bad news is that Neither IE nor Edge support `form:invalid`. However, they will still not submit the form, so this is only a minor tragedy.


```css

/*	Disable Invalid Form
	================================================
	Doesn’t work on IE or Edge, of course,
	but form will still not submit.
	================================================ */

	form#contact:invalid button[type="submit"] {
		opacity: .3;
		pointer-events: none;
	}
```
