0

I am trying to add an on-click-smooth-scroll effect like this one: https://michalsnik.github.io/aos/

I have read this: Smooth scroll to specific div on click and I am unable to adapt it. I don't understand what scrollTop: $("#page2").offset().top does.

My issue is that the scroll is "snapping". And that's probably because I have applied scroll-snap on the containers.

Also, when you're in-between the pages and click on the scroll down arrow it will either move up or down.

I would like to get the second page on full view whenever I press on that arrow. It should Scroll Down until #page2 has height: 100vh or it occupies the whole view port.

// eliminate scroll-bar
var child = document.getElementById('child-container');
child.style.right = child.clientWidth - child.offsetWidth + "px";

//scroll down effect on scroll-down-arrow
$(".scroll-down-arrow").click(function() {
    $('html,body,#child-container').animate({scrollTop: $("#page2").offset().top}, 'slow', 'linear');
});
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
  margin: 0;
 padding: 0;
 border: 0;
 font-size: 100%;
 font: inherit;
 vertical-align: baseline;
}

/* *** index.html - START *** */

body, html {
    height: 100%;
    width: 100%;
    overflow: hidden;
}

#parent-container {
    height: 100%;
    width: 100%;
    overflow: hidden;
    position: relative;
}
#child-container {
    position: absolute;
    top: 0px;
    bottom: 0px;
    left: 0px;
    right: 0px; /* exact value is given through JavaScript */
    overflow: auto;
    scroll-snap-type: both proximity;
}

header {    
    height: 100%;
    background-color: grey;
    background-attachment: fixed;
    background-position: bottom center;
    background-repeat: no-repeat;
    background-size: cover;
    text-align: center;
    scroll-snap-align: center;
}

header h1 {
    font-size: 32px;
    font-weight: bold;
    position: sticky;
    top: 5%;
    margin-bottom:10px;
}

header p {
    position: sticky;
    width: 450px;
    text-align: center;
    margin: auto;
    margin-top: 100px;
    font-size: 1.5em;
}

header .scroll-down-arrow {
 position: absolute;
 left: 50%;
 bottom: 20px;
 display: block;
 text-align: center;
 font-size: 20px;
 z-index: 100;
 text-decoration: none;
 text-shadow: 0;
    width: 30px;
    height: 30px;
    border-bottom: 2px solid #fff;
    border-right: 2px solid #fff;
    left: 50%;
    transform: translate(-50%, 0%) rotate(45deg);
    animation: fade_move_down 3s ease-in-out infinite;
    cursor: pointer;
}

/*animated scroll arrow animation*/
@keyframes fade_move_down {
    0%   { transform:translate(0,-15px) rotate(45deg); opacity: 0;  }
    25%  {opacity: 1;}
    /* 50%  { opacity: 1;  } */
    100% { transform:translate(0,10px) rotate(45deg); opacity: 0; }
  }

.container_page_2 {
    width: 100%;
    height: 100vh;
    scroll-snap-align: center;
    overflow: hidden;
    position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>


<div id="parent-container">
        <div id="child-container">

            <!-- #header -->
            <header>
                <div class="nav-container">
                    <ul>
                        <li></li>
                        <li></li>
                        <li></li>
                    </ul>
                </div>
                <a href="#page2"><h1 id="sticky-title">Lorem ipsum</h1></a>
                <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Modi debitis in libero tenetur suscipit iusto eum nulla dolorum aperiam adipisci unde veritatis vel iure, a nam, saepe exercitationem illum vitae.</p>
                <div class="scroll-down-arrow"></div>
            </header>

            <!-- #page2 -->
            <div id="page2" class="container_page_2">
                <div class="column active">
                    <div class="content">
                        <h1>1</h1>
                        <div class="box">
                            <h2>background-attachment: fixed;</h2>
                            <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Inventore necessitatibus possimus fuga voluptate incidunt enim eius sed, ad suscipit error quasi ex blanditiis ipsa, at vero officiis voluptatem a modi!                                
                            </p>
                        </div>
                    </div>
                    <div class="bg bg1"></div>
                </div>
                <div class="column">
                    <div class="content">
                        <h1>2</h1>
                        <div class="box">
                            <h2>background-attachment: scroll;</h2>
                            <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Inventore necessitatibus possimus fuga voluptate incidunt enim eius sed, ad suscipit error quasi ex blanditiis ipsa, at vero officiis voluptatem a modi!                                
                            </p>
                        </div>
                    </div>
                    <div class="bg bg2"></div>
                </div>
                <div class="column">
                    <div class="content">
                        <h1>3</h1>
                        <div class="box">
                            <h2>background-attachment: scroll;</h2>
                            <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Inventore necessitatibus possimus fuga voluptate incidunt enim eius sed, ad suscipit error quasi ex blanditiis ipsa, at vero officiis voluptatem a modi!                                
                            </p>
                        </div>
                    </div>
                    <div class="bg bg3"></div>
                </div>
                <div class="column">
                    <div class="content">
                        <h1>4</h1>
                        <div class="box">
                            <h2>background-attachment: fixed;</h2>
                            <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Inventore necessitatibus possimus fuga voluptate incidunt enim eius sed, ad suscipit error quasi ex blanditiis ipsa, at vero officiis voluptatem a modi!                                
                            </p>
                        </div>
                    </div>
                    <div class="bg bg4"></div>
                </div>
            </div>

https://codepen.io/bleah1/pen/gjYBgQ

I haven't added all the elements from the second page, but it doesn't matter, because the scrolling isn't affected. As you can see it's not smooth at all, it's actually pretty snappy.

What do you think ? I would like to keep the scroll-snap, because I like that idea.

2 Answers2

2

Hi can you try this solution. Basically I removed the css when click event starts then added it when the scrollTop event ends. Remember to remove it from your css #child-container

$(".scroll-down-arrow").click(function() {
  $('#child-container').css('scroll-snap-type','')
    $('html,body,#child-container').animate({
       scrollTop: $("#page2").offset().top}, 'slow', 'linear')
      .promise()
      .done(() => {$('#child-container')
      .css('scroll-snap-type','both proximity')
    });
});
Ekin Alcar
  • 125
  • 3
  • 7
  • That is half of the solution. This eliminates `scroll-snap` forever and only adds it after I click on the arrow. I think that we should eliminate `scroll-snap` on click, but before or after the smooth scroll it should still be active. – GeorgicaFaraFrica Dec 19 '19 at 10:50
  • Also, if this code `$('#child-container').css('scroll-snap-type','');` is supposed to eliminate the `scroll-snap` on click, why do I have to remove `scroll-snap-type: both proximity;` from `#child-container` ? – GeorgicaFaraFrica Dec 19 '19 at 11:02
  • It also doesn't fix the effect of scrolling up or down whenever you're in between pages. – GeorgicaFaraFrica Dec 19 '19 at 11:03
  • I've fixed it. The trick to getting your answer to work is that `.css` will only remove the element's attributes defined in the "style" attribute. So, adding `scroll-snap-type: both proximity;` as `style` inside the HTML like this: `
    ` fixed all of the issues. I think you should edit your answer and I will accept it as the answer.
    – GeorgicaFaraFrica Dec 19 '19 at 11:18
  • 1
    Also, to fix the effect of scrolling up or down whenever you're in between pages I've replaced `scrollTop: $("#page2").offset().top` with `scrollTop: $(window).height()`. Don't ask me why it works, but it does. – GeorgicaFaraFrica Dec 19 '19 at 11:23
0

Based on @Ekin Alcar answer I was able to fix my issue. I followed his idea of removing the scroll-snap-type css attribute from #child-container by using $('#child-container').css('scroll-snap-type',''); inside of the original script, like this:

$(".scroll-down-arrow-container").click(function() {
    $('#child-container').css('scroll-snap-type','');
    $('html, body, #child-container').animate({
            scrollTop: $(window).height()
        }, 1000)
    .promise()
    .done(() => {$('#child-container')
        .css('scroll-snap-type','both proximity')
    });
});

The trick with .css is that it can only remove attributes that are used in the style tag inside a .html file. It won't work with a .css stylesheet.

From the API's documentation:

It does not, however, remove a style that has been applied with a CSS rule in a stylesheet or < style > element.

As such scroll-snap-type: both proximity; was removed from the .css file and added in the .html file:

<div id="child-container" style="scroll-snap-type: both proximity;">

Also, to fix the effect of scrolling up or down whenever you're in between pages I've replaced scrollTop: $("#page2").offset().top with scrollTop: $(window).height(). Don't ask me why it works, but it does.