Scrolling to an Anchor using Transition/CSS3
While some of the answers were very useful and informative, I thought I would write down the answer I came up with. The answer from Alex was very good, it is however limited in the sense that the height of the div needs to be hard coded in the CSS.
So the solution I came up with uses JS (no jQuery) and is actually a stripped down version (almost to the minimum) of over solutions to solve similar problems I found on Statckoverflow:
HTML
<div class="header">
<p class="menu"><a href="#S1" onclick="test('S1'); return false;">S1</a></p>
<p class="menu"><a href="#S2" onclick="test('S2'); return false;">S2</a></p>
<p class="menu"><a href="#S3" onclick="test('S3'); return false;">S3</a></p>
<p class="menu"><a href="#S4" onclick="test('S4'); return false;">S3</a></p>
</div>
<div style="width: 100%;">
<div id="S1" class="curtain">
blabla
</div>
<div id="S2" class="curtain">
blabla
</div>
<div id="S3" class="curtain">
blabla
</div>
<div id="S4" class="curtain">
blabla
</div>
</div>
NOTE THE "RETURN FALSE;" in the on click call. This is important if you want to avoid having your browser jumping to the link itself (and let the effect being managed by your JS).
JS code:
<script>
function scrollTo(to, duration) {
if (document.body.scrollTop == to) return;
var diff = to - document.body.scrollTop;
var scrollStep = Math.PI / (duration / 10);
var count = 0, currPos;
start = element.scrollTop;
scrollInterval = setInterval(function(){
if (document.body.scrollTop != to) {
count = count + 1;
currPos = start + diff * (0.5 - 0.5 * Math.cos(count * scrollStep));
document.body.scrollTop = currPos;
}
else { clearInterval(scrollInterval); }
},10);
}
function test(elID)
{
var dest = document.getElementById(elID);
scrollTo(dest.offsetTop, 500);
}
</script>
It's incredibly simple. It finds the vertical position of the div in the document using its unique ID (in the function test). Then it calls the scrollTo function passing the starting position (document.body.scrollTop) and the destination position (dest.offsetTop). It performs the transition using some sort of ease-inout curve.
Thanks everyone for your help.
Knowing a bit of coding can help you avoiding (sometimes heavy) libraries, and giving you (the programmer) more control.
Transition to an anchor on a page
I have a codepen already made regarding this issue here.
The best JS function to do the "smooth scroll" is this:
$(function() {
$('a[href*="#"]:not([href="#"])').click(function() {
if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
if (target.length) {
$('html, body').animate({
scrollTop: target.offset().top
}, 1000);
return false;
}
}
});
});
CSS3 Transitions with Anchors
I don't think you can do it with just CSS. Here's a function to achieve it with jQuery:
$('a[href^=#]').on("click",function(e){
var t= $(this.hash);
var t=t.length&&t||$('[name='+this.hash.slice(1)+']');
if(t.length){
var tOffset=t.offset().top;
$('html,body').animate({scrollTop:tOffset-20},'slow');
e.preventDefault();
}
});
This will work with any <a href="#any-id-or-name">
anchor.
Demo.
To make it scroll faster or slower, change 'slow'
to 'fast'
or any numeric value in milliseconds.
Smooth scrolling when clicking an anchor link on react/next.js
There's this:
/**
* Smooth scrolling inside an element
*/
#my-element {
scroll-behavior: smooth;
}
/**
* Smooth scrolling on the whole document
*/
html {
scroll-behavior: smooth;
}
Source
But I feel like JS does a better job:
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
document.querySelector(this.getAttribute('href')).scrollIntoView({
behavior: 'smooth'
});
});
});
So you could give that a try: docs
Smooth scrolling when clicking an anchor link
No need any js just use scroll-behavior: smooth at html tag Thats it
html{
scroll-behavior: smooth;
}
How to scroll an HTML page to a given anchor
function scrollTo(hash) {
location.hash = "#" + hash;
}
No jQuery required at all!
animate scrolling with CSS3
css3 animations work with css properties only. this isn't possible within the confines of css.
Smooth scrolling with just pure css
You can do this with pure CSS but you will need to hard code the offset scroll amounts, which may not be ideal should you be changing page content- or should dimensions of your content change on say window resize.
You're likely best placed to use e.g. jQuery, specifically:
$('html, body').stop().animate({
scrollTop: element.offset().top
}, 1000);
A complete implementation may be:
$('#up, #down').on('click', function(e){
e.preventDefault();
var target= $(this).get(0).id == 'up' ? $('#down') : $('#up');
$('html, body').stop().animate({
scrollTop: target.offset().top
}, 1000);
});
Where element
is the target element to scroll to and 1000
is the delay in ms before completion.
Demo Fiddle
The benefit being, no matter what changes to your content dimensions, the function will not need to be altered.
Related Topics
Flex Elements Ignore Percent Padding in Firefox
How to Customize a Select Element Through CSS to Achieve This Dark Style
How to Define a Dynamic Mixin or Function Name in Sass
CSS Grid Row Height Safari Bug
What's The Point of Having Hidden Input in HTML? What Are Common Uses for This
Thymeleaf - How to Add Checked Attribute to Input Conditionally
HTML5 Flexible Box Model Height Calculation
How to Horizontal & Vertical Center a Div
HTML5 Input Box with Type="Number" Does Not Accept Comma in Chrome Browser
How to Set Character Encoding to Utf-8 for Default.HTML
Why Is There a Default Margin on The <Body> Element
Why Is Box-Sizing Acting Different on Table Vs Div
Bootstrap - Fill Fluid Container Between Header and Footer
Tools for Obfuscating HTML and CSS
Bootstrap Navbar Link Color Won't Change