Make WordPress Core

Changeset 46824


Ignore:
Timestamp:
12/07/2019 11:03:09 AM (7 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.