Build a Responsive Food Website Using HTML, CSS, and JavaScript

Build a Responsive Food Website Using HTML, CSS, and JavaScript

Introduction :

In this tutorial, we will Build a Responsive Food Website Using HTML, CSS, and JavaScript. This site can be used for restaurants, food blogs, or any food-related business.
We’ll focus on creating a responsive layout with beautiful food cards, a gallery, and basic interactivity using JavaScript. This tutorial is perfect for beginners who want to practice frontend web development fundamentals while building a real project.

Prerequisites:

Before starting this tutorial, you should have:

  • A basic understanding of HTML, CSS, and JavaScript.
  • A code editor such as Visual Studio Code, Sublime Text, or any other preferred editor.
  • A folder structure prepared with:
    • index.html
    • style.css
    • script.js
    • An images/ folder for media assets

Step 1(Html Code):

DOCTYPE Declaration and Basic HTML Setup:

  • The file starts with which declares the use of HTML5.
  • The <html lang=”en”> tag wraps the entire content and defines the language as English.
  • The <head> section includes:
    • <meta charset=”UTF-8″> to ensure correct character display.
    • <meta name=”viewport” content=”width=device-width, initial-scale=1.0″> to make the website responsive.
    • A <tittle> element to set the browser tab title.
    • Links to two stylesheets:
    • A custom style.css file.
    • Font Awesome CDN for using icon sets.
  • Navigation Bar:
    • A <nav> element is used to create the main navigation section.
    • It includes clickable links with Font Awesome icons representing: Home, Meals, Burger, Pizza, Contact.
    • The navigation is visually structured and user-friendly.
  • Main Content Container: The body of the page is divided into four main sections wrapped inside a .
  • Food Icons Display:
    • Displays the heading: “Variety of Foods”.
    • Multiple food-related icons (such as egg, cheese, hotdog, fish) are displayed.
    • Icons rotate using JavaScript to create an auto-scrolling effect.
  • Popular Meals:
    • Contains a heading: “Popular Meals”.
    • Showcases food cards with:
      • An image of the meal.
      • The name of the food item (Fish, Cake, Lobster).
      • A call-to-action button labeled “Order Now”.
  • Food Gallery:
    • Includes a heading: “Gallery”.
    • Six food items are arranged in a responsive grid.
    • Each item includes:
      • An image
      • A food name (Pancakes, Cupcakes, etc.)
      • A brief description
  • Email Subscription Form:
    • Displays the heading: “Sign Me Up”.
    • Includes a short message encouraging users to subscribe.
    • Contains a simple form with an email input field and a submit button.
    • Includes a small footer text: “CodeAndCreate © All rights reserved”.

Step 2 (CSS Code):

Next, we will create our CSS file. In this file, we will use some basic CSS rules to design our Food website. We will also add some padding and margin properties to ensure that everything looks correct. This will give our website an upgraded presentation. Create a CSS file with the name of styles.css and paste the given codes into your CSS file. Remember that you must create a file with the .css extension.

Step 3 (JavaScript Code):

To enhance the user experience, we’re now adding a few simple interactive effects using JavaScript. Create a file named script.js and paste the following code inside it. Make sure to link this JS file correctly in your HTML using:

<script src="script.js"></script>
  1. Navbar Toggle Animation (for Mobile Menu):
document.querySelector('.menu').addEventListener('click', () => {
	document.querySelectorAll('.target').forEach((item) => {
		item.classList.toggle('change');
	})
})
  • This part listens for a click event on the .menu element.
  • When clicked, it selects all elements with the class .target and toggles the class change on each.
  • This can be used for toggling mobile nav visibility or animating menu items.

2. Auto Icon Change Animation (Rotating Icons)

const icons = document.querySelectorAll('.section-1-icons i')
let i = 1
setInterval(() => {
	i++
	const icon = document.querySelector('.section-1-icons .change')
	icon.classList.remove('change')

	if (i > icons.length) {
		icons[0].classList.add('change')
		i = 1
	} else {
		icon.nextElementSibling.classList.add('change')
	}
}, 4000)

This section is used to rotate or cycle through the icons in .section-1-icons.
Every 4 seconds (4000 ms):

  • It removes the change class from the currently highlighted icon.
  • Then it adds the change class to the next icon in the sequence.
  • Once it reaches the last icon, it resets and starts from the first icon again.

This creates a smooth loop effect, highlighting one icon at a time.

Index.html

<nav class="navbar target">
        <a href="#" class="navbar-link">
            <i class="fas fa-home"></i>
            <span>Home</span>
        </a>
        <a href="#" class="navbar-link">
            <i class="fas fa-utensils"></i>
            <span>Meals</span>
        </a>
        <a href="#" class="navbar-link">
            <i class="fas fa-hamburger"></i>
            <span>Burger</span>
        </a>
        <a href="#" class="navbar-link">
            <i class="fas fa-pizza-slice"></i>
            <span>Pizza</span>
        </a>
        <a href="#" class="navbar-link">
            <i class="fas fa-blender-phone"></i>
            <span>Contact</span>
        </a>
    </nav>
    <div class="menu target"></div>
    <!-- End of Navbar  -->

    <div class="container">
        <!-- Section 1 -->
        <section class="section-1">
            <h1 class="section-heading">variety of foods</h1>
          <div class="section-1-icons">
              <i class="change fas fa-egg"></i>
              <i class="fas fa-stroopwafel"></i>
              <i class="fas fa-cheese"></i>
              <i class="fas fa-hotdog"></i>
              <i class="fas fa-drumstick-bite"></i>
              <i class="fas fa-apple-alt"></i>
              <i class="fas fa-ice-cream"></i>
              <i class="fas fa-fish"></i>
              <i class="fas fa-cookie"></i>
              <i class="fas fa-seedling"></i>
            </div>
        </section>
        <!-- End Section 1 -->

        <!-- Section 2 -->
        <section class="section-2">
            <h1 class="section-heading">popular meals</h1>
            <div class="cards-container">
                <div class="card">
                    <img src="images/card-img-1.png" class="card-img" />
                    <h3 class="card-name">Fish</h3>
                    <button class="card-btn">Order now</button>
                </div>
                <div class="card">
                    <img src="images/card-img-2.png" class="card-img" />
                    <h3 class="card-name">Cake</h3>
                    <button class="card-btn">Order now</button>
                </div>
                <div class="card">
                    <img src="images/card-img-3.png" class="card-img" />
                    <h3 class="card-name">Lobster</h3>
                    <button class="card-btn">Order now</button>
                </div>
            </div>
        </section>
        <!-- End of Section 2 -->

        <!-- Section 3 -->
        <section class="section-3">
            <h1 class="section-heading">Gallery</h1>
            <div class="gallery">
                <a href="#" class="gallery-link" title="Order Now">
                    <img src="/images/gallery-img-1.jpg" class="food-img" />
                    <h3 class="food-name">Pancakes</h3>
                    <p class="food-description">
                        Lorem ipsum dolor sit amet consectetur adipisicing elit. Ipsa
                        commodi possimus iure hic excepturi. Corporis!
                    </p>
                </a>
                <a href="#" class="gallery-link" title="Order Now">
                    <img src="/images/gallery-img-2.jpg" class="food-img" />
                    <h3 class="food-name">Cupcakes</h3>
                    <p class="food-description">
                        Lorem ipsum dolor sit amet consectetur adipisicing elit. Ipsa
                        commodi possimus iure hic excepturi. Corporis!
                    </p>
                </a>
                <a href="#" class="gallery-link" title="Order Now">
                    <img src="/images/gallery-img-3.jpg" class="food-img" />
                    <h3 class="food-name">Hummus</h3>
                    <p class="food-description">
                        Lorem ipsum dolor sit amet consectetur adipisicing elit. Ipsa
                        commodi possimus iure hic excepturi. Corporis!
                    </p>
                </a>
                <a href="#" class="gallery-link" title="Order Now">
                    <img src="/images/gallery-img-4.jpg" class="food-img" />
                    <h3 class="food-name">Hamburger</h3>
                    <p class="food-description">
                        Lorem ipsum dolor sit amet consectetur adipisicing elit. Ipsa
                        commodi possimus iure hic excepturi. Corporis!
                    </p>
                </a>
                <a href="#" class="gallery-link" title="Order Now">
                    <img src="/images/gallery-img-5.jpg" class="food-img" />
                    <h3 class="food-name">Salmon</h3>
                    <p class="food-description">
                        Lorem ipsum dolor sit amet consectetur adipisicing elit. Ipsa
                        commodi possimus iure hic excepturi. Corporis!
                    </p>
                </a>
                <a href="#" class="gallery-link" title="Order Now">
                    <img src="/images/gallery-img-6.jpg" class="food-img" />
                    <h3 class="food-name">Vegetables</h3>
                    <p class="food-description">
                        Lorem ipsum dolor sit amet consectetur adipisicing elit. Ipsa
                        commodi possimus iure hic excepturi. Corporis!
                    </p>
                </a>
            </div>
        </section>
        <!-- End of Section 3 -->

        <!-- Section 4 -->
        <section class="section-4">
            <div class="section-4-text">
                <h2 class="section-4-heading">Sign Me Up</h2>
                <p class="section-4-paragraph">
                    BE THE FIRST TO KNOW ABOUT NEW PRODUCTS
                </p>
            </div>
            <form class="signup-form ">
                <input
                    type="email"
                    class="signup-form-input"
                    placeholder="Enter Your Email"
                />
                <button type="submit" class="signup-form-btn">
                    <i class="fas fa-arrow-right"></i>
                </button>
            </form>
            <p class="copyright">CodeAndCreate &copy; All rights reserved</p>
        </section>
        <!-- End of Section 4 -->
        </div>
        <script src="script.js"></script>

Style.css

@import url("https://fonts.googleapis.com/css2?family=Nunito:wght@200;300;400;600;700;800;900&display=swap");
/* Common styles */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  text-decoration: none;
  outline: none;
  font-family: "Nunito", sans-serif;
  font-weight: 400;
}

html {
  font-size: 62.5%;
}

.section-heading {
  font-size: 12rem;
  font-weight: 900;
  color: #fff;
  text-align: center;
  text-transform: capitalize;
  letter-spacing: 0.5rem;
  text-shadow: 0.3rem 0.3rem 0.3rem #000;
}
/* End of Common Styles */

/* Navbar */
.navbar {
  width: 100%;
  height: 14rem;
  background-color: #000;
  position: fixed;
  top: -14rem;
  z-index: 150;
  display: flex;
  justify-content: center;
  align-items: center;
  box-shadow: 0.2rem 0.2rem 0.2rem #000;
  /* text-align: center; */
  transition: top 0.4s;
}

.navbar.change {
  top: 0;
  transition: top 0.4s 0.2s;
}

.navbar-link {
  color: #aaa;
  margin: 0 4rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  /* position: relative; */
  opacity: 0;
  transition: color 0.3, opacity, 2s;
}

.change .navbar-link {
  opacity: 1;
}

.change .navbar-link:nth-child(1) {
  transition: opacity 0.4s 0.5s, color 0.3s;
}

.change .navbar-link:nth-child(2) {
  transition: opacity 0.4s 0.6s, color 0.3s;
}

.change .navbar-link:nth-child(3) {
  transition: opacity 0.4s 0.7s, color 0.3s;
}

.change .navbar-link:nth-child(4) {
  transition: opacity 0.4s 0.8s, color 0.3s;
}

.change .navbar-link:nth-child(5) {
  transition: opacity 0.4s 0.9s, color 0.3s;
}

.navbar-link:hover {
  color: #fff;
}

.navbar-link i {
  font-size: 7rem;
}

.navbar-link span {
  font-size: 2.5rem;
  font-weight: 900;
  letter-spacing: 0.5rem;
  margin-top: 0.5rem;
}

.menu {
  width: 4rem;
  height: 6rem;
  background-color: #000;
  position: fixed;
  top: 1rem;
  left: 5rem;
  border-radius: 30rem 30rem 15rem 15rem;
  box-shadow: 0.1rem 0.1rem 0.1rem #000, -0.1rem -0.1rem 0.1rem #000;
  cursor: pointer;
  z-index: 100;
  transition: top 0.4s 0.2s;
}

.menu.change {
  top: 15rem;
  transition: top 0.4s;
}

.menu::before {
  content: "";
  width: 0.3rem;
  height: 15rem;
  background-color: #000;
  position: absolute;
  top: -15rem;
  left: calc(50% - 0.15rem);
  box-shadow: 0.1rem 0rem 0.1rem #000;
  /* transition: all 0.4s; */
}

/* End of Navbar */

/* Section 1 */
.section-1 {
  width: 100%;
  height: 100vh;
  background-color: #333;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-evenly;
}

.section-1-icons i {
  font-size: 35rem;
  color: #a79a2d;
  position: absolute;
  transform: translate(-50%, -50%) scale(0);
  text-shadow: 0.2rem 0.2rem 0.2rem #000;
  transition: transform 0.3s;
}

.section-1-icons i.change {
  transform: translate(-50%, -50%) scale(1);
  transition: transform 0.3s 0.3s;
}
/* End of Section 1 */

/* Section 2 */
.section-2 {
  width: 100%;
  height: 100vh;
  background-color: #222;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 10rem 0;
}

.cards-container {
  display: flex;
  justify-content: space-evenly;
  /* padding: 0 5%; */
}

.card-wrapper {
  perspective: 1000rem;
}

.card {
  width: 30rem;
  background-color: #a79a2d;
  padding: 4rem;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
  box-shadow: 1rem 1rem 1rem #000;
  position: relative;
  transform: rotateY(20deg) skewX(-2deg);
  transition: transform 0.5s, box-shadow 0.5s;
}

.card:hover {
  transform: rotateY(20deg) skewX(-2deg) translateY(-3rem);
  box-shadow: 2rem 2rem 2rem #000;
}

.card::before {
  content: "";
  height: 100%;
  width: 1rem;
  background-color: #817824;
  position: absolute;
  top: 0;
  left: -1rem;
  transform: skewY(45deg);
  transform-origin: right;
  box-shadow: -0.1rem -0.1rem 0.1rem #000;
}

.card::after {
  content: "";
  width: 100%;
  height: 1rem;
  background-color: #8f8317;
  position: absolute;
  top: -1rem;
  left: 0;
  transform: skewX(45deg);
  transform-origin: bottom;
  box-shadow: -0.1rem -0.1rem 0.1rem #000;
}

.card-img {
  width: 100%;
}

.card-name {
  font-size: 3rem;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.5rem;
  color: #111;
  margin: 2rem 0;
  text-shadow: 0.15rem 0.15rem 0.15rem #000;
}

.card-btn {
  width: 70%;
  background-color: #111;
  color: #888;
  border-radius: 5rem;
  font-size: 1.5rem;
  font-weight: 800;
  letter-spacing: 0.2rem;
  text-transform: capitalize;
  border: none;
  padding: 0.5rem 0;
  cursor: pointer;
  box-shadow: -0.2rem -0.2rem 0.2rem #000;
}
/* End of Section 2 */

/* Section 3 */
.section-3 {
  background-color: #333;
  padding: 5rem 0;
}

.gallery {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-evenly;
  margin-top: 10rem;
}

.gallery-link {
  position: relative;
  margin: 4rem 1rem;
}

.gallery-link::before {
  content: "";
  position: absolute;
  top: 2vw;
  left: 80%;
  width: 0.2rem;
  height: 0;
  background-color: #fff;
  z-index: 10;
  transition: height 0.5s;
}

.gallery-link::after {
  content: "";
  position: absolute;
  top: 30%;
  left: 2rem;
  width: 0;
  height: 0.2rem;
  background-color: #fff;
  transition: width 0.5s;
}

.gallery-link:hover::before {
  height: 80%;
}

.gallery-link:hover::after {
  width: 90%;
}

.food-img {
  width: 24vw;
  height: 15vw;
  object-fit: cover;
  box-shadow: 0.3rem 0.3rem 0.1rem #e92929, 0.5rem 0.5rem 0.1rem #a2e946,
    0.7rem 0.7rem 0.1rem #297ce9, 0.9rem 0.9rem 0.1rem #e92999;
  transition: all 0.5s;
}

.gallery-link:hover .food-img {
  box-shadow: 1rem 1rem 0.1rem #e92929, 2rem 2rem 0.1rem #a2e946,
    3rem 3rem 0.1rem #297ce9, 4rem 4rem 0.1rem #e92999;
  transform: scale(1.1);
  filter: blur(0.5rem);
  opacity: 0.5;
}

.food-name {
  position: absolute;
  top: 3rem;
  left: 3rem;
  font-size: 2rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1rem;
  color: #fff;
  width: 0;
  overflow: hidden;
  transition: width 0.3s;
}

.gallery-link:hover .food-name {
  width: 100%;
  transition: width 1.5s 0.5s;
}

.food-description {
  position: absolute;
  bottom: 3vw;
  left: 2rem;
  width: 70%;
  font-size: 1.5rem;
  font-weight: 300;
  letter-spacing: 0.1rem;
  text-transform: uppercase;
  color: #fff;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s;
}

.gallery-link:hover .food-description {
  opacity: 1;
  visibility: visible;
  transition: opacity 1s 1s;
}
/* End of Section 3 */

/* Section 4 */

.section-4 {
  width: 100%;
  height: 30vh;
  background-color: #222;
  display: flex;
  justify-content: space-around;
  padding: 3rem 0;
  position: relative;
  align-items: flex-start;
}

.section-4-text {
  text-transform: uppercase;
}

.section-4-heading {
  font-size: 4rem;
  font-weight: 900;
  color: #a79a2d;
}

.section-4-paragraph {
  font-size: 1.5rem;
  color: #888;
}

.signup-form {
  /* position: relative; */
  display: flex;
  align-items: center;
}

.signup-form-input {
  width: 35rem;
  height: 5rem;
  padding: 1rem;
  border: 0.2rem solid #a79a2d;
  font-size: 1.6rem;
  font-weight: 700;
  letter-spacing: 0.1rem;
  color: #a79a2d;
}

.signup-form-input::placeholder {
  color: #a79a2d;
}

.signup-form-btn {
  position: relative;
  left: -4.5rem;
  width: 4rem;
  height: 4rem;
  background-color: #333;
  color: #a79a2d;
  border: none;
  font-size: 1.8rem;
  cursor: pointer;
}

.copyright {
  position: absolute;
  bottom: 3rem;
  font-size: 1.7rem;
  font-weight: 200;
  color: #eee;
  letter-spacing: 0.1rem;
  border-top: 0.1rem solid #888;
  padding-top: 6rem;
  width: 100%;
  text-align: center;
}
/* End of Section 4 */

/* Responsive */
@media (max-width: 1400px) {
  html {
    font-size: 50%;
  }

  .section-2 {
    height: auto;
  }

  .cards-container {
    margin-top: 10rem;
  }

  .gallery-link {
    width: 40rem;
    height: 25rem;
    margin: 5rem;
  }

  .food-img {
    width: 100%;
    height: 100%;
  }
}

@media (max-width: 1000px) {
  .section-heading {
    font-size: 9rem;
    margin: 0 5rem;
  }

  .section-1-icons i {
    font-size: 25rem;
  }

  .cards-container {
    flex-wrap: wrap;
  }

  .card {
    margin: 5rem;
  }

  .section-4 {
    height: 30rem;
  }
}

@media (max-width: 900px) {
  .navbar-link {
    margin: 2rem;
  }

  .navbar-link i {
    font-size: 4rem;
  }

  .navbar-link span {
    font-size: 2rem;
  }
}

@media (max-width: 700px) {
  .section-heading {
    font-size: 7rem;
    margin: 0 10rem;
  }

  .section-1-icons i {
    font-size: 20rem;
  }

  .menu {
    left: 2rem;
  }

  .section-4 {
    height: 40rem;
    flex-direction: column;
    justify-content: flex-start;
    align-items: center;
  }

  .section-4-text {
    margin-bottom: 8rem;
  }
}

@media (max-width: 550px) {
  html {
    font-size: 40%;
  }

  .navbar-link {
    margin: 0 0.7rem;
  }
}
/* End of Responsive */

Script.js

document.querySelector('.menu').addEventListener('click', () => {
	document.querySelectorAll('.target').forEach((item) => {
		item.classList.toggle('change');
	})
})

const icons = document.querySelectorAll('.section-1-icons i')
let i = 1

setInterval(() => {
	i++
	const icon = document.querySelector('.section-1-icons .change')
	icon.classList.remove('change')

	if (i > icons.length) {
		icons[0].classList.add('change')
		i = 1
	} else {
		icon.nextElementSibling.classList.add('change')
	}
}, 4000)