From bd3bd0c6ff464c82b1baf7f1ef271651c07e9fa0 Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Sat, 7 Dec 2019 11:08:01 +0000 Subject: [PATCH] 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. Merges [46824] to the 5.3 branch. Fixes #48763, #48551, #48866. Built from https://develop.svn.wordpress.org/branches/5.3@46825 git-svn-id: http://core.svn.wordpress.org/branches/5.3@46625 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- .../themes/twentytwenty/assets/js/index.js | 139 ------------------ wp-content/themes/twentytwenty/style-rtl.css | 7 + wp-content/themes/twentytwenty/style.css | 7 + wp-includes/version.php | 2 +- 4 files changed, 15 insertions(+), 140 deletions(-) diff --git a/wp-content/themes/twentytwenty/assets/js/index.js b/wp-content/themes/twentytwenty/assets/js/index.js index 9234f11976..5ded1852ac 100644 --- a/wp-content/themes/twentytwenty/assets/js/index.js +++ b/wp-content/themes/twentytwenty/assets/js/index.js @@ -322,98 +322,6 @@ twentytwenty.intrinsicRatioVideos = { }; // twentytwenty.instrinsicRatioVideos -/* ----------------------------------------------------------------------------------------------- - Smooth Scroll ---------------------------------------------------------------------------------------------------- */ - -twentytwenty.smoothScroll = { - - init: function() { - // Scroll to anchor - this.scrollToAnchor(); - - // Scroll to element - this.scrollToElement(); - }, - - // Scroll to anchor - scrollToAnchor: function() { - var anchorElements = document.querySelectorAll( 'a[href*="#"]' ); - var anchorElementsList = Array.prototype.slice.call( anchorElements ); - anchorElementsList.filter( function( element ) { - if ( element.href === '#' || element.href === '#0' || element.id === 'cancel-comment-reply-link' || element.classList.contains( 'do-not-scroll' ) || element.classList.contains( 'skip-link' ) ) { - return false; - } - return true; - } ).forEach( function( element ) { - element.addEventListener( 'click', function( event ) { - var target, scrollOffset, originalOffset, adminBar, scrollSpeed, additionalOffset; - - // On-page links - if ( window.location.hostname === event.target.hostname ) { - // Figure out element to scroll to - target = window.location.hash !== '' && document.querySelector( window.location.hash ); - target = target ? target : event.target.hash !== '' && document.querySelector( event.target.hash ); - - // Does a scroll target exist? - if ( target ) { - // Only prevent default if animation is actually gonna happen - event.preventDefault(); - - // Get options - additionalOffset = event.target.dataset.additionalOffset; - scrollSpeed = event.target.dataset.scrollSpeed ? event.target.dataset.scrollSpeed : 500; - - // Determine offset - - adminBar = document.querySelector( '#wpadminbar' ); - - originalOffset = target.getBoundingClientRect().top + window.pageYOffset; - scrollOffset = additionalOffset ? originalOffset + additionalOffset : originalOffset; - - if ( adminBar && event.target.className === 'to-the-top' ) { - scrollOffset = scrollOffset - adminBar.getBoundingClientRect().height; - } - - twentytwentyScrollTo( scrollOffset, null, scrollSpeed ); - - window.location.hash = event.target.hash.slice( 1 ); - } - } - } ); - } ); - }, - - // Scroll to element - scrollToElement: function() { - var scrollToElement = document.querySelector( '*[data-scroll-to]' ); - - if ( scrollToElement ) { - scrollToElement.addEventListener( 'click', function( event ) { - var originalOffset, additionalOffset, scrollOffset, scrollSpeed, - // Figure out element to scroll to - target = event.target.dataset.twentytwentyScrollTo; - - // Make sure said element exists - if ( target ) { - event.preventDefault(); - - // Get options - additionalOffset = event.target.dataset.additionalOffset; - scrollSpeed = event.target.dataset.scrollSpeed ? event.target.dataset.scrollSpeed : 500; - - // Determine offset - originalOffset = target.getBoundingClientRect().top + window.pageYOffset; - scrollOffset = additionalOffset ? originalOffset + additionalOffset : originalOffset; - - twentytwentyScrollTo( scrollOffset, null, scrollSpeed ); - } - } ); - } - } - -}; // twentytwenty.smoothScroll - /* ----------------------------------------------------------------------------------------------- Modal Menu --------------------------------------------------------------------------------------------------- */ @@ -745,7 +653,6 @@ twentytwentyDomReady( function() { twentytwenty.toggles.init(); // Handle toggles twentytwenty.coverModals.init(); // Handle cover modals twentytwenty.intrinsicRatioVideos.init(); // Retain aspect ratio of videos on window resize - twentytwenty.smoothScroll.init(); // Smooth scroll to anchor link or a specific element twentytwenty.modalMenu.init(); // Modal Menu twentytwenty.primaryMenu.init(); // Primary Menu twentytwenty.touchEnabled.init(); // Add class to body if device is touch-enabled @@ -891,49 +798,3 @@ function twentytwentyFindParents( target, query ) { return parents; } - -// twentytwentyEaseInOutQuad functions http://goo.gl/5HLl8 -function twentytwentyEaseInOutQuad( t, b, c, d ) { - t /= d / 2; - if ( t < 1 ) { - return ( ( ( c / 2 ) * t ) * t ) + b; - } - t--; - return ( ( -c / 2 ) * ( ( t * ( t - 2 ) ) - 1 ) ) + b; -} - -function twentytwentyScrollTo( to, callback, duration ) { - var start, change, increment, currentTime; - - function move( amount ) { - document.documentElement.scrollTop = amount; - document.body.parentNode.scrollTop = amount; - document.body.scrollTop = amount; - } - - start = document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop; - change = to - start; - increment = 20; - currentTime = 0; - - duration = ( typeof ( duration ) === 'undefined' ) ? 500 : duration; - - function animateScroll() { - var val; - - // increment the time - currentTime += increment; - // find the value with the quadratic in-out twentytwentyEaseInOutQuad function - val = twentytwentyEaseInOutQuad( currentTime, start, change, duration ); - // move the document.body - move( val ); - // do the animation unless its over - if ( currentTime < duration ) { - window.requestAnimationFrame( animateScroll ); - } else if ( callback && typeof ( callback ) === 'function' ) { - // the animation is done so lets callback - callback(); - } - } - animateScroll(); -} diff --git a/wp-content/themes/twentytwenty/style-rtl.css b/wp-content/themes/twentytwenty/style-rtl.css index 269ddab62f..c1a80fd864 100644 --- a/wp-content/themes/twentytwenty/style-rtl.css +++ b/wp-content/themes/twentytwenty/style-rtl.css @@ -115,6 +115,13 @@ blockquote::after { html { font-size: 62.5%; /* 1rem = 10px */ + scroll-behavior: smooth; +} + +@media (prefers-reduced-motion: reduce) { + html { + scroll-behavior: auto; + } } body { diff --git a/wp-content/themes/twentytwenty/style.css b/wp-content/themes/twentytwenty/style.css index 4edd09fb12..93e35ae11c 100644 --- a/wp-content/themes/twentytwenty/style.css +++ b/wp-content/themes/twentytwenty/style.css @@ -115,6 +115,13 @@ blockquote::after { html { font-size: 62.5%; /* 1rem = 10px */ + scroll-behavior: smooth; +} + +@media (prefers-reduced-motion: reduce) { + html { + scroll-behavior: auto; + } } body { diff --git a/wp-includes/version.php b/wp-includes/version.php index 5a9e359039..362523d3db 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -13,7 +13,7 @@ * * @global string $wp_version */ -$wp_version = '5.3.1-alpha-46818'; +$wp_version = '5.3.1-alpha-46825'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.