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

The JSON output is throwing an error because it is unable to access the property '0' since it is

Trying to convert JSON data into an HTML table, I encountered the following error: "Cannot read property '0' of undefined" <?php $idmatchs = "bGdzkiUVu,bCrAvXQpO,b4I6WYnGB,bMgwck80h"; $exploded = explode(",", $idmatchs); $count = count( ...

What is the best way to pass default event argument alongside another argument in React?

This snippet demonstrates the function I wish to call when a certain input type is invoked: _handleOnEnterPress = (e, receiverUserId) => { if (e.keyCode === 13) { // assuming keycode 13 corresponds to 'enter' console.log("pressed ...

What techniques are most effective for creating unit tests in a Node.js environment?

One of the challenges I am facing is writing a unit test for a module where I load a mustache template file. To tackle this, I am exploring the use of mocha, chai, and rewire. Below is an excerpt from my module.js: var winston = require('winston&apo ...

What is the process for updating field values when opening the modal with various modes and input values?

Encountering an issue with the Modal Form component where the fields do not update when opening the modal in different modes with initial values. Despite attempting to pass initial values into Antd Form, the expected behavior is not achieved as the field v ...

Is there a way to make all cards in material ui the same height?

My challenge lies in rendering cards in a grid list using material-ui. Each card comprises an image file at the top and some content in the rest of the space. However, variations in text content cause differences in card height. Despite several attempts, I ...

Other Components take turns submitting the form in one Component

Two components, CreateCandidate and Technologies are being used. CreateCandidate requires technologies from the Technologies Component. When passing the technologies to CreateCandidate, the form within CreateCandidate is submitted. Below is the code: Crea ...

Can regex matching characters be made easier to understand?

I am working on creating an ECMAScript (JavaScript) flavored regex to evaluate the complexity of my password based on specific criteria: Characters Used Password Strength Length ABC abc 123 #$& WEAK ... 1 x ...

AngularJS directive ngShow not working properly

It seems like I'm encountering some scope issues that I can't seem to resolve. Here's a rundown of the problem: I'm trying to create a custom directive called "my-create-content" that will insert an "img" HTML template into the element ...

PHP incorporate diverse files from various subfolders located within the main directory

My question is similar to PHP include file strategy needed. I have the following folder structure: /root/pages.php /root/articles/pages.php /root/includes/include_files.php /root/img/images.jpg All pages in the "/root" and "/root/art ...

Is it possible to replicate an HTML table using JavaScript without including the headers?

Discover a JavaScript snippet in this stack overflow post that allows you to create a button for automatically selecting and copying a table to the clipboard. When pasting the data into an Excel template, my users prefer not to include the header informat ...

Retrieve hyperlinks from webpage

Currently, I am attempting to extract all Netflix movie/show links from this source , along with their respective country names. For example, I aim to retrieve information such as , USA, etc. Despite my efforts so far, the current code retrieves all links ...

What is the best way to show the Logout button on the main UI after successfully logging in?

I am currently working on implementing a new feature in my React JS application. The idea is that upon successful login, the UI should display a Logout button in the navbar. However, clicking on this button should log the user out and redirect them to the ...

Leveraging ES6 import declarations within Firebase functions

I've been experimenting with using ES6 in Firebase functions by trying to import modules like "import App from './src/App.js'. However, after adding type:"module" to my package.json, I encountered a strange error with Firebase ...

Create a new project using Firebase Functions along with a Node.js backend and a React.js frontend

In the process of developing my application, I have chosen to utilize node.js, express.js, and Firebase with firebase functions, all coded in TypeScript. For the client side framework, I am interested in incorporating react.js. Currently, I have set up nod ...

What are the potential risks of using a Python csv and StringIO to create an .xls file and how it could lead to

I have a React component that performs an AJAX call using Axios to connect to my own API and retrieve data in the form of an ".xls" file, which is then automatically downloaded. Everything works as expected, however, upon opening the .xls file, Excel displ ...

Utilizing JSONP callbacks in Dart

I've been struggling with implementing basic JSONP in Dart and I can't seem to figure it out. After reading this specific blog post along with another helpful resource, it suggests using window.on.message.add(dataReceived); to receive a MessageEv ...

Error when the class is not found + Application

I am attempting to create my debut Applet named MemoSaver2.java In addition, I have crafted the following html: <html> <object classid="java:MemoSaver2.class" type="application/x-java-applet" archive="MemoSaver2.jar" he ...

Hover over me to see the CSS animation translate upwards until it reaches a specific point

I am new to CSS animation and I am trying to create a circle that moves from one end to the other on hover. However, I am facing an issue where the circle goes off-screen when the browser size is changed. How can I make it stop at a certain point within th ...

CSS: How to target a specific element using its ID with nth-child selector?

Here is the HTML code that I am working with: <dl id="id"> <dt>test</dt> <dd>whatever</dd> <dt>test1</dt> <dd>whatever2</dd> .... </dl> I am trying to select the third dd ele ...

Element with absolute position does not expand along with scrollable content (over 100%)

In my popup window, the fade element is supposed to stretch to the full width of the screen. However, when the content exceeds 100% of the browser window height, the element does not extend to the full page height. If I set html, body { height: 100%; over ...