Tailwind CSS Contact Form with a node.js Form Handler - Part 1
Tags: tailwindcss, css, html, forms
Published: 2021-02-10 15:32:03

**The chances are, if you have a website you’ll need a way for your customers to be able to contact you. Step up the humble** ***contact form.***

Using some basic HTML and the power of Tailwind CSS, we can quickly build out a stylish contact form and add it to our website.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/44ceypx4gilzbgdhyo23.jpg)

We’ll also need a way to receive any form requests, so in ***Part 2*** we’ll build a simple mail server API using node.js, Express and SendGrid.

>Check out the [DEMO](https://codepen.io/brandymedia/full/MWbaxpE)
Download the [SOURCE CODE](https://github.com/brandymedia/tailwind-contact-form)

{% github brandymedia/tailwind-contact-form no-readme %}

##Front-end first

Both our front-end (contact form) and back-end (form handler) are going to be using ***npm*** for some dependencies, so make sure you have the latest version installed locally on your computer.

npm comes bundled with ***node.js***, so you can get the download from [nodejs.org](https://nodejs.org/).

Once you have node.js & npm installed locally, create a new folder for your project `mkdir contact-form`.

Next, navigate to our project with `cd contact-form`.

Now let’s initiate npm with the `npm init -y` command in the terminal. The `-y` flag simply answers ***yes*** to all the default questions, feel free to manually set this up by omitting this flag, or in the package.json file later.

Before we go any further, I just wanted to point out that Tailwind CSS can be used by simply using their dedicated CDN, as per their [docs](https://tailwindcss.com/docs/installation#using-tailwind-via-cdn) - however, this does not give us all of the functionality we need and is not recommended.

Instead, we are going to install this and use it as a [PostCSS plugin](https://tailwindcss.com/docs/installation#installing-tailwind-css-as-a-post-css-plugin).

So, let’s get the dependencies we require installed with `npm i tailwindcss@latest @tailwindcss/forms postcss@latest autoprefixer@latest postcss-cli`.

Once this has finished installing, we need to set up a couple more things before we can code our form.

Open the `package.json` file, as we need to add a couple of scripts to allow us to compile our Tailwind CSS later.

```javascript
"build": "postcss ./src/styles.css -o ./public/dist/styles.css",
"prod": "NODE_ENV=production postcss ./src/styles.css -o ./public/dist/styles.css"
```

As a follow on from my last post [Build a JavaScript and Tailwind CSS Theme Switcher](https://dev.to/brandymedia/build-a-javascript-and-tailwind-css-theme-switcher-4hbc) I want to be able to use ***dark*** mode, so we need to set this up in Tailwind.

{% link https://dev.to/brandymedia/build-a-javascript-and-tailwind-css-theme-switcher-4hbc %}

In your terminal, run `npx tailwindcss init -p` to create our tailwind.config.js and postcss.config.js files, then open up the `tailwind.config.js` file.

First add the forms plugin.

```javascript
plugins: [
    require('@tailwindcss/forms')
  ],
```

Then change `darkMode` to `class`.

Before we can compile our CSS, we need to create the source CSS file.

Create the src folder `mkdir src` then `cd src` in to the directory and create the CSS file `touch styles.css`.

Add the included to the styles.css file

```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

Then run `npm run build`. This should output our compiled styles to our `public/dist/styles.css` file.

With all the setup out of the way, let’s get some coding done. Create an `index.html` file in our ***public*** directory `touch public/index.html` and then open it up.

As I’m using Visual Studio Code as my text editor, I'll add my HTML boilerplate code by pressing `!` and then `tab`.

Next, update the `title`, add our CSS as a `link` tag and pull in Font Awesome.

```html
<title>HTML & Tailwind CSS Contact Form</title>
<link rel="stylesheet" href="dist/styles.css">
<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous"/>
```

Tailwind CSS is a bit different from other CSS frameworks that you may have used before, such as ***Bootstrap*** or ***Foundation***. Tailwind CSS does not assume any styles on your HTML elements.

With this in mind, we’ll need to style each of our HTML elements with CSS classes, as they will not have any default styles out-of-the-box. As this will all be controlled by adding ***utility*** classes to our HTML markup, this means we won’t need to write a single line of CSS.

The structure of our HTML is going to be straight forward, as we’re just going to create a form centralised on the page. Let’s create the bare-bones.

```html
<form>
	<div>
		<!-- heading -->
	</div>
	<div>
		<!-- message field -->
	</div>
	<div>
		<!-- name field -->
	</div>
	<div>
		<!-- email field -->
	</div>
	<div>
		<!-- button -->
	</div>
</form>
```

This now gives us a good skeleton - let’s start populating these sections with our content.

Let’s create the styles for our ***form*** element. Remember, we do this by adding various CSS classes directly to the HTML markup.

```html
<form action="" class="mt-20 p-10 max-w-xl mx-auto shadow-md sm:border-0 md:border md:border-gray-900 md:dark:border-gray-100 bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-gray-100">
	<!-- form content -->
</form>
```

There’s quite a few classes required to get the desired design, so I’ll briefly explain what each one does. If you need further clarification, then check out the [Tailwind CSS Documentation](https://tailwindcss.com/docs).

```html
my-20 <!-- adds 5rem vertical margin -->
p-10 <!-- adds 2.5rem padding -->
max-w-xl <!-- sets the max width to 36rem  -->
mx-auto <!-- sets left and right margin auto to center -->
shadow-md <!-- adds a medium box shadow -->
sm:border-0 <!-- removes any border on small devices -->
md:border <!-- adds a border on medium devices and above -->
md:border-gray-900 <!-- sets the border color to a dark grey (light mode) -->
md:dark:border-gray-100 <!-- sets the border color to a light grey (dark mode) -->
bg-gray-100 <!-- sets the background color to a light grey (light mode) -->
dark:bg-gray-800 <!-- sets the background color to a dark grey (dark mode) -->
text-gray-900 <!-- sets the text color to a dark grey (light mode) -->
dark:text-gray-100 <!-- sets the text color to a light grey (dark mode) -->
```

Now that you have a better idea how to style HTML elements with Tailwind CSS’s ***utility*** classes, I’ll give you the rest of the markup verbatim. Feel free to look over the styles and reference these in the [Tailwind CSS Documentation](https://tailwindcss.com/docs) to see what each class does.

```html
<body class="bg-white dark:bg-gray-900">
    <div class="flex w-full justify-around items-center bg-gray-100 dark:bg-gray-900 text-gray-900 dark:text-white py-5">
        <div class="theme-switcher">
            <button class="theme-switcher-button theme-switcher-light bg-gray-200 border-gray-200 border-2 dark:bg-black dark:border-black p-2 focus:outline-none" title="Light"><i class="fas fa-sun pointer-events-none"></i> Light</button><button class="theme-switcher-button theme-switcher-dark bg-gray-200 border-gray-200 border-2 dark:bg-black dark:border-black p-2 focus:outline-none" title="Dark"><i class="fas fa-moon pointer-events-none"></i> Dark</button><button class="theme-switcher-button theme-switcher-auto bg-gray-200 border-gray-200 dark:bg-black border-2 dark:border-black p-2 focus:outline-none" title="Auto"><i class="fas fa-adjust pointer-events-none"></i> Auto</button>
        </div>
    </div>
    <form action="" class="my-20 p-10 max-w-xl mx-auto shadow-md sm:border-0 md:border md:border-gray-900 md:dark:border-gray-100 bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-gray-100">
        <div class="mb-10">
            <h1 class="font-bold text-4xl mb-3">Get in touch</h1>
            <p class="font-medium text-lg mb-5">Send us a quick message and we'll get back to you shortly.</p>
            <hr class="border-gray-900 dark:border-gray-100">
        </div>
        <div class="mb-5">
            <label for="message" class="text-lg flex justify-between items-end"><span>Message</span><span class="text-xs text-red-500">Required</span></label>
            <textarea name="message" id="message" cols="30" rows="10" class="shadow-md mt-1 block w-full sm:text-sm rounded-none border-gray-900 dark:border-gray-100 bg-white dark:bg-gray-900"></textarea>
        </div>
        <div class="mb-5">
            <label for="name" class="text-lg flex justify-between items-end"><span>Name</span><span class="text-xs text-red-500 ">Required</span></label>
            <div class="mt-1 flex shadow-md">
                <span class="inline-flex items-center px-3 rounded-none border border-r-0 border-gray-900 dark:border-gray-100"><i class="fas fa-user"></i></span>
                <input type="text" name="name" class="flex-1 block w-full sm:text-sm rounded-none border border-gray-900 dark:border-gray-100 bg-white dark:bg-gray-900">
            </div>
        </div>
        <div class="mb-5">
            <label for="email" class="text-lg flex justify-between items-end"><span>Email</span><span class="text-xs text-red-500">Required</span></label>
            <div class="mt-1 flex shadow-md">
                <span class="inline-flex items-center px-3 rounded-none border border-r-0 border-gray-900 dark:border-gray-100"><i class="fas fa-envelope"></i></span>
                <input type="email" name="email" class="flex-1 block w-full sm:text-sm rounded-none border border-gray-900 dark:border-gray-100 bg-white dark:bg-gray-900">
            </div>
        </div>
        <div>
            <button type="button" class="font-medium shadow-md rounded-none p-2 w-full focus:outline-none focus:ring-2 focus:ring-offset-2 border border-gray-900 dark:border-gray-100 bg-gray-800 dark:bg-gray-200 text-gray-200 dark:text-gray-800 hover:bg-gray-900 dark:hover:bg-gray-100"><i class="fas fa-check"></i> Send</button>
        </div>
    </form>
</body>
```

You should now have a pretty nice looking contact form built with HTML and Tailwind CSS.

That wraps up this part of the tutorial. 

In the next part, we’re going to look at building a form handler which will email us when a user submits a form. This will be built with node.js, Express and SendGrid. We’ll also look at some client-side and server-side form validation.

Please make sure you follow me here on [dev.to](https://dev.to/brandymedia) and [Twitter](https://twitter.com/brandymedia) so you don’t miss out when the next part is available.