DEV Community

Cover image for Responsive Travel website using HTML, CSS and Javascript
Modern Web
Modern Web

Posted on

Responsive Travel website using HTML, CSS and Javascript

Website Preview Gif

In this article, you will learn to create this awesome fully responsive travel website using only HTML, CSS and Javascript. It is fully responsive and has animation on scroll, smooth scrolling, tile animated background images slider and a lot of stuff.

You can download the code.

So without wasting time let's see how to code this.

Let's go

Video Tutorial

Video tutorial if you like to watch a video and follow along.

Let's go

So to start coding or following this article. First you need to setup the folder.

For this project, we will use Google Fonts , AOS library for animations and Fontawesome for icons.

So you can either add CDNs manually or you can download the start files from this repo

Github Repo

Repo also includes all the images

So I hope you have the starting files now. Let's start with our navbar first.

Navbar

To create navbar we need to make a header and that header will contain the navbar, as well as the main section.

index.html
<header>
    <nav class="navbar">
        <ul class="links-container">
            <li class="link-item"><a href="#travel">Travel</a></li>
            <li class="link-item"><a href="#explore-section">Explore</a></li>
            <li class="link-item"><a href="#hero-section"><img src="img/logo.png" class="logo" alt=""></a></li>
            <li class="link-item"><a href="#services">Services</a></li>
            <li class="link-item"><a href="#booknow">Book Now</a></li>
        </ul>
    </nav>
</header>
Enter fullscreen mode Exit fullscreen mode

The value of href of links are id of the sections that we will create next. Giving ids as a link will take you to that section after clicking on the link.

But to add a smooth scrolling effect to the navbar links. Make sure you give scroll-behaviour to the html.

style.css
html{
    scroll-behavior: smooth;
}

body{
    font-family: 'Poppins', sans-serif;
    background: #161813;
    overflow-x: hidden;
}

.navbar{
    position: fixed;
    top: 0;
    left: 0;
    z-index: 9;
    width: 100%;
    height: 100px;
    padding: 20px 10vw;
}

.navbar.bg{
    background: #161813;
}

.links-container{
    display: flex;
    align-items: center;
    justify-content: center;
    list-style: none;
}

.logo{
    height: 50px;
    margin-top: 10px;
}

.link-item{
    margin: 0 20px;
    transition: .5s;
}

.link-item a{
    color: #fff;
    text-decoration: none;
    padding: 20px;
}

.link-item:hover{
    transform: scale(1.2);
}
Enter fullscreen mode Exit fullscreen mode
Output

Navbar

Hero Section

Now to create hero section we will use main tag inside header after nav.

index.html
<main class="hero-section" id="hero-section">

    <div class="hero-section-content" data-aos="fade-up">
        <h1 class="hero-section-title">wonderful experience</h1>
        <p class="hero-section-sub-heading">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
    </div>

    <!-- scroll down img -->
    <img src="img/down arrow.png" class="scroll-down-icon" alt="scroll down indicator">
</main>
Enter fullscreen mode Exit fullscreen mode

If you notice, i used data-aos attribute in code. This attribute is custom provided by AOS library to add sroll animations. In this case, I am adding fade-up effect. To make it work though. you have to put AOS.init() in app.js along with the CDNs provided in the github repo.

Make sure you download the repo to start

style.css
.hero-section{
    width: 100%;
    height: 100vh;
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;
    color: #fff;
}

.hero-section-title{
    font-family: 'Roboto Slab', serif;
    font-weight: 300;
    font-size: 80px;
    text-align: center;
    text-transform: capitalize; 
}

.hero-section-sub-heading{
    text-align: center;
    text-transform: capitalize;
    margin: 20px 0;
    font-size: 20px;
}

.scroll-down-icon{
    position: absolute;
    bottom: 10%;
    left: 50%;
    transform: translateX(-50%);
    width: 20px;
    animation: down ease 1s infinite;
}

@keyframes down{
    from { bottom: 10% }
    to { bottom: 8% }
}
Enter fullscreen mode Exit fullscreen mode
Output

Hero Section

Now the best part of this whole website, the background image slider.

Image Slider

To create Image Slider, first we will create a img below the content and then above img we will create 6 divs of background black in a grid. Those divs will cover whole image when needed. So basically, we will show those divs and hide them and in between we will change the background image using JS.

For this make .background div inside main before hero-section-content

index.html
<div class="background">
    <img src="img/img1.png" class="background-image" alt="hero-section image">

    <!-- grid -->
    <div class="grid-slider">
        <div class="grid-item hide"></div>
        <div class="grid-item hide"></div>
        <div class="grid-item hide"></div>
        <div class="grid-item hide"></div>
        <div class="grid-item hide"></div>
        <div class="grid-item hide"></div>
    </div>

</div>
Enter fullscreen mode Exit fullscreen mode

And give some styles.

.background{
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: -1;
}

.background-image{
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: -2;
}

.background::before, .background::after{
    content: '';
    position: absolute;
    left: 0;
    width: 100%;
    height: 50%;
}

.background::before{
    top: 0;
    left: 0;
    background: var(--gradient-top);
}

.background::after{
    bottom: 0;
    background: var(--gradient-bottom);
}

.grid-slider{
    width: 100%;
    height: 100%;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: repeat(2, 1fr);
}

.grid-item{
    width: 100%;
    height: 100%;
    background: #000;
    opacity: 1;
    transition: .5s;
}

.grid-item.hide{
    opacity: 0;
}
Enter fullscreen mode Exit fullscreen mode

If you see above code, I used ::before and ::after to create some linear gradients over the image to create the depth. The variables I used are in the CSS file of repo.

Output

Background Image

Now to make this slider working. Just add this simple JS code inside app.js file

//header

// slider images array

const sliderImgs = ["img1.png", "img2.png", "img3.png", "img4.png", "img5.png", "img6.png"];
let sliderImage = document.querySelector('.background-image');
let sliderGrids = [...document.querySelectorAll('.grid-item')];

let currentImage = 0;

setInterval(() => {
    changeSliderImage();
}, 5000);

const changeSliderImage = () => {
    sliderGrids.map((gridItem, index) => {
        setTimeout(() => {
            gridItem.classList.remove('hide');

            setTimeout(() => {

                if(index == sliderGrids.length - 1){
                    if(currentImage >= sliderImgs.length - 1){
                        currentImage = 0;
                    } else{
                        currentImage++;
                    }

                    sliderImage.src = `img/${sliderImgs[currentImage]}`;

                    sliderGrids.map((item, i) => {
                        setTimeout(() => {
                            item.classList.add('hide')
                        }, i * 100);
                    })

                }

            }, 100);

        }, index * 100);
    })
}
Enter fullscreen mode Exit fullscreen mode

After adding this, the slider will work. In above code we are basically using timeout to hide and show the 6 divs and in between changing the src of the image.

Output

slider

Explore Section

To create next section which is "explore section" Its actually simple. Just add this in index.html file.

index.html
<section class="explore-section" id="explore-section">
    <h1 class="section-title" data-aos="fade-up">Explore the world</h1>
    <p class="section-para" data-aos="fade-up">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut rutrum
        sem augue, vitae bibendum nibh tempor nec. Aenean quis commodo lectus, in rhoncus lorem</p>

    <!-- grid -->

    <div class="tours-container">
        <div class="tour-card" data-aos="fade-up">
            <img src="img/australia.png" class="tour-img" alt="tour-image">
            <div class="tour-body">
                <h3 class="tour-name">Australia</h3>
                <p class="tour-action">View city</p>
            </div>
        </div>

        <div class="tour-card" data-aos="fade-up">
            <img src="img/maldives.png" class="tour-img" alt="tour-image">
            <div class="tour-body">
                <h3 class="tour-name">Maldives</h3>
                <p class="tour-action">View city</p>
            </div>
        </div>

        <div class="tour-card" data-aos="fade-up">
            <img src="img/paris.png" class="tour-img" alt="tour-image">
            <div class="tour-body">
                <h3 class="tour-name">Paris</h3>
                <p class="tour-action">View city</p>
            </div>
        </div>

        <div class="tour-card" data-aos="fade-up">
            <img src="img/dubai.png" class="tour-img" alt="tour-image">
            <div class="tour-body">
                <h3 class="tour-name">Dubai</h3>
                <p class="tour-action">View city</p>
            </div>
        </div>

        <div class="tour-card" data-aos="fade-up">
            <img src="img/india.png" class="tour-img" alt="tour-image">
            <div class="tour-body">
                <h3 class="tour-name">India</h3>
                <p class="tour-action">View city</p>
            </div>
        </div>

        <div class="tour-card" data-aos="fade-up">
            <img src="img/italy.png" class="tour-img" alt="tour-image">
            <div class="tour-body">
                <h3 class="tour-name">Italy</h3>
                <p class="tour-action">View city</p>
            </div>
        </div>
    </div>
</section>
Enter fullscreen mode Exit fullscreen mode
style.css
/* explore section */

.explore-section{
    position: relative;
    width: 100%;
    padding: 80px 10vw;
    color: #fff;
}

.section-title{
    font-size: 30px;
    font-weight: 400;
    text-align: center;
    text-transform: capitalize;
}

.section-para{
    width: 50%;
    min-width: 300px;
    display: block;
    margin: 30px auto;
    text-align: center;
    line-height: 25px;
    opacity: 0.6;
}

.tours-container{
    position: relative;
    width: 100%;
    height: 600px;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-template-rows: repeat(2, 1fr);
    grid-gap: 20px;
    margin-top: 100px;
}

.tour-card{
    width: 100%;
    height: 100%;
    position: relative;
    border-radius: 20px;
    box-shadow: 0;
    overflow: hidden;
    padding: 10px;
    display: flex;
    align-items: end;
}

.tour-card:nth-child(2){
    grid-row: span 2;
}

.tour-card:last-child{
    grid-column: span 2;
}

.tour-img{
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: .5s;
    z-index: -1;
}

.tour-card:hover .tour-img{
    opacity: 0.8;
    transform: scale(1.1);
}

.tour-name{
    font-weight: 300;
}

.tour-action{
    margin-left: 20px;
    font-size: 14px;
    position: relative;
}

.tour-action::before{
    content: '';
    position: absolute;
    left: -20px;
    top: 2px;
    background: url('img/pin.png');
    width: 15px;
    height: 15px;
    background-size: contain;
}
Enter fullscreen mode Exit fullscreen mode
Output

Explore

If you see your output, you'll notice that the navbar and explore sections are overlapping and navbar is not fully readable. To fix that, we need to add background to the navbar after a certain amount of scroll using JS.

app.js
// nav

const navbar = document.querySelector('.navbar');

window.addEventListener('scroll', () => {
    if(scrollY >= 188){
        navbar.classList.add('bg');
    } else{
        navbar.classList.remove('bg')
    }
})
Enter fullscreen mode Exit fullscreen mode

and after adding this, you'll see after 188 of scrollY navbar changing its background color.

Service Section

In this section, for icons I am using fontawesome, so make sure you have its CDN to be able to see the icons in your code.

index.html
<section class="services-section" id="services">
    <h1 class="section-title" data-aos="fade-up">Why Us ?</h1>
    <p class="section-para" data-aos="fade-up">Lorem ipsum dolor sit amet, consectetur adipiscing elit. </p>

    <!-- services grid -->
    <div class="serives-grid">
        <div class="service-card" data-aos="fade-up">
            <div class="circle"></div>
            <i class="fa-solid fa-earth-americas card-icon"></i>
            <p class="service-text">We are based all over the world</p>
        </div>
        <div class="service-card" data-aos="fade-up">
            <div class="circle"></div>
            <i class="fa-solid fa-coins card-icon"></i>
            <p class="service-text">Travel the World,Without thinking</p>
        </div>
        <div class="service-card" data-aos="fade-up">
            <div class="circle"></div>
            <i class="fa-solid fa-book-open card-icon"></i>
            <p class="service-text">Get to know about local cultures</p>
        </div>
        <div class="service-card" data-aos="fade-up">
            <div class="circle"></div>
            <i class="fa-solid fa-person-snowboarding card-icon"></i>
            <p class="service-text">Have you best experience</p>
        </div>
    </div>

    <div class="bg-circle"></div>

    <div class="travel-grid" id="travel">
        <img src="img/img1.png" data-aos="fade-up" alt="">
        <img src="img/img2.png" data-aos="fade-up" alt="">
        <img src="img/img3.png" data-aos="fade-up" alt="">
        <img src="img/img4.png" data-aos="fade-up" alt="">
        <img src="img/img5.png" data-aos="fade-up" alt="">
        <img src="img/img6.png" data-aos="fade-up" alt="">
        <img src="img/australia.png" data-aos="fade-up" alt="">
        <img src="img/dubai.png" data-aos="fade-up" alt="">
        <img src="img/maldives.png" data-aos="fade-up" alt="">
        <img src="img/paris.png" data-aos="fade-up" alt="">
        <img src="img/india.png" data-aos="fade-up" alt="">
        <img src="img/italy.png" data-aos="fade-up" alt="">
    </div>

</section>
Enter fullscreen mode Exit fullscreen mode
style.css
/* services section */

.services-section{
    color: #fff;
    padding: 80px 10vw;
}

.serives-grid{
    width: 100%;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-gap: 20px;
}

.service-card{
    margin-top: 100px;
    width: 100%;
    height: 250px;
    border-radius: 20px;
    border: 1px solid #2D2D2D;
    background: #161813;
    padding: 10px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 20px;
    overflow: hidden;
    position: relative;
}

.card-icon{
    text-align: center;
    font-size: 60px;
    z-index: 1;
}

.service-text{
    text-align: center;
    padding: 0 20px;
    z-index: 1;
}

.circle{
    position: absolute;
    top: 0%;
    left: 0%;
    width: 100%;
    height: 100%;
    clip-path: circle(0% at 100% 100%);
    transition: .5s;
}

.service-card:nth-child(1) .circle{
    background: url(img/img5.png);
    background-size: cover;
}

.service-card:nth-child(2) .circle{
    background: url(img/img2.png);
    background-size: cover;
}

.service-card:nth-child(3) .circle{
    background: url(img/img6.png);
    background-size: cover;
}

.service-card:nth-child(4) .circle{
    background: url(img/img4.png);
    background-size: cover;
}

.service-card:hover .circle{
    clip-path: circle(141.4% at 100% 100%);
}

.travel-grid{
    width: 100%;
    columns: 3;
    column-gap: 20px;
    margin-top: 200px;
}

.travel-grid img{
    width: 100%;
    height: auto;
    object-fit: cover;
    margin-bottom: 20px;
    border-radius: 10px;
}

.bg-circle{
    z-index: -1;
    position: absolute;
    width: 500px;
    height: 500px;
    border-radius: 50%;
    background: var(--sphere-gradient-one);
    right: -250px;
}
Enter fullscreen mode Exit fullscreen mode
Output

Services

Book Section and footer

And the last but not least, book now and footer.

index.html
<!-- contact section -->
<section class="book-section" id="booknow">
    <div class="book-content" data-aos="fade-up">
        <h1 class="book-now-title">Book your travel today</h1>
        <p class="book-now-text">Give yourself and your family a peacfull and wonderful vacation this holiday</p>

        <button class="book-now">book now</button>
    </div>
    <div class="bg-circle-2"></div>
    <img src="img/book.png" data-aos="fade-up" class="book-now-img" alt="">
</section>

<!-- footer -->
<footer class="footer">
    <img src="img/logo.png" class="footer-logo" alt="">
    <div class="footer-text">
        <p>Travel the world, on this holiday</p>
        <p>Email - support@travel.com</p>
        <p>Phone - 99 88 776655, 99 88 776644</p>
    </div>
    <p class="copyright-line">This design is a concept design. Made by Modern Web ❤️</p>
</footer>
Enter fullscreen mode Exit fullscreen mode
style.css
/* book now section */

.book-section{
    position: relative;
    display: flex;
    padding: 0 10vw;
    align-items: center;
    width: 100%;
    height: 100vh;
    gap: 30px;
}

.book-now-img{
    position: absolute;
    width: 50%;
    right: 0;
}

.book-content{
    width: 50%;
    color: #fff;
}

.book-now-title{
    font-size: 50px;
    font-weight: 300;
    width: 300px;
}

.book-now-text{
    width: 300px;
    opacity: 0.5;
    line-height: 25px;
    margin: 30px 0;
}

.book-now{
    position: relative;
    padding: 10px 20px;
    outline: none;
    border: none;
    background: #000;
    text-transform: capitalize;
    color: #fff;
    border-radius: 20px;
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
    font-size: 18px;
    cursor: pointer;
    overflow: hidden;
}

.book-now::before{
    content: '';
    position: absolute;
    top: -10px;
    left: -30px;
    width: 20px;
    height: 200%;
    background: #fff;
    opacity: 0.2;
    transform: rotate(5deg);
    transition: .5s;
}

.book-now:hover::before{
    left: 100%;
}

.bg-circle-2{
    z-index: -1;
    position: absolute;
    width: 250px;
    height: 250px;
    border-radius: 50%;
    background:  var(--sphere-gradient-two);
    left: -125px;
    bottom: -100px;
}

.footer{
    width: 100%;
    padding: 100px 10vw;
    background: #000;
    display: flex;
    justify-content: space-evenly;
    flex-wrap: wrap;
    align-items: center;
    position: relative;
}

.footer-logo{
    width: 100px;
    opacity: 0.3;
}

.footer-text{
    color: #fff;
    opacity: 0.5;
    font-size: 20px;
}

.footer-text p{
    margin: 20px 0;
}

.copyright-line{
    width: 100%;
    background: #000;
    color: #fff;
    text-transform: capitalize;
    text-align: center;
    position: absolute;
    bottom: 0;
    left: 0;
    padding: 10px 0;
}
Enter fullscreen mode Exit fullscreen mode
Output

last section

So we are done, now to make this website responsive. Just use media-query of CSS like this.

style.css
/* tab view */

@media screen and (max-width: 996px) {
    .link-item{
        margin: 0 10px;
    }
    .hero-section-title{
        font-size: 60px;
    }
    .tours-container{
        height: 900px;
        grid-template-columns: repeat(2, 1fr);
        grid-template-rows: repeat(4, 1fr);
    }
    .tour-card:last-child{
        grid-column: span 1;
    }
    .tour-card:nth-child(3){
        grid-row: span 2;
    }
    .serives-grid{
        grid-template-columns: repeat(2, 1fr);
    }
    .service-card:nth-child(3), .service-card:nth-child(4){
        margin-top: 0;
    }
    .travel-grid{
        columns: 2;
    }
    .book-now-img{
        width: 40%;
    }
    .footer-logo{
        width: 70px;
    }
    .footer-text{
        font-size: 16px;
    }
}

/* much smaller device */

@media screen and (max-width:798px){
    .navbar{
        height: auto;
    }

    .link-item{
        margin-top: 80px;
        text-align: center;
    }
    .link-item:nth-child(3){
        margin: -50px -30px 0 -30px;
    }
    .link-item a{
        padding: 10px;
        margin: auto;
        display: block;
    }

    .section-title{
        font-size: 50px;
    }
    .grid-slider{
        grid-template-rows: repeat(3, 1fr);
        grid-template-columns: repeat(2, 1fr);
    }
    .hero-section-sub-heading{
        font-size: 16px;
    }
    .section-para{
        width: 100%;
    }
    .tours-container{
        height: 1200px;
        grid-template-columns: repeat(1, 1fr);
        grid-template-rows: repeat(6, 1fr);
    }
    .tour-card:nth-child(2){
        grid-row: auto;
    }
    .tour-card:last-child{
        grid-column: span 1;
    }
    .tour-card:nth-child(3){
        grid-row: span 1;
    }
    .serives-grid{
        grid-template-columns: repeat(1, 1fr);
    }
    .service-card:nth-child(2){
        margin-top: 0;
    }
    .travel-grid{
        columns: 1;
    }
    .book-section{
        height: auto;
        padding: 80px 10vw;
    }
    .bg-circle{
        display: none;
    }
    .bg-circle-2{
        z-index: 2;
    }
    .book-now-img{
        width: 100%;
        opacity: 0.3 !important;
    }
    .book-content{
        width: 100%;
        z-index: 2;
        text-align: center;
    }
    .book-now-title, .book-now-text{
        width: 100%;
    }
}
Enter fullscreen mode Exit fullscreen mode

And the website is done. Its fully responsive now too.

So we are done, we made this awesome responsive travel website. If you stuck anywhere or run into some error, feel free to leave a comment or DM me on instagram.

I hope you like this article, you like the website design and the tutorial. If this helped you in someway make sure you follow me on my instagram and youtube.

You can checkout my youtube channel, I create lots of content like this including fullstack ecommerce website and fullstack blogging website.

You can download the code. Thanks for reading 👋

Oldest comments (5)

Collapse
 
mide202016 profile image
mide2020-16

Thanks this is great

Collapse
 
artydev profile image
artydev

You are awesome.
Thank you :-)

Collapse
 
kalejaiye75 profile image
Kalejaiye75

Thanks for sharing this, it's really helpful..

Collapse
 
dasasa profile image
Fozla • Edited

Greetings to all! Our extensive and unique knowledge in this field allows us to provide the most relevant and useful information Hungary residence by investment immigrantinvest.com/blog/hungary-g... . We will not only tell you about the program, but also guide you through all the stages, helping you overcome difficulties and get the citizenship you so much desire.

Collapse
 
ericryan3132 profile image
ericryan3132

Thank you for sharing your detailed tutorial on creating a responsive travel website using HTML, CSS, and JavaScript. Your step-by-step instructions have been immensely helpful as I've been following along to create my own marrakech vs casablanca website. The clear explanations and structured approach you've provided have made the process smooth and enjoyable. I appreciate the effort you've put into sharing your knowledge and expertise, and I look forward to exploring more of your tutorials in the future.