Semantic HTML-CSS Form
Tags: beginners, html, css
Published: 2020-10-31 14:37:49

# Semantic HTML-CSS Form

We will create a simple 'user registration form' with semantic (using 'proper' tags in a right way) markup and with basic accessibility ♿ baked right in.


# Getting Started

## Starter Repo

I will be using my ['Front End Starter' repo.](https://github.com/manavm1990/front-end-starter) Here's a post I wrote about it: {% link https://dev.to/codefinity/html-css-js-starter-repo-1ii2 %}

For the rest of this post, I will assume that you are using this or something similar.

## Font/Title

As per the `TODO`s shown in 'index.html,' we should add some type of [Google Fonts](https://fonts.google.com/)

There's a `link` to a special CSS 💄 file from Google that belongs in our `<head>`. We also need to add the provided `font-family` rule to a `body` _CSS selector._

![Add Google Fonts](https://dev-to-uploads.s3.amazonaws.com/i/r4fm7y1rjn8cu1d7yyce.gif)

We should also replace the `<title>`. For Search Engine Optimization (SEO) purposes (not that that matters here - it's FYI), we should try to match up `<title>` with our `<h1>`. 

```html
<title>User Registration</title>
  </head>
  <body>
    <h1>User Registration</h1>
```


# HTML

HyperText Markup Language has one essential job - to *describe* the content on the page 📃. Each HTML 💬 tag should serve that purpose and nothing more!

## Emmet.io

Assuming that you are using VS Code (and you probably should be - it's damn near the industry-standard text editor for web dev!), you have 'built-in' access to something called 'Emmet.' It's a handy tool that saves us a lot of typing for HTML code.

Case and point, enter this: `form>(div>label+input)*5+button`
 under the `<h1>` tag and press 'TAB' and 'RETURN' when you are finished.

If this doesn't work, you may have to hit ⬇️ to select the completion that says, 'Emmet Abbreviation', first.

![Emmet](https://dev-to-uploads.s3.amazonaws.com/i/gpufwxrcm9zlf2dqi3d2.gif)

## `<form>`

Remove the `action` _attribute_ from the opening `<form` - we don't need that spit!

Each `for` _attribute_ inside of the `label` should corresponding with a matching `id` _attribute_ in an `input`.

Add a `placeholder` _attribute_ to each `input` to indicate what it's for. 

**The `label` is for _accessibility_ ♿ purposes. We will use CSS to 'hide' it.**

`<label for="name">Name:</label><input type="text" placeholder="Name" id="name" required/>`

Following this pattern 👆🏽, in addition to a 'name,' set up our form to take in: `✉️`, `☎️`, `username` and `password`.

While you're at it, add `required` to each `input`. This will simplify our lives by letting the browser confirm that the fields are filled in before the user can submit. _Note that this is not usually sufficient by itself for a 'real' app. Additional client-side and/or server-side JS would be required as a 'backup.'_

For, ✉️ and `password`, you should change the `type` _attribute_ in those `input`s from `"text"` to `"email"` and `"password"` respectively.

For ☎️, the `type` is: `tel`: `<label for="fone">Phone</label><input type="tel" placeholder="Phone" id="fone" required/>`

For the `button` - just put some text like, "Register Now!". `<button>Register Now!</button>`

# Check ✅ Out How It Looks 👀 in the Browser

Go back to your terminal and do: `npm start`. This will fire up [`browser-sync`](https://browsersync.io/) - a local webserver with 'hot 🔥 reloading.' 

It doesn't look 👀 gr8 - that's we need CSS 💄.

# CSS

Let's also open this up on a simulated mobile screen by using Dev Tools. At least in Chrome, this is done on Mac with: 'COMMAN+OPTION+I' and then 'COMMAND+SHIFT+M'. From there, just pick one of the 📱 sizes - whatever you want.

![Responsive Dev Tools](https://dev-to-uploads.s3.amazonaws.com/i/wacpqtok2z39n3o96zmq.gif)

Let's establish a 'base font-size' by adding: `font-size: 10px` under the `body` selector. This will carry over to our relative CSS units for things like `margin` and `padding` later.

## Get Rid of Labels

```css
label {
  left: -9999px;
  position: absolute;
  top: -9999px;
}
```

`position: absolute` takes the `label`s out of their normal 'positioning' and allows us to directly move them all really far off of the screen.

## Centering

You might think 🤔 that we can just throw a `text-align: center` under `body` and be done. Although that _would_ work here, we are trying to learn some better habits that will carry over to larger projects.

`text-align` should be used for aligning...text 😼. We'll align our elements with `display: flex` 👈🏽 That goes under `body`.

Having a look 👀 in our browser, we see that the `h1` and the `form` are sort of 'side-by-side.'

By default, applying `display: flex` makes all of the _direct children_ - of an _element_ line up in a row. But, creating this 'parent-child' 'flex' relationship allows us to easily align things how we want to. Just put: `flex-direction: column` underneath `body`. Now, things are looking 👀 better.

Now, `align-items: center;` under `body`.

Now, let's get the `button` in the `form` centered.

```css
form {
  align-items: center;
  display: flex;
  flex-direction: column;
}
```

### ♻️

In fact, to avoid some of the rule duplications, consolidate:

```css
body,
form {
  align-items: center;
  display: flex;
  flex-direction: column;
}
```

## Spacing

```css
button,
input {
  /* top/bottom left/right */
  margin: 4px 0;
}
```

## `button`

```css
button {
  background-color: #48c774;
  border-color: transparent;
  border-radius: 4px;
  color: white;
  padding: 0.5rem;
}
```

`border-color: transparent` is to get rid of that ugly default behavior. 

I encourage you to tinker with these other values 👆🏽 and you'll soon see what they do. 

There's still a lot more that could be done or course, but for the purposes of a form, this is styled well enough, for now.