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
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.
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>
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>
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;
}
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>
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);
}
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>
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>
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);
}
So after doing all this, the navbar should look like this.
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>
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);
}
After adding above CSS, you should see something like this.
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>
.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);
}
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.
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>
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%;
}
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.
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>
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;
}
Your hero section should look like this after applying above CSS styles.
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>
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();
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>
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.
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;
}
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.
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
I really appreciate if you can subscribe my youtube channel. I create awesome web contents.
Source Code
Thanks for reading
Top comments (2)
Great Thank you :-)
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.