29

Create a Stylish Dark Contact Form with HTML, CSS, and JavaScript

 5 years ago
source link: https://www.tuicool.com/articles/hit/BVriUbb
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

In this tutorial, we’ll walk through the process of styling basic contact form elements. We’ll examine different ways for making a form beautiful and fully functional at the same time.

Here’s the form that we’re going to build:

Note: this contact form is perfect for any dark mode UI! Learn more about how you can switch between dark and light mode using nothing but CSS:

1. Begin With the Page Markup

We’ll start from scratch with a form element which contains a heading and an unordered list. We’ll use a .container for setting a maximum width to the form and horizontally center its contents:

<form class="my-form">
  <div class="container">
    <h1>Get in touch!</h1>
    <ul>
      <li>...</li>    
      <li>...</li>    
      <li>...</li>    
      <li>...</li>    
      <li>...</li>
      <li>...</li>
    </ul>
  </div>
</form>

Inside the list we’ll place the form elements.

The first list item, for example,  will contain a select element with four options. By default the first option is selected, yet disabled:

<select>
  <option selected disabled>-- Please choose an option --</option>
  <option>Request Quote</option>
  <option>Send Resume</option>
  <option>Other</option>      
</select>

In the second list item we’ll place two required input fields:

<div class="grid grid-2">
  <input type="text" placeholder="Name" required>  
  <input type="text" placeholder="Surname" required>
</div>

The third list item includes a required and an optional input field:

<div class="grid grid-2">
  <input type="email" placeholder="Email" required>  
  <input type="tel" placeholder="Phone">
</div>

The fourth list item holds a textarea:

<textarea placeholder="Message"></textarea>

The fifth list item contains a checkbox along with its label:

<input type="checkbox" id="terms">
<label for="terms">...</label>

Finally, the sixth list item contains a div element and two buttons (types  submit and reset ):

<div class="grid grid-3">
  <div class="required-msg">REQUIRED FIELDS</div>
  <button class="btn-grid" type="submit" disabled>
    <span class="back">
      <img src="IMG_SRC" alt="">
    </span>
    <span class="front">SUBMIT</span>
  </button>
  <button class="btn-grid" type="reset" disabled>
    <span class="back">
      <img src="IMG_SRC" alt="">
    </span>
    <span class="front">RESET</span>
  </button> 
</div>

2. Define Some Basic Styles

Before having a closer look at the individual form elements, let’s first define some CSS styles. These include a few custom variables to give us our color scheme, and some reset rules:

:root {
  --white: #afafaf;
  --red: #e31b23;
  --bodyColor: #292a2b;
  --borderFormEls: hsl(0, 0%, 10%);
  --bgFormEls: hsl(0, 0%, 14%);
  --bgFormElsFocus: hsl(0, 7%, 20%);
}

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
  outline: none;
}

a {
  color: inherit;
}

input,
select,
textarea,
button {
  font-family: inherit;
  font-size: 100%; 
}

button,
label {
  cursor: pointer;
}

select {
  appearance: none;
}

select::-ms-expand {
  display: none;
}

select:-moz-focusring {
  color: transparent !important;
  text-shadow: 0 0 0 var(--white);
}

textarea {
  resize: none;
}

ul {
  list-style: none;
}

Note: for simplicity I won't walk through  all the CSS rules in the tutorial. You can check the rest of them by clicking the CSS tab of the demo project.

3. Build the Form Layout

On small screens all our form elements will be stacked:

uyuIFbB.jpg!web

However on viewports 600 pixels wide and above, the form layout will change. More specifically:

  • We’ll arrange the elements of the second and third list items into two equal width columns.
  • The elements of the sixth list item will be arranged into three columns.
bYRJNvv.jpg!web

Thanks to CSS Grid, we can easily build the desired multi-column layout. We begin by declaring our .my-form .grid container as being a grid, then we define the columns on the grid items we need to change:

@media screen and (min-width: 600px) {
  .my-form .grid {
    display: grid;
    grid-gap: 1.5rem;
  }
  
  .my-form .grid-2 {
    grid-template-columns: 1fr 1fr;   
  }

  .my-form .grid-3 {
    grid-template-columns: auto auto auto;
    align-items: center;
  }
}

All of these rules are placed within a media query so they only take effect on viewports more than 600px wide.

4. Style the Form Elements

With our structure sorted out, we next add some initial aesthetic styles to all form elements:

/*CUSTOM VARIABLES HERE*/

.my-form select,
.my-form input,
.my-form textarea,
.my-form button {
  width: 100%;
  line-height: 1.5;
  padding: 15px 10px;
  border: 1px solid var(--borderFormEls);
  color: var(--white);
  background: var(--bgFormEls);
  transition: background-color 0.3s cubic-bezier(0.57, 0.21, 0.69, 1.25),
    transform 0.3s cubic-bezier(0.57, 0.21, 0.69, 1.25);
}

.my-form textarea {
  height: 170px;
}

.my-form ::placeholder {
  color: inherit;
  opacity: 1;
}

Note:alternatively, for setting the textarea’s width and height, we could have used its  cols and rows attributes respectively.

Add “On Focus” Styles

Each time a form element is in focus, I’d like its background color to change. Furthermore, some elements scale up a little bit, just for emphasis:

vIveyiM.png!web

Here’s how that’s done:

/*CUSTOM VARIABLES HERE*/

.my-form select:focus,
.my-form input:focus,
.my-form textarea:focus,
.my-form button:focus {
  background: var(--bgFormElsFocus);
}

.my-form select:focus,
.my-form input:focus,
.my-form textarea:focus {
  transform: scale(1.02);
}

Add Custom Icons

All required elements contain an icon (asterisk) positioned in the center right corner:

raAB3eb.png!web

Similarly, the select also contains a custom icon (arrow) positioned in the center right corner:

em677jf.png!web

We achieve that by applying an SVG icon as the background image:

.my-form *:required,
.my-form select {
  background-repeat: no-repeat;
  background-position: center right 12px;
  background-size: 15px 15px;
}

.my-form *:required {
  background-image: url(asterisk.svg);  
}

.my-form select {
  background-image: url(down.svg);
}

Style the Buttons

As already discussed, in our form we have two types of buttons: a submit button and a reset button. If you revisit the form markup, you’ll notice that each of those buttons contains two elements: the .back element and the .front element.

By default only their .front child appears:

7ZJFBr7.png!web

But as we hover over a button, or when it’s in focus, magic things happen. Specifically, its background color changes, the .front child disappears, and at the same time the  .back child appears with a slide-in animation:

Here are the styles responsible for that behavior:

/*CUSTOM VARIABLES HERE*/

.my-form .btn-grid {
  position: relative;
  overflow: hidden;
  transition: filter 0.2s;
}

.my-form button:enabled:hover,
.my-form button:focus {
  background: var(--bgFormElsFocus);
}

.my-form button > * {
  display: inline-block;
  width: 100%;
  transition: transform 0.4s ease-in-out;
}

.my-form button .back {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-110%, -50%);
}

.my-form button:enabled:hover .back,
.my-form button:focus .back {
  transform: translate(-50%, -50%);
}

.my-form button:enabled:hover .front,
.my-form button:focus .front {
  transform: translateX(110%);
}

5. Create a Custom Checkbox

If you look again at the markup inside the fifth list item, you’ll see that the checkbox’s id value matches the label’s  for value. That creates an association between the two elements which gives us the ability to build a custom checkbox.

As a first step we visually hide the default checkbox:

.my-form input[type="checkbox"] {
  position: absolute;
  left: -9999px;
}

Then we take advantage of the label’s ::before and ::after pseudo-elements to generate our own checkbox. 

So, first we use the ::before pseudo-element to configure its unchecked state:

YNf6Nfv.png!web

And then the ::after pseudo-element along with the  :checked  pseudo-class to implement its checked state:

VNfMFrr.png!web

As we did with the other form elements, we add some extra styling when the checkbox is in focus. Lastly, it’s wise to make sure users can access our form through keyboard navigation.

Check the associated styles below:

/*CUSTOM VARIABLES HERE*/

.my-form input[type="checkbox"] + label {
  position: relative;
  display: inline-block;
  padding-left: 2rem;
  transition: background 0.3s cubic-bezier(0.57, 0.21, 0.69, 1.25);
}

.my-form input[type="checkbox"]:focus + label {
  background: var(--bgFormElsFocus);
}

.my-form input[type="checkbox"] + label::before,
.my-form input[type="checkbox"] + label::after {
  content: '';
  position: absolute;
}

.my-form input[type="checkbox"] + label::before {
  left: 0;
  top: 6px;
  width: 18px;
  height: 18px;
  border: 2px solid var(--white);
}

.my-form input[type="checkbox"]:checked + label::before {
  background: var(--red);
}

.my-form input[type="checkbox"]:checked + label::after {
  left: 7px;
  top: 7px;
  width: 6px;
  height: 14px;
  border-bottom: 2px solid var(--white);
  border-right: 2px solid var(--white);
  transform: rotate(45deg);
}

@media screen and (min-width: 541px) {
  .my-form input[type="checkbox"] + label::before {
    top: 50%;
    transform: translateY(-50%);
  }
  
  .my-form input[type="checkbox"]:checked + label::after {
    top: 3px;
  }
}

It’s worth mentioning that we could have also used some custom icons to build the desired checkbox.

6. Toggle the Buttons’ State

Initially the form buttons are disabled. That means we cannot click on them or select them:

7BvUnmY.png!web

In our CSS we add a few styles specifically targeting these disabled elements, making it clear to the user that they cannot be interacted with:

.my-form *:disabled {
  cursor: default;
  filter: blur(2px);
}

The buttons become active as soon as the checkbox is checked:

Un2yme3.png!web

The JavaScript code that handles this functionality is shown below:

const checkbox = document.querySelector('.my-form input[type="checkbox"]');
const label = document.querySelector(".my-form label");
const btns = document.querySelectorAll(".my-form button");

checkbox.addEventListener("change", function() {
  const checked = this.checked;
  for (const btn of btns) {
    checked ? (btn.disabled = false) : (btn.disabled = true);
  }
});

Conclusion

That’s it folks! Here’s what we’ve built!

In this tutorial, we covered plenty of different tips and tricks for styling contact form elements. Although we concentrated on a dark mode aesthetic, you can apply any kind of UI design using these same principles.

Hopefully you enjoyed the contact form we built here and you’ll use it as inspiration for developing your own forms. As always, thanks for reading!

Learn More About Designing Web Forms


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK