smooth scroll on sticky menu with sfixed sidebar

33 Views Asked by At

I am working on creating a section with a sticky menu on the left column. The right column contains multiple small paragraphs/sections that should smoothly scroll when clicked from the menu. Each paragraph corresponds to its own menu item.

However, I'm facing an issue with applying smooth scroll specifically to the right column. If I enable it, the entire page scrolls down. I've attempted using CSS transitions, but it results in scrolling up the entire column, and clicking a menu item still causes the page to jump to the relative paragraph.

I want the smooth scroll to be triggered by clicking a menu item and smoothly scrolling only the right column to the corresponding paragraph.

This is my code:

HTML

    <div class="infoscroller">
        <div class="left-column">
            <ul>
                <li class="active" data-section="section-1"><span class="circle"></span><a href="#section-1" data-scroll>Prototyping</a></li>
                <li data-section="section-2"><span class="circle"></span><a href="#section-2" data-scroll>Brand Identity</a></li>
                <li data-section="section-3"><span class="circle"></span><a href="#section-3" data-scroll>Design Building</a></li>
                <li data-section="section-4"><span class="circle"></span><a href="#section-4" data-scroll>Usability Tests</a></li>
            </ul>
        </div>
        <div class="right-column">
                <section id="section-1">
                    <h2>Prototyping</h2>
                    <p>Analysis of the target and prototype composing to create a proposal that will coherently be in line with your vision.<br>This made possible through various tools and researches </p>
                </section>
                <section id="section-2">
                    <h2>Brand Identity</h2>
                    <p>Developing a product that adheres to identity rules involves establishing coherent brand elements such as color palettes, shapes, and marketing targets, ensuring a consistent and cohesive visual identity.</p>
                </section>
                <section id="section-3">
                    <h2>Design Building</h2>
                    <p>Creating a product that aligns with identity rules entails the establishment of consistent brand elements, including meticulously chosen color palettes, distinct shapes, and targeted marketing strategies. This process ensures the development of a visual identity that is not only harmonious but also cohesive, reflecting the brand's essence and values.</p>
                </section>
                <section id="section-4">
                    <h2>Usability Tests</h2>
                    <p>The analysis of the target audience and the composition of prototypes are essential steps in formulating a proposal that seamlessly aligns with your vision. This harmonious integration is made possible through the utilization of various tools and comprehensive research methods. By conducting usability tests, the proposed design is refined and optimized, ensuring that it not only meets but exceeds the expectations and preferences of the intended audience.</p>
                </section>
                <section id="section-empty">
                </section>
        </div>
    </div>

JS

document.addEventListener('DOMContentLoaded', function () {
    var leftColumn = document.querySelector('.left-column');
    var rightColumn = document.querySelector('.right-column');
    var sectionsContainer = document.querySelector('.column-container');
    var leftColumnItems = document.querySelectorAll('.left-column li');

    leftColumn.addEventListener('click', function (event) {
        var targetLi = event.target.closest('li');
        if (targetLi) {
            leftColumn.querySelector('li.active').classList.remove('active');
            targetLi.classList.add('active');

            var sectionId = targetLi.getAttribute('data-section');
            var targetSection = document.getElementById(sectionId);

            
            var sectionOffset = targetSection.offsetTop - sectionsContainer.offsetTop;

            
            sectionsContainer.style.transition = 'transform 0.5s ease';
            sectionsContainer.style.transform = 'translateY(-' + sectionOffset + 'px)';

            
            setTimeout(function () {
                sectionsContainer.style.transition = '';
            }, 500);
        }
    });

    leftColumnItems.forEach(function (item, index) {
        item.addEventListener('mouseenter', function () {
            var circle = item.querySelector('.circle');
            if (circle) {
                circle.style.width = '100%';
                circle.style.borderRadius = '50%';
            }
        });

        item.addEventListener('mouseleave', function () {
            var circle = item.querySelector('.circle');
            if (circle) {
                circle.style.width = '';
                circle.style.borderRadius = '';
            }
        });
    });
});

CSS

body {
  background: black;
}

.infoscroller {
    display: flex;
    max-width: 90%;
    margin: 0 auto;
    margin-top: 100px;
    border-top: 1px solid white;
}

.left-column {
    width: 35%;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
    padding-top: 100px;
    min-width: 35%;
}

.left-column a {
    text-decoration: none;
    color: white;
}

.left-column li a:hover + .circle,
.left-column li a.active + .circle {
    width: 100%;
    border-radius: 50%;
}

.left-column ul {
    list-style-type: none;
    padding: 0;
    font-size: 2em;
    text-transform: uppercase;
    max-width: 50%;
    margin: 0 auto;
}

.left-column li {
    margin-bottom: 10px;
    position: relative;
    cursor: pointer;
}

.left-column .circle {
    display: inline-block;
    width: 30px;
    height: 30px;
    background-color: #f7f7f700;
    border: 1px solid white;
    border-radius: 50%;
    position: absolute;
    left: -45px;
    top: 50%;
    transform: translateY(-50%);
    transition: all 0.5s ease;
}

.circle {
    pointer-events: none;
}

.right-column {
    flex-grow: 1; 
  color: white;
    max-height: 500px;
    overflow-y: auto;
    padding: 20px;
    border-left: 1px white solid;
    transition: transform 0.5s ease; 
}

.right-column section {
    margin-bottom: 20px;
    min-height: 300px;
}

.right-column section:not(:last-child) {
    border-bottom: 1px solid #fff;
}

.right-column section h2 {
    margin-bottom: 10px;
    padding-top: 100px;
    text-transform: uppercase;
}

.right-column p {
    margin: 0;
    max-width: 50%;
}

.left-column li.active .circle {
    width: 100%;
    border-radius: 50%;
}

.section-empty {
    min-height: 600px;
}

Could it be done or is it just not possible to smooth scroll only inside the column? Thanks

Here you can se the code in action

I've tryed with css transitiona and js coding, i would like to understand if it possible or if i should design it differently

0

There are 0 best solutions below