Udacity Project Landing Page

This is the second project of Udacity Front End Nano Degree .

Project Requirement

– It should be responsive across desktop, tablet, and phone browsers.
– Navigation should be built dynamically as an unordered list.
– When navigation menu item is clicked, the link should scroll to it’s respective section.
– Clicked navigation menu item should be highlighted.
– Scrolling should be smooth.
– Viewed section should be differentiated from other section.

HTML

<header class="page_header">
        <nav class="navbar_menu">
            <ul id="navbar_ul"></ul>
        </nav>
 </header>
    <main>
        <header class="main_hero">
            <h1>Landing Page</h1>
        </header>   
        <section id="section1" data-nav="Section 1" class="section_container">
            <div class="active_section"></div>
            <div class="section_container_1 section">
                <h2>Section 1</h2>
                <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. 
                    Illo saepe nemo neque veniam exercitationem quod aspernatur
                    fugit consequuntur excepturi fuga. Ratione aliquid accusamus
                    nulla ipsum consectetur blanditiis eaque officiis debitis.
                    Esse aut dicta possimus tenetur voluptatibus laudantium vitae consequuntur
                    distinctio rem quae minus provident quas modi numquam hic molestiae
                    doloribus inventore explicabo quo labore? Sequi nihil soluta commodi
                    voluptas quidem.
                </p>
                <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. 
                    Sunt, eos perspiciatis. Consequuntur, iste magnam eaque,
                    veritatis architecto provident mollitia similique officia earum,
                    saepe laudantium dicta odio nostrum modi ullam repellendus?
                </p>
                <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. 
                    Sunt, eos perspiciatis. Consequuntur, iste magnam eaque,
                    veritatis architecto provident mollitia similique officia earum,
                    saepe laudantium dicta odio nostrum modi ullam repellendus?
                </p>
            </div>
        </section>
        <section id="section2" data-nav="Section 2" class="section_container">
            <div class="active_section"></div>
            <div class="section_container_2 section">
                <h2>Section 2</h2>
                <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. 
                    Illo saepe nemo neque veniam exercitationem quod aspernatur
                    fugit consequuntur excepturi fuga. Ratione aliquid accusamus
                    nulla ipsum consectetur blanditiis eaque officiis debitis.
                    Esse aut dicta possimus tenetur voluptatibus laudantium vitae consequuntur
                    distinctio rem quae minus provident quas modi numquam hic molestiae
                    doloribus inventore explicabo quo labore? Sequi nihil soluta commodi
                    voluptas quidem.
                </p>
                <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. 
                    Sunt, eos perspiciatis. Consequuntur, iste magnam eaque,
                    veritatis architecto provident mollitia similique officia earum,
                    saepe laudantium dicta odio nostrum modi ullam repellendus?
                </p>
                <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. 
                    Sunt, eos perspiciatis. Consequuntur, iste magnam eaque,
                    veritatis architecto provident mollitia similique officia earum,
                    saepe laudantium dicta odio nostrum modi ullam repellendus?
                </p>
            </div>
        </section>
        <section id="section3" data-nav="Section 3" class="section_container">
            <div class="active_section"></div>
            <div class="section_container_3 section">
                <h2>Section 3</h2>
                <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. 
                    Illo saepe nemo neque veniam exercitationem quod aspernatur
                    fugit consequuntur excepturi fuga. Ratione aliquid accusamus
                    nulla ipsum consectetur blanditiis eaque officiis debitis.
                    Esse aut dicta possimus tenetur voluptatibus laudantium vitae consequuntur
                    distinctio rem quae minus provident quas modi numquam hic molestiae
                    doloribus inventore explicabo quo labore? Sequi nihil soluta commodi
                    voluptas quidem.
                </p>
                <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. 
                    Sunt, eos perspiciatis. Consequuntur, iste magnam eaque,
                    veritatis architecto provident mollitia similique officia earum,
                    saepe laudantium dicta odio nostrum modi ullam repellendus?
                </p>
                <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. 
                    Sunt, eos perspiciatis. Consequuntur, iste magnam eaque,
                    veritatis architecto provident mollitia similique officia earum,
                    saepe laudantium dicta odio nostrum modi ullam repellendus?
                </p>
            </div>
        </section>
        <section id="section4" data-nav="Section 4" class="section_container">
            <div class="active_section"></div>
            <div class="section_container_4 section">
                <h2>Section 4</h2>
                <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. 
                    Illo saepe nemo neque veniam exercitationem quod aspernatur
                    fugit consequuntur excepturi fuga. Ratione aliquid accusamus
                    nulla ipsum consectetur blanditiis eaque officiis debitis.
                    Esse aut dicta possimus tenetur voluptatibus laudantium vitae consequuntur
                    distinctio rem quae minus provident quas modi numquam hic molestiae
                    doloribus inventore explicabo quo labore? Sequi nihil soluta commodi
                    voluptas quidem.
                </p>
                <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. 
                    Sunt, eos perspiciatis. Consequuntur, iste magnam eaque,
                    veritatis architecto provident mollitia similique officia earum,
                    saepe laudantium dicta odio nostrum modi ullam repellendus?
                </p>
                <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. 
                    Sunt, eos perspiciatis. Consequuntur, iste magnam eaque,
                    veritatis architecto provident mollitia similique officia earum,
                    saepe laudantium dicta odio nostrum modi ullam repellendus?
                </p>
            </div>
        </section>
    </main>

CSS

@import url('https://fonts.googleapis.com/css2?family=Roboto+Slab:wght@400;700&family=Roboto:wght@400;700&display=swap');

html{
    box-sizing: border-box;
    scroll-behavior: smooth;
}
*, 
*::before,
*::after{
    box-sizing: inherit;
}

body{
    padding: 0;
    margin: 0;
    color: #fff;
    font-family: 'Roboto', sans-serif;
    background-color: #031834;
}

.navbar_menu{
    background-color: #fff;
    position: fixed;
    top: 0;
    height: 50px;
    width: 100%;
    overflow: hidden;
    z-index: 100;
}

#navbar_ul{
    display: flex;
    justify-content: space-between;
    width: 90%;
    margin:0 auto;
}

.navbar_li{
    padding: 0 15px;
    line-height: 50px;
}

.navbar_li a{
    color: #000;
    text-decoration: none;
    font-size: 18px;
}
.active_li{
    background-color: #42e2ba;
}
main{
    width: 90%;
    height: 100%;
    margin:0 auto;
}

.main_hero{
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
}

.main_hero h1{
    font-size: 10vw;
}

section{
    position: relative;
}

.section h2{
    font-size: 38px;
    border-bottom: 1px solid yellow;
}

.section p{
    line-height: 1.4;
    font-size: 19px;
}

.section_container{
    padding: 19px;
    border: 1px solid #fff;
    height: 100vh;
    display: flex;
    align-items: center;
}

.section_container_2 h2{
     text-align: right;
}
    
.section_container_2 p{
    text-align: right;
}

.section_container_4 h2{
    text-align: right;
}

.section_container_4 p{
    text-align: right;
}

/* animation for active section */

/* add animating circle to odd number section*/
.circle_left{
    width: 130px;
    height: 130px;
    border-radius: 50%;
    background:rgba(255,255,255, 0.2);
    position: absolute;
    top: 55px;
    animation: animate_left 4s linear  infinite;
}
@keyframes animate_left{
    0%{
        transform: translateX(0px) ;
    }
    50%{
        transform: translateX(120px);
    }
    100%{
        transform: translateX(0px) rotateY(360deg);
    }
}

/* add animating circle to even number section*/
.circle_right{
    width: 130px;
    height: 130px;
    border-radius: 50%;
    background:rgba(255,255,255, 0.2);
    position: absolute;
    top: 55px;
    animation: animate_right 4s linear  infinite;
}
@keyframes animate_right{
    0%{
        transform: translateX(320px) ;
    }
    50%{
        transform: translateX(200px);
    }
    100%{
        transform: translateX(320px) rotateY(360deg);
    }
}

@media (min-width: 768px){

    #navbar_ul{
        justify-content: flex-end;
    }

    .navbar_li{
        padding: 0 15px;
        margin-left: 60px;
    }

    .navbar_li a{
        font-size: 22px;
    }

    .section h2{
        font-size: 48px;
    }

    .section p{
        font-size: 20px;
    }

     /* animation for active section */
    /* add animating circle to even number section*/
    
    .circle_left, .circle_right{
        top: 160px;
    }
    @keyframes animate_right{
        0%{
            transform: translateX(1380px) ;
        }
        50%{
            transform: translateX(1260px);
        }
        100%{
            transform: translateX(1380px) rotateY(360deg);
        }
    }
}

  @media (min-width: 1024px) {

    .section h2{
        font-size: 48px;
    }
    
    .section p{
        line-height: 1.6;
        font-size: 22px;
    }
   
    .section_container_1,
    .section_container_3{
        width: 70%;
    }

    .section_container_2,
    .section_container_4{
        width: 70%;
        margin-left: auto; 
        margin-right: 0;
    }
  }

JS

let ul = document.querySelector('#navbar_ul');
let list = document.querySelectorAll('.section_container');
let active_section = document.querySelectorAll('.active_section');

//Dynamically adding li to ul (Navigation)
for(let i =0; i<list.length; i++){
    let li = document.createElement('li');
    let link = document.createElement('a');
 
    link.href = `#${list[i].id}`;
    link.innerHTML = list[i].dataset.nav;
    li.appendChild(link);
    li.className = "navbar_li";
    ul.appendChild(li);
}
let nav_li = document.querySelectorAll('.navbar_li');

//Scroll to respective section from navigation menu (Scroll to Anchor)
nav_li.forEach(ele => {
    ele.addEventListener('click', e =>{
        e.preventDefault();
        let ahref_id = ele.firstChild.getAttribute("href");
        let section_id = document.querySelector(ahref_id);
        section_id.scrollIntoView();
    })
})

window.addEventListener('scroll', e =>{
    let currentSection = '';
    list.forEach(section =>{
        let section_top = window.scrollY + section.getBoundingClientRect().top; //section location relative to the viewport
        if(section_top <= scrollY + 350){
            currentSection = section.id;
        }
    })

    //Highlight active navigation menu li (Navbar Menu Active State)
    nav_li.forEach(li =>{
       let li_id = li.firstChild.getAttribute("href").slice(1);
        li.classList.remove('active_li');
        if(li_id === currentSection){
            li.classList.add('active_li');
        }    
    })
    
    // Add class to  a section that is being viewed (Section Active State)
    active_section.forEach(e =>{
        e.classList.remove('circle_left','circle_right');
        if(currentSection !== ''){
            let odd_even = +currentSection.slice(-1);
            let array_position = odd_even - 1;
            if(array_position % 2 === 0){
                active_section[array_position].classList.add('circle_left')
            }else{
                active_section[array_position].classList.add('circle_right')
            }   
        }  
    })

});