jQuery scrollto breaks links (for most browsers) when using Foundation

So I’m building a site using Foundation 4. It’s a one page website, so I have a sidebar with anchor links to sections of the content.

The anchor links work just fine on their own, but whenever I try to animate the scroll the links just break and do nothing when you click them.

I’ve tried so many different methods, and all have the same outcome.

Not sure if it’s something that is conflicting with Foundation or if it’s something I’m not doing right.

The strange thing is, it works in Safari and a few mobile browsers but not for Chrome, IE, Firefox and Opera on desktop.

Anyway, heres the fiddle http://jsfiddle.net/nTSXY/2/ (If you remove the js on the fiddle the anchors will work normally again)

Any help is much appreciated :slight_smile:

Hi donmildreone. Welcome to the forums. :slight_smile:

Your script works fine for me in all browsers with a little tweak to the CSS:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style>
nav {width: 150px; position: fixed;}
.nav-bar {
    padding: 20px;
}

.main-content {
    padding: 20px;
    margin-left: 200px;
    padding-bottom: 1000px; /*for testing scroll*/
}

p {
    margin-bottom: 200px;
}

</style>
</head>
<body>

<div class="row">
    <div class="large-2 small-2 columns nav-bar">
        <nav>
            <ul>
                <li><a href="#first">First</a></li>
                <li><a href="#second">Second</a></li>
                <li><a href="#third">Third</a></li>
                <li><a href="#fourth">Fourth</a></li>
                <li><a href="#fifth">Fifth</a></li>
            </ul>
        </nav>
    </div>
    <div class="small-8 large-8 main-content">
        <div class="row" id="first">
            <h1>First</h1>
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sit amet libero a purus blandit condimentum.
            </p>
        </div>
        <div class="row" id="second">
            <h1>Second</h1>
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sit amet libero a purus blandit condimentum.
            </p>
        </div>
        <div class="row" id="third">
            <h1>Third</h1>
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sit amet libero a purus blandit condimentum.
            </p>
        </div>
        <div class="row" id="fourth">
            <h1>Fourth</h1>
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sit amet libero a purus blandit condimentum.
            </p>
        </div>
        <div class="row" id="fifth">
            <h1>Fifth</h1>
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sit amet libero a purus blandit condimentum.
            </p>
        </div>
    </div>
</div>

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(document).ready(function() {

    // Click event for any anchor tag that's href starts with #
    $('a[href^="#"]').click(function(event) {

        // The id of the section we want to go to.
        var id = $(this).attr("href");

        // An offset to push the content down from the top.
        var offset = 60;

        // Our scroll target : the top position of the
        // section that has the id referenced by our href.
        var target = $(id).offset().top - offset;

        // The magic...smooth scrollin' goodness.
        $('html, body').animate({scrollTop:target}, 500);

        //prevent the page from jumping down to our section.
        event.preventDefault();
    });
});

</script>	
</body>
</html>

The problem is that you are scrolling the body element and as the nav and the main-content are 100vh (100% of the viewport height) then the body has no scroll so nothing happens because there is nowhere for it to scroll. Safari and mobile are probably working because they don’t understand the vh unit I expect and as Ralphs code show you it will work if the elements are not contained within an overflow div.

You should instead be scrolling .main-content:


 $('[B].main-content[/B]').animate({scrollTop:target}, 500);

However that will only work once as I don’t think you will get the right scroll amount on subsequent clicks.

Maybe @Pullo ; could help with routine here.

Sure could, but unless I’m mistaken Ralph has beaten me to it :slight_smile:

Or did I miss something?

It depends on whether there is more to the page than we see in the fiddle. :slight_smile:

Yes Ralph’s code will work and may indeed be a good solution but changes the dynamics of the page. The nav and main-content are set to 100vh (= 100% of the viewport height) and become independent elements without the nav having to be fixed (and avoids the problem of fixed elements).

The issue with the existing code is that the you need to scroll inside .main-content and not the body but it only seems to work once when using .main-content as subsequent clicks are all out of kilter and don’t match the destination correctly.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<script src="http://ajax.microsoft.com/ajax/jQuery/jquery-1.9.1.min.js "></script>
<style>
html, body, ul {
	margin:0;
	padding:0;
}
* {
	-moz-box-sizing:border-box;
	box-sizing:border-box
}
ul { list-style:none }
.nav-bar {
	height: 100vh;
	padding: 20px;
	float:left;
	position:relative;
	z-index:99;
}
.main-content {
	height:100vh;
	overflow: scroll;
	padding: 20px;
	border:1px solid #000;
	position:relative
}
p { margin-bottom: 200px; }
#fifth p { margin-bottom:0 }
</style>
</head>

<body>
<div class="row">
		<div class="large-2 small-2 columns nav-bar">
				<nav>
						<ul>
								<li><a href="#first">First</a></li>
								<li><a href="#second">Second</a></li>
								<li><a href="#third">Third</a></li>
								<li><a href="#fourth">Fourth</a></li>
								<li><a href="#fifth">Fifth</a></li>
						</ul>
				</nav>
		</div>
		<div class="small-8 large-8 main-content">
				<div class="row" id="first">
						<h1>First</h1>
						<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sit amet libero a purus blandit condimentum. </p>
				</div>
				<div class="row" id="second">
						<h1>Second</h1>
						<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sit amet libero a purus blandit condimentum. </p>
				</div>
				<div class="row" id="third">
						<h1>Third</h1>
						<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sit amet libero a purus blandit condimentum. </p>
				</div>
				<div class="row" id="fourth">
						<h1>Fourth</h1>
						<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sit amet libero a purus blandit condimentum. </p>
				</div>
				<div class="row" id="fifth">
						<h1>Fifth</h1>
						<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sit amet libero a purus blandit condimentum. </p>
				</div>
		</div>
</div>
<script>
$(document).ready(function() {

    // Click event for any anchor tag that's href starts with #
    $('a[href^="#"]').click(function(event) {

        // The id of the section we want to go to.
        var id = $(this).attr("href");

        // An offset to push the content down from the top.
        var offset = 60;

        // Our scroll target : the top position of the
        // section that has the id referenced by our href.
        var target = $(id).offset().top - offset;

        // The magic...smooth scrollin' goodness.
        $('.main-content').animate({scrollTop:target}, 500);

        //prevent the page from jumping down to our section.
        event.preventDefault();
    });
});

</script>
</body>
</html>

However, It’s probably best to wait for the OP to answer as Ralph’s suggestion may do the job anyway and I will have wasted your time.:slight_smile:

No problem. I’m subscribed to the thread now, so I’ll see any response.

I hadn’t actually heard of these viewport units (vw, vh, vmin, vmax), so I learned something already (although it is sometimes depressing how rapidly the web is evolving …)