DEV Community

Cover image for 🔥🤯 Amazing Food Order hero section using HTML, CSS and JS.
Modern Web
Modern Web

Posted on

🔥🤯 Amazing Food Order hero section using HTML, CSS and JS.

If you know web development and tired of making simple looking websites. Then this article is right for you. In this article, you’ll learn to create a modern looking food order hero section using HTML, CSS and JS with cool animations and we will make it responsive too.

So, without wasting more time, let's start. To see how you can code full website, you can watch the tutorial below.

Video Tutorial

DEMO

DEMO

If you want to code full landing page then follow the video tutorial above. Else continue reading.

Folder Strucutre

So to start any project you should know what is the folder structure of it. Well since this is a simple hero section ( part of a simple page ). There is no complex folder strucutre.

I have an img folder contains all the images we need, app.js, index.html and style.css files.

Folder Strucutre

Download the images ( Github Repo ) , Download Full landing page source code

Link Files.

After you download the github repo, open index.html file and link style.css and app.js.

<head>
    <!-- default codes -->
    <!-- Style -->
    <link rel="stylesheet" href="style.css">
</head>
<body>

   <!-- Scripts -->
   <script src="app.js"></script>
</body>

Enter fullscreen mode Exit fullscreen mode

Navbar

Before we work on our hero section, let's first make our navbar. So make sure you have download the github repo I provided you above and follow me.

So In our navbar, we have 3 main things, first is a logo then links and the other is search box with cart icon.

So create those. I'll use nav tag and inside it. I will first create logo.


<body>

<header> <!-- header will wrap our navbar and hero section -->
        <!-- navbar -->
        <nav class="navbar">
             <!-- logo -->
            <img src="img/logo.png" class="logo" alt="">
        </nav>
</header>

</body>

Enter fullscreen mode Exit fullscreen mode

So this will make an image, now we have to style our navbar to make it look like a navbar. For that in CSS file, you can add this CSS.


/* repo code above */

html {
    font-size: 16px;
}

body{
    font-family: 'Lato', sans-serif;
    color: var(--primary-text-color);
    background: var(--primary-color); /* variables are defined in :root selector of github repo*/
}

/* navbar */

.navbar{
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 4rem;
    display: flex;
    align-items: center;
    padding: 0 10vw;
    z-index: 9;
    background: var(--accent-color);
}

.logo{
    height: 1.5rem;
}
Enter fullscreen mode Exit fullscreen mode

So in the above code I am just setting "fixed" position to .navbar so it will stay on top irrespective of scrolling and gave it a display: flex so that we can make logo, search box, and links side by side instead of coming below each other.

So after logo, we need link. To create links we can use <ul> tag to create a list of <a> tags. Something Like this.

<nav class="navbar">

<!-- previous code -->
<!-- ul -->

<ul class="links-container">
    <li class="link-items"><a href="#" class="links">Menu</a></li>
    <li class="link-items"><a href="#" class="links">Order</a></li>
    <li class="link-items"><a href="#" class="links">Restaurants</a></li>
    <li class="link-items"><a href="#" class="links">Track Order</a></li>
</ul>

</nav>
Enter fullscreen mode Exit fullscreen mode

and we can style to the ul so that the links come side by side.

.links-container{
    display: flex;
    gap: 1rem;
    list-style: none;
    margin-left: 7.5%;
}

.links{
    color: var(--primary-text-color);
    text-decoration: none;
    text-transform: capitalize;
    padding: .5rem 1rem;
    transition: .2s;
}

.links:hover{
    color: var(--secondary-text-color);
}
Enter fullscreen mode Exit fullscreen mode

In Above code I have set .links-container element's display: flex so that all the links inside it comes side by side. Following that it has list-style: none property which if you don't know use to remove the bullet points from the list items.

After this we need a search box and cart icon in navbar. But to use icons I will use fontawesome. So use that, add its CDN in your head tag before style.css file.

<head>

<!-- previous code -->

<!-- font awesome cdn -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">

</head>
Enter fullscreen mode Exit fullscreen mode

Now we can use fontawesome icons. So inside navbar, let's create search box.

<nav class="navbar">

           <!-- previous code -->       

            <!-- search box -->
            <div class="nav-extras">
                <!-- search box -->
                <div class="search">
                    <input type="text" class="search-box" placeholder="Search Restaurants, Cuisine..... ">
                    <button class="search-btn"><i class="fa-solid fa-magnifying-glass"></i></button>
                </div>

                <!-- cart btn -->

                <a href="#" class="cart"><i class="fa-solid fa-cart-shopping"></i></a>
            </div>

</nav>
Enter fullscreen mode Exit fullscreen mode

and add stylings.


.nav-extras{
    display: flex;
    align-items: center;
    margin-left: auto;
    gap: 1rem;
}

.search{
    position: relative;
    width: 20vw;
    min-width: 150px;
    height: 2.5rem;
    border-radius: .5rem;
    overflow: hidden;
}

.search-box{
    width: 100%;
    height: 100%;
    background: var(--primary-color);
    border: none;
    padding: 1rem;
    outline: none;
    font-size: .9rem;
}

.search-btn{
    position: absolute;
    border: none;
    right: 0;
    width: 3rem;
    height: 100%;
    background: var(--primary-color);
    text-align: center;
    cursor: pointer;
    color: var(--secondary-text-color);
}

.cart{
    width: 2.5rem;
    height: 2.5rem;
    color: var(--secondary-text-color);
    border-radius: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    text-decoration: none;
    transition: .5s;
}

.cart:hover {
    background: var(--alpha-secondary-color);
}

Enter fullscreen mode Exit fullscreen mode

So after doing all this, the navbar should look like this.

Navbar

Okay now let's come to the main part. The hero section.

Hero Section

In our hero section, we have 2 divs one for hero content which is a group of texts and action buttons and the other one is a group of images and graphics to make the hero section more appealing. So let's create the group of texts first.

Inside header but outside nav add main tag and this will our hero section.

<header>

       <nav class="navbar">... Navbar HTML</nav>

        <!-- hero section -->

        <main id="hero-section">

            <!-- hero content -->
            <div class="hero-content">
                <h1 class="hero-heading">Eat the best</h1>
                <p class="hero-line">Explore and understand the culture more by tasting the amazing dishes of that culture</p>

                <div class="search location">
                    <input type="text" class="search-box" placeholder="Search Restaurants, Cuisine..... ">
                    <button class="search-btn locate-btn"><i class="fa-solid fa-location-crosshairs"></i></button>
                </div>

                <div class="hero-action-btn-container">
                    <button class="btn">Order Food</button>
                    <p class="or">or</p>
                    <button class="btn transparent">Make reservation</button>
                </div>
            </div>

        </main>
</header>
Enter fullscreen mode Exit fullscreen mode

Inside .hero-content element I have a h1 for heading, p for sub heading and then I have a .search.location element which is same as .search from the navbar I just added .location class to it so that I can add custom styles to this search box using .location class, and at last I have a div which contains 2 action buttons.

So now, let's style it and its really simple.

/* hero section */

#hero-section{
    min-height: 100vh;
    padding: 0 10vw;
    display: flex;
    justify-content: space-between;
    align-items: center;
    background: var(--accent-color);
}

.hero-content{
    width: 40%;
}

.hero-heading{
    font-size: 4rem;
    line-height: 5rem;
    font-weight: 700;
    color: var(--secondary-text-color);
}

.hero-line{
    line-height: 2rem;
    opacity: 0.75;
    margin-top: 2rem;
}

.search.location{
    width: 100%;
    height: 3.5rem;
    border-radius: .2rem;
    margin: 2.5rem 0;
}

.locate-btn{
    font-size: 1.2rem;
    width: 4rem;
    transition: .5s;
}

.search.location .search-box{
    padding: 1rem 1.5rem;
}

.hero-action-btn-container{
    display: flex;
    align-items: center;
    gap: 2rem;
}

.btn{
    padding: 1rem 1.5rem;
    border: none;
    border-radius: .3rem;
    font-size: 1rem;
    color: var(--light-text-color);
    background: var(--secondary-color);
    text-transform: capitalize;
    cursor: pointer;
}

.btn.transparent{
    background: transparent;
    border: .1rem solid var(--secondary-color);
    color: var(--secondary-text-color);
}

.hero-action-btn-container .or{
    color: var(--secondary-text-color);
}
Enter fullscreen mode Exit fullscreen mode

After adding above CSS, you should see something like this.

hero content

Now, we will create the images groups of hero section. So let's first make 3 circles where we will place images on top later.

<main id="hero-section">

        <!-- previous code -->
        <!-- hero image container -->

        <div class="hero-img-container">
            <div class="backgrond-ele">
                <div class="ellipse"></div>
                <div class="ellipse"></div>
                <div class="ellipse"></div>
            </div>
        </div>      

</main>
Enter fullscreen mode Exit fullscreen mode

.hero-img-container is a container which will contain all the images, review box and everything. .background-ele contains 3 divs of ellipse class. and we will use these 3 divs to create 3 circles of on top of each other with different width and rotation value. So add CSS now.

.hero-img-container{
    min-width: 30rem;
    min-height: 30rem;
    position: relative;
    transform: scale(0.9) translateY(1rem);
}

.background-ele{
    width: 100%;
    min-height: 100%;
    position: absolute;
}

.ellipse{
    position: absolute;
    height: 100%;
    top: 50%;
    left: 50%;
    border-radius: 100%;
    border: .01rem solid var(--secondary-color);
    transform-origin: center;
}

.ellipse:nth-child(1){
    width: 80%;
    transform: translate(-50%, -50%) rotate(20deg);
}

.ellipse:nth-child(2){
    width: 90%;
    transform: translate(-50%, -50%) rotate(40deg);
}

.ellipse:nth-child(3){
    width: 90%;
    transform: translate(-50%, -50%) rotate(-20deg);
}
Enter fullscreen mode Exit fullscreen mode

And the above code will simply make all the .ellipse on top of each other with different width and rotation. :nth-child is a CSS selector which lets you select individual element of same class or tag and using this I am able to select .ellipse individually to give them different styles.

ellipses

Now we want to add 3 food images on top this .background-ele for that, in HTML add the code inside #hero-section

<main id="hero-section">

         <!-- previous code -->

         <div class="forground-elements">
                <img src="img/hero-biryani.png" class="hero-img" alt="">
                <img src="img/hero-burger.png" class="hero-img" alt="">
                <img src="img/hero-pizza.png" class="hero-img" alt="">
         </div>

</main>
Enter fullscreen mode Exit fullscreen mode

Now add styles.

.hero-img{
    position: absolute;
    width: 10rem;
    border-radius: 100%;
    box-shadow:  0 1rem 1rem var(--shadow);
}

.hero-img:nth-child(1){
    width: 20rem;
    left: -8%;
    top: -15%;
}

.hero-img:nth-child(2){
    width: 15rem;
    right: -15%;
    top: 15%;
}

.hero-img:nth-child(3){
    width: 15rem;
    left: 35%;
    bottom: -20%;
}
Enter fullscreen mode Exit fullscreen mode

In above code I have given all the images position to absolute so that I can use top left bottom right properties to place the image anywhere we want. Now the problem using absolute is that it takes all the spaces then according to its relative parent so this is very important that you make sure that you have given relative position to .hero-img-container otherwise these absolute positioned elements won't consider .hero-img-container as a relative parent and to make sure that image stays on its place irrespective of screen size add a fixed width and height to .hero-img-container.

So you should see something like this now.

Hero images

Now the last thing we want is a review box over the food images. For that add this HTML after inside .forground-elements.

<!-- hero section -->

<main id="hero-section">

    <!-- hero image container -->

    <div class="hero-img-container">
        <!-- previous code -->
        <div class="forground-elements">
            <!-- previouse code -->

            <div class="review-box">
                <div class="reviewer-info">
                    <img src="img/user-1.png" class="reviewer-img" alt="">

                    <div class="reviewer">
                        <div class="reviewer-rating">
                            <i class="fa-solid fa-star"></i>
                            <i class="fa-solid fa-star"></i>
                            <i class="fa-solid fa-star"></i>
                            <i class="fa-solid fa-star"></i>
                            <i class="fa-solid fa-star-half-stroke"></i>
                            <p>4.5</p>
                        </div>
                        <h2 class="reviewer-name">Arik</h2>
                    </div>
                </div>
                <div class="review-body">
                    <i class="fa-solid fa-quote-left"></i>
                    <p class="review">The restaurant was good. Staff was very welcoming and the food.... well no words for it. Chef was amazing and the view of sky from the top deck was fabulous.</p>
                </div>
            </div>
        </div>
    </div>
</main>
Enter fullscreen mode Exit fullscreen mode

add add these styles.

.review-box{
    position: absolute;
    width: 30rem;
    padding: 1rem 2rem;
    bottom: 5%;
    left: -25%;
    border-radius: .5rem;
    background: var(--alpha-primary-color);
    backdrop-filter: blur(.5rem);
}

.reviewer-info{
    display: flex;
    gap: 1rem;
}

.reviewer-img{
    width: 3rem;
    height: 3rem;
    border-radius: 100%;
}

.reviewer-rating{
    display: flex;
    gap: .1rem;
    font-size: .7rem;
    align-items: center;
}

.reviewer-rating i{
    color: var(--rating-color);
}

.reviewer-name{
    font-weight: 400;
    font-size: 1.2rem;
    margin-top: .75rem;
}

.review-body{
    display: flex;
    gap: 1rem;
    margin-top: .5rem;
    padding: 1rem 0;
}

.review-body i{
    font-size: 1.4rem;
    color: var(--secondary-text-color);
}

.review{
    line-height: 1.75rem;
}
Enter fullscreen mode Exit fullscreen mode

Your hero section should look like this after applying above CSS styles.

hero section

Now the fun part, which will make this hero section next level. We need to add some animations. To add animations I will use AOS library, this library let's you add animation to elements on scroll. So to use it. We first need to import the library in our HTML file. So add these CDNS in their respective places.

<head>

    <!-- add this CDN before style.css link -->
    <!-- AOS CDN -->
    <link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">

</head>
<body>

    <!-- body HTML -->

    <!-- add this CDN before app.js import -->
    <script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>

</body>
Enter fullscreen mode Exit fullscreen mode

So this will import the AOS library, now we need to initialise it in order to use it and we can do that by adding AOS.init() in our app.js

AOS.init();
Enter fullscreen mode Exit fullscreen mode

AOS.init() also takes some parameters to change the default values of AOS library but we don't need that for now.

So the way we can add animation in HTML using this library is by adding data-aos attribute to the element. data-aos attributes is provided by AOS library and in value of data-aos you can give animation name either defaul animation or your custom animation name. So we can add this data-aos .hero-img-container HTML like this.

<!-- hero image container -->

<div class="hero-img-container">
    <div class="backgrond-ele" data-aos="fade-in" data-aos-delay="700">
        <div class="ellipse"></div>
        <div class="ellipse"></div>
        <div class="ellipse"></div>
    </div>
    <div class="forground-elements">
        <img src="img/hero-biryani.png" data-aos="zoom-in" data-aos-delay="0" class="hero-img" alt="">
        <img src="img/hero-burger.png" data-aos="zoom-in" data-aos-delay="150" class="hero-img" alt="">
        <img src="img/hero-pizza.png" data-aos="zoom-in" data-aos-delay="300" class="hero-img" alt="">

        <div class="review-box" data-aos="zoom-in" data-aos-delay="450">
            <div class="reviewer-info"  data-aos="zoom-out" data-aos-delay="600">
                <img src="img/user-1.png" class="reviewer-img" alt="">

                <div class="reviewer">
                    <div class="reviewer-rating">
                        <i class="fa-solid fa-star"></i>
                        <i class="fa-solid fa-star"></i>
                        <i class="fa-solid fa-star"></i>
                        <i class="fa-solid fa-star"></i>
                        <i class="fa-solid fa-star-half-stroke"></i>
                        <p>4.5</p>
                    </div>
                    <h2 class="reviewer-name">Arik</h2>
                </div>
            </div>
            <div class="review-body" data-aos="zoom-out" data-aos-delay="650">
                <i class="fa-solid fa-quote-left"></i>
                <p class="review">The restaurant was good. Staff was very welcoming and the food.... well no words for it. Chef was amazing and the view of sky from the top deck was fabulous.</p>
            </div>
        </div>
    </div>
</div>
Enter fullscreen mode Exit fullscreen mode

In above code you can see, I have given data-aos to those element whom I want to add animations. But you can also see data-aos-delay attribute. Well this attribute sets the animation delay in ms. So by adding this I can add delay in the animation trigger and every element won't appear at once.

So by doing this, you should see the animation.

fix

But if you something like this. Then we need to add another CSS. Well this data-aos adds transform properties on the element and since we are using transform to rotate the .ellipse already, data-aos is just re-writing its transform therefore creating this sort of effect. To fix this, we just need to tell CSS that don't overwrite .ellipse CSS like this.

[data-aos="fade-in"].aos-animate {
    transform: none !important;
}
Enter fullscreen mode Exit fullscreen mode

So the above CSS is selecting the element through attribute data-aos="fade-in" which is the attribute we have on .background-ele then .aos-animate is a AOS class which AOS adds to the element whenever the element is in scrollable zone means from where user can see the element. So instead of just selecting .backgroud.ele and setting its transform to none. Select like this in order to get the most specificity.

This will fix the animation issue and you should see something like this.

DEMO

So, that's it. Great work guys. We are done with the hero section.

I hope you understood each and everything. If you have doubt or I missed something let me know in the comments.

Articles you may find Useful

  1. Best CSS Effect
  2. Infinte CSS loader
  3. Disney+ Clone
  4. Youtube API - Youtube Clone
  5. TMDB - Netflix Clone

I really appreciate if you can subscribe my youtube channel. I create awesome web contents.

Source Code
Thanks for reading

Top comments (2)

Collapse
 
artydev profile image
artydev

Great Thank you :-)

Collapse
 
diomed profile image
May Kittens Devour Your Soul

you just included font family Lato but forgot to mention to grab it from google fonts

I had struggles with understanding navbar for quite a while, but I managed to do it.