I have a series of links which are using an anchor mechanism:
You can find the answer to your question on the following page:
https://stackoverflow.com/a/17633941/2359161
Here is the JSFiddle that was given:
http://jsfiddle.net/YYPKM/3/
Note the scrolling section at the end of the CSS, specifically:
/*
*Styling
*/
html,body {
width: 100%;
height: 100%;
position: relative;
}
body {
overflow: hidden;
}
header {
background: #fff;
position: fixed;
left: 0; top: 0;
width:100%;
height: 3.5rem;
z-index: 10;
}
nav {
width: 100%;
padding-top: 0.5rem;
}
nav ul {
list-style: none;
width: inherit;
margin: 0;
}
ul li:nth-child( 3n + 1), #main .panel:nth-child( 3n + 1) {
background: rgb( 0, 180, 255 );
}
ul li:nth-child( 3n + 2), #main .panel:nth-child( 3n + 2) {
background: rgb( 255, 65, 180 );
}
ul li:nth-child( 3n + 3), #main .panel:nth-child( 3n + 3) {
background: rgb( 0, 255, 180 );
}
ul li {
display: inline-block;
margin: 0 8px;
margin: 0 0.5rem;
padding: 5px 8px;
padding: 0.3rem 0.5rem;
border-radius: 2px;
line-height: 1.5;
}
ul li a {
color: #fff;
text-decoration: none;
}
.panel {
width: 100%;
height: 500px;
z-index:0;
-webkit-transform: translateZ( 0 );
transform: translateZ( 0 );
-webkit-transition: -webkit-transform 0.6s ease-in-out;
transition: transform 0.6s ease-in-out;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.panel h1 {
font-family: sans-serif;
font-size: 64px;
font-size: 4rem;
color: #fff;
position:relative;
line-height: 200px;
top: 33%;
text-align: center;
margin: 0;
}
/*
*Scrolling
*/
a[ id= "servicios" ]:target ~ #main article.panel {
-webkit-transform: translateY( 0px);
transform: translateY( 0px );
}
a[ id= "galeria" ]:target ~ #main article.panel {
-webkit-transform: translateY( -500px );
transform: translateY( -500px );
}
a[ id= "contacto" ]:target ~ #main article.panel {
-webkit-transform: translateY( -1000px );
transform: translateY( -1000px );
}
<a id="servicios"></a>
<a id="galeria"></a>
<a id="contacto"></a>
<header class="nav">
<nav>
<ul>
<li><a href="#servicios"> Servicios </a> </li>
<li><a href="#galeria"> Galeria </a> </li>
<li><a href="#contacto">Contacta nos </a> </li>
</ul>
</nav>
</header>
<section id="main">
<article class="panel" id="servicios">
<h1> Nuestros Servicios</h1>
</article>
<article class="panel" id="galeria">
<h1> Mustra de nuestro trabajos</h1>
</article>
<article class="panel" id="contacto">
<h1> Pongamonos en contacto</h1>
</article>
</section>
I guess it might be possible to set some kind of hardcore transition to the top
style of a #container
div
to move your entire page in the desired direction when clicking your anchor. Something like adding a class that has top:-2000px
.
I did use JQuery because I'm to lazy too use native JS, but it is not necessary for what I did.
This is probably not the best possible solution because the top content just moves towards the top and you can't get it back easily, you should definitely use JQuery if you really need that scroll animation.
DEMO
I tried user18490 solution but there were some problems like:
Well after I edited and researched, I was able to come up with a solution. Hopefully it'll work for everyone
Just change the script tag to:
var html = document.documentElement
var body = document.body
var documentHeight = Math.max(body.scrollHeight, body.offsetHeight, html.scrollHeight, html.clientHeight, html.offsetHeight)
var PageHeight = Math.max(html.clientHeight || 0, window.innerHeight || 0)
function scrollDownTo(to, duration) {
if (document.body.scrollTop == to) return;
if ((documentHeight-to) < PageHeight) {
to = documentHeight - PageHeight;
}
var diff = to - window.pageYOffset;
var scrollStep = Math.PI / (duration / 10);
var count = 0, currPos; ajaxe = 1
var start = window.pageYOffset;
var scrollInterval = setInterval(function(){
if (window.pageYOffset != to) {
count = count + 1;
if (ajaxe > count) {
clearInterval(scrollInterval)
}
currPos = start + diff * (0.5 - 0.5 * Math.cos(count * scrollStep));
scroll( 0, currPos)
ajaxe = count
}
else { clearInterval(scrollInterval);}
},20);
}
function test (elID) {
var dest = document.getElementById(elID);
scrollDownTo((dest.getBoundingClientRect().top + window.pageYOffset), 500);
}
The HTML is still the same:
<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>
If you still encounter any issues kindly comment
If anybody is just like me willing to use jQuery, but still found himself looking to this question then this may help you guys:
https://html-online.com/articles/animated-scroll-anchorid-function-jquery/
$(document).ready(function () {
$("a.scrollLink").click(function (event) {
event.preventDefault();
$("html, body").animate({ scrollTop: $($(this).attr("href")).offset().top }, 500);
});
});
<a href="#anchor1" class="scrollLink">Scroll to anchor 1</a>
<a href="#anchor2" class="scrollLink">Scroll to anchor 2</a>
<p id="anchor1"><strong>Anchor 1</strong> - Lorem ipsum dolor sit amet, nonumes voluptatum mel ea.</p>
<p id="anchor2"><strong>Anchor 2</strong> - Ex ignota epicurei quo, his ex doctus delenit fabellas.</p>
Here is a pure css solution using viewport units and variables that automatically scales to the device (and works on window resize). I added the following to Alex's solution:
html,body {
width: 100%;
height: 100%;
position: fixed;/* prevents scrolling */
--innerheight: 100vh;/* variable 100% of viewport height */
}
body {
overflow: hidden; /* prevents scrolling */
}
.panel {
width: 100%;
height: var(--innerheight); /* viewport height */
a[ id= "galeria" ]:target ~ #main article.panel {
-webkit-transform: translateY( calc(-1*var(--innerheight)) );
transform: translateY( calc(-1*var(--innerheight)) );
}
a[ id= "contacto" ]:target ~ #main article.panel {
-webkit-transform: translateY( calc(-2*var(--innerheight)) );
transform: translateY( calc(-2*var(--innerheight)) );
I implemented the answer suggested by @user18490 but ran into two problems:
I developed the following class to get around the mentioned problems, and it works fine:
export class SScroll{
constructor(){
this.delay=501 //ms
this.duration=500 //ms
this.lastClick=0
}
lastClick
delay
duration
scrollTo=(destID)=>{
/* To prevent "bounce" */
/* https://stackoverflow.com/a/28610565/3405291 */
if(this.lastClick>=(Date.now()-this.delay)){return}
this.lastClick=Date.now()
const dest=document.getElementById(destID)
const to=dest.offsetTop
if(document.body.scrollTop==to){return}
const diff=to-document.body.scrollTop
const scrollStep=Math.PI / (this.duration/10)
let count=0
let currPos
const start=window.pageYOffset
const scrollInterval=setInterval(()=>{
if(document.body.scrollTop!=to){
count++
currPos=start+diff*(.5-.5*Math.cos(count*scrollStep))
document.body.scrollTop=currPos
}else{clearInterval(scrollInterval)}
},10)
}
}
There is a problem with Firefox as mentioned here. Therefore, to make it work on Firefox, I implemented the following code. It works fine on Chromium-based browsers and also Firefox.
export class SScroll{
constructor(){
this.delay=501 //ms
this.duration=500 //ms
this.lastClick=0
}
lastClick
delay
duration
scrollTo=(destID)=>{
/* To prevent "bounce" */
/* https://stackoverflow.com/a/28610565/3405291 */
if(this.lastClick>=(Date.now()-this.delay)){return}
this.lastClick=Date.now()
const dest=document.getElementById(destID)
const to=dest.offsetTop
if((document.body.scrollTop || document.documentElement.scrollTop || 0)==to){return}
const diff=to-(document.body.scrollTop || document.documentElement.scrollTop || 0)
const scrollStep=Math.PI / (this.duration/10)
let count=0
let currPos
const start=window.pageYOffset
const scrollInterval=setInterval(()=>{
if((document.body.scrollTop || document.documentElement.scrollTop || 0)!=to){
count++
currPos=start+diff*(.5-.5*Math.cos(count*scrollStep))
/* https://stackoverflow.com/q/28633221/3405291 */
/* To support both Chromium-based and Firefox */
document.body.scrollTop=currPos
document.documentElement.scrollTop=currPos
}else{clearInterval(scrollInterval)}
},10)
}
}