Using HTML and CSS to create a Contact Form

Greetings! I have come across this contact form code:

/* Custom Contact Form Styling */

input[type=text],
[type=email],
select,
textarea {
  width: 100%;
  padding: 12px;
  border: 1px solid #555;
  margin-top: 6px;
  margin-bottom: 16px;
  resize: vertical;
}

input[type=submit] {
  background-color: #0563bb;
  color: white;
  padding: 12px 20px;
  border: none;
  cursor: pointer;
}

input[type=submit]:hover {
  opacity: 0.9;
}

.contactform {
  position: relative;
  border-radius: 50px;
  background-color: #f2f2f2;
  padding: 5px;
  z-index: 2;
  display: block;
  margin-left: auto;
  margin-right: auto;
  margin-bottom: auto;
  margin-top: 1%;
  width: 100%;
  animation-name: gradient;
  animation-duration: 3s;
  animation-iteration-count: infinite;
}

.contactform:hover {
  animation-name: gradientTwo;
  animation-duration: 15s;
  animation-iteration-count: infinite;
}

.column {
  float: center;
  width: 50%;
  margin-top: 6px;
  padding: 20px;
  display: block;
  margin-left: auto;
  margin-right: auto;
}

.row:after {
  content: "";
  display: table;
  clear: both;
}

@media screen and (max-width: 600px) {
  .column,
  input[type=submit] {
    width: auto;
    margin-top: 0;
  }
}

@keyframes customAnimation {
  10%,
  90% {
    transform: translateX(-1px);
  }
  20%,
  80% {
    transform: translateX(2px);
  }
  30%,
  50%,
  70% {
    transform: translateX(-4px);
  }
  40%,
  60% {
    transform: translateX(4px);
  }
}
<section id="contact">
  <div class="container" data-aos="fade-up">
    <div class="contactform">
      <div style="text-align:center">
        <div class="section-title">
          <h2><br/>Connect With Us</h2>
        </div>
        <p>Feel free to fill out our contact form!</p>
      </div>
      <div class="row">
        <div class="column">
          <form name="myform" action="thankyou.html" method="POST" novalidate>
            <label for="firstname">First Name</label>
            <input type="text" id="first name" name="firstname" placeholder="Your First Name.." required>
            <label for="lastname">Last Name</label>
            <input type="text" id="lastname" name="lastname" placeholder="Your Last Name.." required>
            <label for="email">Email:</label>
            <input type="email" id="email" name="email" placeholder="Your Email.." required>
            <label for="subject">Subject</label>
            <textarea id="subject" name="subject" placeholder="Write your message here..." style="height:170px" required></textarea>
            <input type="submit" value="Submit">
          </form>
        </div>
      </div>
    </div>
  </div>
</section>

I am looking to enhance this form by adding animations specifically on the input fields. The goal is to display the input field label above the respective field when clicked, similar to the demonstration in this video.

Desired Outcome

You can view the desired outcome through this video link: Video Link

If you have any recommendations on how I can achieve this effect within the form, please share your thoughts and suggestions.

Below is the code snippet of the contact form showcased in the video:

ContactForm.jsx:

/ dependencies
import React from 'react'
import { Grid, Typography, TextField, Button, Divider, useMediaQuery } from '@material-ui/core'
import emailjs from 'emailjs-com'

// icons
import { FaGithub, FaLinkedin, FaPhone } from 'react-icons/fa'
import { MdEmail } from 'react-icons/md'

// file imports
import { db } from "../../firebaseConfig";
import ContactStyles from './ContactStyles'

import{ init } from 'emailjs-com';
init(process.env.REACT_APP_USER_ID);

const ContactForm = () => {
    // classes and queries
    const classes = ContactStyles();
    const md = useMediaQuery('(max-width: 960px)');
    const lg = useMediaQuery('(min-width: 960px)');

    // state declaration
    const [name, setName] = React.useState("");
    const [email, setEmail] = React.useState("");
    const [message, setMessage] = React.useState("");
    const [errorName, setErrorName] = React.useState(false);
    const [errorEmail, setErrorEmail] = React.useState(false);
    const [errorMessage, setErrorMessage] = React.useState(false);

    // event handler
    const submitHandler = (e) => {
        e.preventDefault(); // prevent page refresh
        // regex pattern for validating email address
        const emailRegex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
        setErrorName(false);
        setErrorEmail(false);
        setErrorMessage(false);

        // check if any field is invalid to prevent submission
        if (name === "" || !emailRegex.test(email) || message === "") {
            if (name === "") {
                setErrorName(true);
            }

            if (!emailRegex.test(email)) {
                setErrorEmail(true);
            }

            if (message === "") {
                setErrorMessage(true);
            }
        } else {
            const firebaseData = { // data to save to Firebase and send via email
                name: name,
                email: email,
                message: message
            }

            // save to Firestore
            db.collection('contacts').add(firebaseData)
                .then(() => {
                    console.log('Message submitted to Firebase');
                })
                .catch((err) => {
                    console.log(err.message);
                });

            // send via email
            emailjs.send(
                process.env.REACT_APP_SERVICE_ID,
                process.env.REACT_APP_TEMPLATE_ID,
                {
                    name: name,
                    email: email,
                    to_name: "",
                    from_name: "",
                    message: message,
                }
            )
            .then((response) => {
                alert('Message successfully sent!');
                console.log(response);
            })
            .catch((err) => {
                console.error(err);
            });

            setName('');
            setEmail('');
            setMessage('');
            setErrorName(false);
            setErrorEmail(false);
            setErrorMessage(false);
        }
    }

    return (
        <Grid container className={classes.root} id="contact">
            {/* Title */}
            <Grid className={classes.title} item xs={12}>
                <br />
                <Typography variant="h2">Contact Me</Typography>
                <Typography variant="h4">Let's Connect!</Typography>
            </Grid>

            {/* Contact Info */}
            {lg && <>
                <Grid item xs={1}></Grid>
            <Grid item xs={10} md={5}>
                <br /><br />
                <Typography variant="h5"><b>Get in Touch!</b></Typography>
                <Divider></Divider>
                <br />
                <MdEmail />&nbsp;
                <Typography display="inline"><b> Email:</b></Typography>
                <a rel="noreferrer" target="_blank" className={classes.contact} href="mailto:<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c5a4abafa4a9aca2b1a485aab0b1a9aaaaaeeba6aaa8">[email protected]</a>">
                    <Typography display="inline"> <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7f1e11151e1316180b1e3f100a0b13101014511c1012">[email protected]</a></Typography>
                </a>
                <div /><br />
                <FaPhone />&nbsp;
                <Typography display="inline"><b> Phone:</b></Typography>
                <a rel="noreferrer" target="_blank" className={classes.contact} href="647-544-0781">
                    <Typography className={classes.contact}  display="inline"> 647-544-0781</Typography>
                </a>
                <div /><br />
                <FaGithub />&nbsp;
                <Typography display="inline"><b> Github:</b></Typography>
                <a rel="noreferrer" target="_blank" className={classes.contact} href="https://github.com/anjalig21">
                    <Typography  display="inline"> github.com/AnjaliGupta</Typography>
                </a>
                <div /><br />
                <FaLinkedin />&nbsp;
                <Typography display="inline"><b> LinkedIn:</b></Typography>
                <a rel="noreferrer" target="_blank" className={classes.contact} href="https://www.linkedin.com/in/anjali-gupta21/">
                    <Typography  display="inline"> linkedin.com/in/AnjaliGupta</Typography>
                </a>
                <br /><br /><br />
            </Grid>
            <Grid item xs={1}></Grid>
            </>}

            {/* Contact Form */}
            {md && <Grid item xs={1}></Grid>}
            <Grid item xs={10} md={4}>
                <div className={classes.formContainer}>
                    <form onSubmit={submitHandler} className={classes.form}>
                        <TextField
                            className={classes.input}
                            value={name}
                            onChange={(e) => setName(e.target.value)}
                            label="Full Name"
                            variant="outlined"
                            error={errorName}
                            helperText={errorName ? "Please provide your full name." : ""}
                        />
                        <br /><br />
                        <TextField
                            className={classes.input}
                            value={email}
                            onChange={(e) => setEmail(e.target.value)}
                            label="Email Address"
                            variant="outlined"
                            error={errorEmail}
                            helperText={errorEmail ? "Please enter a valid email." : ""}
                        />
                        <br /><br />
                        <TextField
                            className={classes.input}
                            value={message}
                            onChange={(e) => setMessage(e.target.value)}
                            label="Your Message"
                            multiline
                            rows={10}
                            variant="outlined"
                            error={errorMessage}
                            helperText={errorMessage ? "Please write a message." : ""}
                        />
                        <br /><br />
                        <div className={classes.center}>
                            <Button type="submit" variant="contained" size="large" className={classes.button}>
                                Send
                            </Button>
                        </div>
                    </form>
                </div>
            </Grid>
            <Grid item xs={1}></Grid>
        </Grid>
    )
}

export default ContactForm;

ContactStyles.jsx:

import { makeStyles } from '@material-ui/styles';

const ContactStyles = makeStyles((theme) => ({
    root: {
        background: theme.palette.primary.dark
    },
    title: {
        textAlign: "center",
        color: theme.palette.secondary.dark
    },
    formContainer: {
        height: "78vh",
        position: "relative"
    },
    form: {
        position: "absolute",
        top: "50%",
        left: "50%",
        transform: "translate(-100%, -50%)"
    },
    input: {
        width: "200%",
        fontWeight: "600",
        '& label.Mui-focused': {
      color: theme.palette.secondary.dark,
    },
    '& .MuiInput-underline:after': {
      borderBottomColor: theme.palette.secondary.dark,
    },
    '& .MuiOutlinedInput-root': {
      '& fieldset': {
        borderColor: '#0644A3',
      },
      '&:hover fieldset': {
        borderColor: theme.palette.secondary.dark,
      },
      '&.Mui-focused fieldset': {
        borderColor: theme.palette.secondary.dark,
      },
    },
    },
    center: {
        display: "flex",
        justifyContent: "center",
        width: "200%"
    },
    button: {
        backgroundColor: "#0644A3",
        color: "#FFFFFF",
        borderRadius: 20,
        marginRight: "2%",
        textTransform: "none",
        '&:hover': {
            transition: "0.3s",
            color: "#0644A3",
            backgroundColor: "#FFFFFF",
            border: "1px solid #0644A3",
        }
    },
    contact: {
        textDecoration: "none",
        color: "#000000",
        '&:hover': {
            transition: "0.3s",
            color: "#b5befa"
        }
    },
    spacing: {
        display: "flex",
        alignItems: "center"
    }
}))

export default ContactStyles;

Answer №1

I decided to take on the challenge of creating a Beta version for you, inspired by the video link you provided.

My approach was to solely use HTML and CSS...

The key here is to establish an Extra Div as a Parent element, allowing us to encapsulate the label and input together.

Next, I set the parent element to have a position: relative;, enabling the label to be positioned using absolute

By utilizing TOP, LEFT, RIGHT, BOTTOM properties, we were able to position the label effectively as the placeholder.

The logic for this can be seen in the following code snippet:

.input-container input:focus~label

* {
  --input-height: 3rem;
}

section {
  height: 100vh;
  width: 100vw;
  display: grid;
  place-content: center;
}

.input-container input {
  height: var(--input-height);
  width: 80vw;
  font-size: 2rem;
}

.input-container {
  position: relative;
  display: grid;
  place-items: center start;
}

.input-container label {
  position: absolute;
  left: 1rem;
  font-size: 1.5rem;
  color: rgb(90, 90, 90);
  background-color: white;
  transition-duration: 0.5s;
}

.input-container input:focus~label {
  position: absolute;
  font-size: 0.7rem;
  top: -0.6rem;
  padding: 0.2em;
  left: 0.5rem;
  color: rgb(0, 81, 255);
  background-color: white;
  transition-duration: 0.2s;
  z-index: 2;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="style.css">
</head>

<body>
  <section>
    <form action="">
      <div class="input-container">
        <input type="text" name="" id="my-input">
        <label for="my-input">hello world</label>
      </div>
    </form>
  </section>
</body>

</html>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

retrieving the element's height results in a value of 'undefined'

I am attempting to get the height of a specific element, but unfortunately I keep getting undefined. Here is what I have tried: var dl; $(window).load(function(){ dl = $("#dashboard_left").height(); }); $(document).ready(function(){ alert(dl); } ...

Formatting Numbers in HighCharts Shared Tooltip

My first experience with HighCharts JS has been quite positive. I am currently creating multiple series and using a shared tooltip feature. The numbers displayed in the shared tooltip are accurate, but the formatting is not to my liking. For instance, it s ...

What causes the Object expected error in jQuery?

Looking for a way to demo horizontal collapse pane with a simple web page that includes html, css, and jquery. <html> <head> <script type="text/javascript" src="//code.jquery.com/jquery-1.10.1.js"></script> <title>Sa ...

What potential issues can arise when importing a default export alongside a named export and using webpack in conjunction with babel?

I have two distinct constructors in my codebase: SignUp and GoogleSignIn. They are structured as follows: import SignUp, {gapi_promise} from "./SignUp"; /** * * @param element * @extends SignUp * @constructor */ function GoogleSignIn(element){ SignUp ...

The log out button is unresponsive and does not function properly

I am having trouble positioning the logout button on the left toolbar. I have tried using the position property, but it is not responsive. When I resize the Chrome window, the button disappears. I also attempted to use margin, but that did not work either. ...

Utilizing Angular Components Across Various Layers: A Guide

Consider the following component structure: app1 -- app1.component.html -- app1.component.ts parent1 parent2 app2 -- app2.component.html -- app2.component.ts Is it possible to efficiently reuse the app2 component within the ap ...

overlay appears as I reveal the slide-out menu

Struggling with adding an overlay to an expanding navigation bar, similar to Youtube's overlay when the slide-out nav is open. Need help with the implementation. Here is the javascript code for the expanding navigation using jQuery: 'use strict ...

What is the best way to elegantly display a block containing background and text using Angular and ngAnimate?

I'm a beginner when it comes to JavaScript and Angular. I am attempting to use ng-show and ng-hide for my background and text elements. However, I am experiencing an issue with my text: It smoothly hides, but when it is shown again, the text appears b ...

Struggling to make comparisons with numerical data from MongoDB in an ExpressJS route

I am currently developing a website using Node.js, EJS template, MongoDB, and Express. I am working on implementing search functionality on my page using forms, but I am encountering a small issue. The problem is related to a logical issue in the search f ...

How to turn off code splitting (chunks) in Vue.js and Vite.js

Is there a way to turn off chunking in Vue.js and Vite.js when building a project using Rollup.js? I attempted the following approach, but it did not work for me: export default defineConfig({ build: { rollupOptions: { output: { ...

Update the color of the menu ID

Feeling frustrated trying to figure out how to modify this <nav class="mainnav "> <a id="top"/> <div class="navwrap"> <ul id="menu-top" class="menu"> <li id="menu-item-70" class="menu-item menu-item-type-custom menu-item-object- ...

Display the number in a formatted manner without displaying any zeros in the decimal part

Can you help me with a decimal number display issue I am having? <nested:text property="product.price" maxlength="5" onclick="javascript:validatePriceValue(this);"/> number displayed as 44 44.00 I want to use J ...

I possess an item that I must display its title as a <choice> in a <menu> while returning a different variable

I am working with an object: company: { name: 'Google', id: '123asd890jio345mcn', } My goal is to display the company name as an option in a material-ui selector (Autocomplete with TextField rendering). However, when a user selects ...

"Customize the font style of columns in a WordPress table created with TablePress by setting them to it

Recently, I designed a table in a WordPress blog using the TablePress plugin. My intention now is to style the left column's font in italics, excluding the table header. ...

Tips on maintaining the numerical value while using JSON.stringify()

Having trouble using the JSON.stringify() method to convert some values into JSON format. The variable amount is a string and I want the final value in JSON format to be a number, but it's not working as expected. Even after applying JSON.stringify(), ...

Comparing JSON objects using Javascript and AngularJS

In the page I'm working on, there are several input fields where users can enter data such as text boxes and dropdowns. When a user fills in the data and clicks SAVE, certain checks and manipulations need to be done before the actual saving process st ...

How is it possible to retrieve the flex-direction property value of a div using JavaScript?

While attempting to troubleshoot this issue using Windows Chrome 59, I utilized devtools to examine the properties. let element = document.getElementById("divId"); Upon checking the value of the element, I noticed that the object structure displayed: &g ...

Adjust the height of an element when an animation is initiated (Angular)

Check out the transition I've set up to smoothly slide between my views: https://plnkr.co/edit/yhhdYuAl9Kpcqw5tDx55?p=preview To ensure that both 'panels' slide together, I need to position the view absolutely. However, this causes the view ...

Zebra Calendar Alignment Problem

Currently working on an asp.net app and utilizing the Jquery Zebra DatePicker. Encountering an issue where when opening the form in a Jquery dialog, the calendar appears at the bottom of the page instead of within the dialog. A similar problem was discus ...

Beyond the footer area on the right side

I have a two-column layout, but I'm having issues with the footer area. When I add a border around it, the right side extends beyond what I expected. Check out the issue here. I tested it in Firefox and used some CSS: footer { border-style: solid ...