Make WordPress Core

Changeset 46824


Ignore:
Timestamp:
12/07/2019 11:03:09 AM (5 years ago)
Author:
SergeyBiryukov
Message:

Twenty Twenty: Replace Smooth Scroll JS implementation with scroll-behavior CSS property.

The JS implementation had multiple issues and did not work as expected.

This change includes an accessibility enhancement by using prefers-reduced-motion: reduce media query property for users that don't want motion effects. For further explanation on this media query, see MDN documentation: https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior#Accessibility_concerns

Props audrasjb, melchoyce, joostdevalk, Anlino, mauteri, sergiomdgomes, littlebigthing, williampatton, netweb, andraganescu, joyously, acosmin, mukesh27, hareesh-pillai.
Fixes #48763, #48551, #48866.

Location:
trunk/src/wp-content/themes/twentytwenty
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-content/themes/twentytwenty/assets/js/index.js

    r46786 r46824  
    324324
    325325/*  -----------------------------------------------------------------------------------------------
    326     Smooth Scroll
    327 --------------------------------------------------------------------------------------------------- */
    328 
    329 twentytwenty.smoothScroll = {
    330 
    331     init: function() {
    332         // Scroll to anchor
    333         this.scrollToAnchor();
    334 
    335         // Scroll to element
    336         this.scrollToElement();
    337     },
    338 
    339     // Scroll to anchor
    340     scrollToAnchor: function() {
    341         var anchorElements = document.querySelectorAll( 'a[href*="#"]' );
    342         var anchorElementsList = Array.prototype.slice.call( anchorElements );
    343         anchorElementsList.filter( function( element ) {
    344             if ( element.href === '#' || element.href === '#0' || element.id === 'cancel-comment-reply-link' || element.classList.contains( 'do-not-scroll' ) || element.classList.contains( 'skip-link' ) ) {
    345                 return false;
    346             }
    347             return true;
    348         } ).forEach( function( element ) {
    349             element.addEventListener( 'click', function( event ) {
    350                 var target, scrollOffset, originalOffset, adminBar, scrollSpeed, additionalOffset;
    351 
    352                 // On-page links
    353                 if ( window.location.hostname === event.target.hostname ) {
    354                     // Figure out element to scroll to
    355                     target = window.location.hash !== '' && document.querySelector( window.location.hash );
    356                     target = target ? target : event.target.hash !== '' && document.querySelector( event.target.hash );
    357 
    358                     // Does a scroll target exist?
    359                     if ( target ) {
    360                         // Only prevent default if animation is actually gonna happen
    361                         event.preventDefault();
    362 
    363                         // Get options
    364                         additionalOffset = event.target.dataset.additionalOffset;
    365                         scrollSpeed = event.target.dataset.scrollSpeed ? event.target.dataset.scrollSpeed : 500;
    366 
    367                         // Determine offset
    368 
    369                         adminBar = document.querySelector( '#wpadminbar' );
    370 
    371                         originalOffset = target.getBoundingClientRect().top + window.pageYOffset;
    372                         scrollOffset = additionalOffset ? originalOffset + additionalOffset : originalOffset;
    373 
    374                         if ( adminBar && event.target.className === 'to-the-top' ) {
    375                             scrollOffset = scrollOffset - adminBar.getBoundingClientRect().height;
    376                         }
    377 
    378                         twentytwentyScrollTo( scrollOffset, null, scrollSpeed );
    379 
    380                         window.location.hash = event.target.hash.slice( 1 );
    381                     }
    382                 }
    383             } );
    384         } );
    385     },
    386 
    387     // Scroll to element
    388     scrollToElement: function() {
    389         var scrollToElement = document.querySelector( '*[data-scroll-to]' );
    390 
    391         if ( scrollToElement ) {
    392             scrollToElement.addEventListener( 'click', function( event ) {
    393                 var originalOffset, additionalOffset, scrollOffset, scrollSpeed,
    394                     // Figure out element to scroll to
    395                     target = event.target.dataset.twentytwentyScrollTo;
    396 
    397                 // Make sure said element exists
    398                 if ( target ) {
    399                     event.preventDefault();
    400 
    401                     // Get options
    402                     additionalOffset = event.target.dataset.additionalOffset;
    403                     scrollSpeed = event.target.dataset.scrollSpeed ? event.target.dataset.scrollSpeed : 500;
    404 
    405                     // Determine offset
    406                     originalOffset = target.getBoundingClientRect().top + window.pageYOffset;
    407                     scrollOffset = additionalOffset ? originalOffset + additionalOffset : originalOffset;
    408 
    409                     twentytwentyScrollTo( scrollOffset, null, scrollSpeed );
    410                 }
    411             } );
    412         }
    413     }
    414 
    415 }; // twentytwenty.smoothScroll
    416 
    417 /*  -----------------------------------------------------------------------------------------------
    418326    Modal Menu
    419327--------------------------------------------------------------------------------------------------- */
     
    746654    twentytwenty.coverModals.init();    // Handle cover modals
    747655    twentytwenty.intrinsicRatioVideos.init();   // Retain aspect ratio of videos on window resize
    748     twentytwenty.smoothScroll.init();   // Smooth scroll to anchor link or a specific element
    749656    twentytwenty.modalMenu.init();  // Modal Menu
    750657    twentytwenty.primaryMenu.init();    // Primary Menu
     
    892799    return parents;
    893800}
    894 
    895 // twentytwentyEaseInOutQuad functions http://goo.gl/5HLl8
    896 function twentytwentyEaseInOutQuad( t, b, c, d ) {
    897     t /= d / 2;
    898     if ( t < 1 ) {
    899         return ( ( ( c / 2 ) * t ) * t ) + b;
    900     }
    901     t--;
    902     return ( ( -c / 2 ) * ( ( t * ( t - 2 ) ) - 1 ) ) + b;
    903 }
    904 
    905 function twentytwentyScrollTo( to, callback, duration ) {
    906     var start, change, increment, currentTime;
    907 
    908     function move( amount ) {
    909         document.documentElement.scrollTop = amount;
    910         document.body.parentNode.scrollTop = amount;
    911         document.body.scrollTop = amount;
    912     }
    913 
    914     start = document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop;
    915     change = to - start;
    916     increment = 20;
    917     currentTime = 0;
    918 
    919     duration = ( typeof ( duration ) === 'undefined' ) ? 500 : duration;
    920 
    921     function animateScroll() {
    922         var val;
    923 
    924         // increment the time
    925         currentTime += increment;
    926         // find the value with the quadratic in-out twentytwentyEaseInOutQuad function
    927         val = twentytwentyEaseInOutQuad( currentTime, start, change, duration );
    928         // move the document.body
    929         move( val );
    930         // do the animation unless its over
    931         if ( currentTime < duration ) {
    932             window.requestAnimationFrame( animateScroll );
    933         } else if ( callback && typeof ( callback ) === 'function' ) {
    934             // the animation is done so lets callback
    935             callback();
    936         }
    937     }
    938     animateScroll();
    939 }
  • trunk/src/wp-content/themes/twentytwenty/style-rtl.css

    r46762 r46824  
    116116html {
    117117    font-size: 62.5%; /* 1rem = 10px */
     118    scroll-behavior: smooth;
     119}
     120
     121@media (prefers-reduced-motion: reduce) {
     122    html {
     123        scroll-behavior: auto;
     124    }
    118125}
    119126
  • trunk/src/wp-content/themes/twentytwenty/style.css

    r46762 r46824  
    116116html {
    117117    font-size: 62.5%; /* 1rem = 10px */
     118    scroll-behavior: smooth;
     119}
     120
     121@media (prefers-reduced-motion: reduce) {
     122    html {
     123        scroll-behavior: auto;
     124    }
    118125}
    119126
Note: See TracChangeset for help on using the changeset viewer.