Is There a Safari Equivalent for Scroll-Behavior: Smooth;

Is there a Safari equivalent for scroll-behavior: smooth;?

Safari 15.4 adds support for CSS scroll-behavior as detailed in the 15.4 release notes.

Added support for the CSS scroll-behavior property and ScrollOptions, allowing smooth scrolling to anchors or via JavaScript.

JavaScript - window.scroll({ behavior: 'smooth' }) not working in Safari

Behavior options aren't fully supported in IE/Edge/Safari, so you'd have to implement something on your own. I believe jQuery has something already, but if you're not using jQuery, here's a pure JavaScript implementation:

function SmoothVerticalScrolling(e, time, where) {
var eTop = e.getBoundingClientRect().top;
var eAmt = eTop / 100;
var curTime = 0;
while (curTime <= time) {
window.setTimeout(SVS_B, curTime, eAmt, where);
curTime += time / 100;
}
}

function SVS_B(eAmt, where) {
if(where == "center" || where == "")
window.scrollBy(0, eAmt / 2);
if (where == "top")
window.scrollBy(0, eAmt);
}

And if you need horizontal scrolling:

function SmoothHorizontalScrolling(e, time, amount, start) {
var eAmt = amount / 100;
var curTime = 0;
var scrollCounter = 0;
while (curTime <= time) {
window.setTimeout(SHS_B, curTime, e, scrollCounter, eAmt, start);
curTime += time / 100;
scrollCounter++;
}
}

function SHS_B(e, sc, eAmt, start) {
e.scrollLeft = (eAmt * sc) + start;
}

And an example call is:

SmoothVerticalScrolling(myelement, 275, "center");

How to do a smooth scrollTo (or equivalent) on Safari?

If you want to do a smooth (or animated) scroll to a position on your page using the JavaScript functions scroll, scrollTo, or scrollBy in all browsers (including IE 9 and up and Safari) and you’re not loading jQuery, then the iamdustan smoothscroll polyfill might be the easiest way to add the functionality.

You can either include the polyfill in the page’s head section and server it to every user (it’s only around 1,400 bytes when gzipped) or you can do a test and if the polyfill is needed, add it to the page.

The smoothscroll polyfill is available from the jsdelivr.net CDN.

For IE9, a polyfill for requestAnimationFrame for handling the animation is also required. Since IE9 users are becoming rare, it’s probably easier to use an IE conditional to load a the polyfill from your own server.

I included some code to use auto instead of smooth for the scrolling if the user has their system setup for prefers-reduced-motion: reduce.’ I do ignore prefers-reduced-motion` on Internet Explorer as IE11 was reporting it was off when it was on (but IE9, using a polyfill for window.matchMedia, was reporting it correctly). My assumption is that anybody who needs accessibility settings will be using one of the newer browsers.

var reducedMotionQuery = false;
var scrollBehavior = "smooth";
var one = document.querySelector("#one").offsetTop;
var two = document.querySelector("#two").offsetTop;
var three = document.querySelector("#three").offsetTop;

// If IE, just scroll - my assumption is an IE user won't be using reduced-motion
if (!(document.documentMode)) {
if (typeof window.matchMedia === "function") {
reducedMotionQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
}

// Check if the media query matches or is not available.
if (!reducedMotionQuery || reducedMotionQuery.matches) {
scrollBehavior = "auto";
}
}

function toOne() {
window.scroll({
top: one,
left: 0,
behavior: scrollBehavior
});
}
function toTwo() {
window.scrollTo({
top: two,
left: 0,
behavior: scrollBehavior
});
}
function toThree() {;
window.scrollTo({
top: three,
left: 0,
behavior: scrollBehavior
});
}
function upDown(distance) {
window.scrollBy({
top: distance,
left: 0,
behavior: scrollBehavior
});
}
.block {
height: 100vh;
}
<!-- requestAnimationFrame polyfill -->
<!--[if IE 9]>
<script src="https://cdn.jsdelivr.net/npm/raf-polyfill@1.0.0/raf.min.js"></script>
<![endif]-->

<!-- scrollBehavior polyfill for IE and Safari-->
<script>
if (!('scrollBehavior' in document.documentElement.style)) {
var js = document.createElement('script');
js.src = "https://cdn.jsdelivr.net/npm/smoothscroll-polyfill@0.4.4/dist/smoothscroll.min.js";
document.head.appendChild(js);
}
</script>

<div id="one" class="block">
<h1>one</h1>
<button type="button" onclick="toOne()">To One</button>
<button type="button" onclick="toTwo()">To Two</button>
<button type="button" onclick="toThree()">To Three</button>
<button type="button" onclick="upDown(500)">Down</button>
</div>
<div id="two" class="block">
<h1>two</h1>
<button type="button" onclick="toOne()">To One</button>
<button type="button" onclick="toTwo()">To Two</button>
<button type="button" onclick="toThree()">To Three</button>
</div>
<div id="three" class="block">
<h1>three</h1>
<button type="button" onclick="toOne()">To One</button>
<button type="button" onclick="toTwo()">To Two</button>
<button type="button" onclick="toThree()">To Three</button>
<button type="button" onclick="upDown(-500)">Up</button>
</div>

Smooth scroll to top of page

Use the onclick-Event:

<header id="top">....</header>
<div style="background-color: red; height: 1200px"></div>
<footer>
<a style="cursor:pointer;" onclick="window.scrollTo({ top: 0, behavior: 'smooth' })"><img class="to-top" src="https://upload.wikimedia.org/wikipedia/commons/thumb/d/d6/Feather-arrows-arrow-up.svg/24px-Feather-arrows-arrow-up.svg.png"></a>
</footer>

How to enable smooth scrolling on mobile iOs?

Unfortunately Smooth Scrolling is not possible in Safari on OSX and iOS natively. But there are some JavaScript polyfills for that. For example: https://github.com/iamdustan/smoothscroll
You have to initialize it with JavaScript, not with CSS.

Why is scroll-behavior not working on my phone?

As you have noticed, Safari does not support the scroll-behavior CSS property (see this). You'd need some JavaScript to achieve the same effect across different browsers. You may find an example here.

Update:
This is a working code snippet of this answer (which combines the answers of George Daniel and terrymorse).

function scrollToSection(event) {
if (supportsSmoothScrolling()) {
return;
}
event.preventDefault();
const scrollToElem = document.getElementById("section");
SmoothVerticalScrolling(scrollToElem, 300, "top");
}

function supportsSmoothScrolling() {
const body = document.body;
const scrollSave = body.style.scrollBehavior;
body.style.scrollBehavior = 'smooth';
const hasSmooth = getComputedStyle(body).scrollBehavior === 'smooth';
body.style.scrollBehavior = scrollSave;
return hasSmooth;
};

function SmoothVerticalScrolling(element, time, position) {
var eTop = element.getBoundingClientRect().top;
var eAmt = eTop / 100;
var curTime = 0;
while (curTime <= time) {
window.setTimeout(SVS_B, curTime, eAmt, position);
curTime += time / 100;
}
}

function SVS_B(eAmt, position) {
if (position == "center" || position == "")
window.scrollBy(0, eAmt / 2);
if (position == "top")
window.scrollBy(0, eAmt);
}
body {
scroll-behavior: smooth;
height: 1000px;
}
section {
margin-top: 500px;
}
<a onclick="scrollToSection(event)" href="#section">
Redirect On section
</a>

<section id="section">
Section Content
</section>

Implement element.scrollIntoView with scrollTo

Based on this answer

const targetEl = document.getElementById('target');

window.scrollTo({
behavior: 'smooth',
top: targetEl.offsetTop + targetEl.clientHeight - window.innerHeight
})

window scroll smooth in safari (looking for solution without using jQuery)

Take a look at scroll, it has easing options.



Related Topics



Leave a reply



Submit