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
Apply Different CSS Stylesheet for Different Parts of the Same Web Page
Print Background Colours in Chrome
Bootstrap 4 Navbar and Content Fill Height Flexbox
Are CSS Selectors Case-Sensitive
How to Change the Font-Size of a Select Option
Styling Elements with a Dot (.) in the Class Name
Differencebetween Block and Inline-Block with Width: 100%
How to Apply Styles to Multiple Classes at Once
Why Put in Front of the File Name "_" or "_" in SCSS/Css
How to Select the Last N Items with Nth-Child
What's the Difference Between CSS3's :Root Pseudo Class and HTML
Styling Password Fields in CSS
Bootstrap 3: Pull-Right for Col-Lg Only
CSS Opacity and Child Elements
How to Implement Wordwrap on Jqgrid Which Works on IE7, IE8 and Ff
Next.Js Global CSS Cannot Be Imported from Files Other Than Your Custom <App>