user3376899 user3376899 - 4 months ago 19
CSS Question

How can I make the navbar scroll and fix to the top of the page when it is expanded?

When my navbar is collapsed, scrolling is normal and the navbar becomes fixed to the top of the page when scrolling past the header/ jumbotron. However, when the navbar is expanded (revealing 'one', 'two', and 'three'), the page will jump skipping some of the content and covering it up by the navbar. How can I make the page scroll/ behave "normally" and allow the expanded navbar fix to the top of the page without jumping over content below?

<!DOCTYPE html>
<html>

<head>
<title>Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Cabin" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Lobster" rel="stylesheet">
<script type="text/javascript">
</script>
<style>
.affix {
top: 0;
width: 100%;
}
.affix + .container-fluid {
padding-top: 70px;
}
nav {
z-index: 9;
}
.emoji p:hover {
text-decoration: none;
}
</style>
</head>

<body>
<div class="container-fluid" style="background-color:#f64e09; color:#fff; height:200px;">
<div class="container text-center" style="color: white;">
<div>
<h1 style="font-family: 'Lobster', cursive;">Website</h1> </div>
<h1 style="font-size: 30px; font-family: 'Cabin', sans-serif;">

</h1> </div>
</div>
<nav class="navbar navbar-inverse" data-spy="affix" data-offset-top="197">
<div class="container-fluid">
<div class="navbar-static-top">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a id="navId" class="navbar-brand" style="color:white;" href="#">Navbar Title</a> </div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav">
<li><a href="#">One</a> </li>
<li class="active"><a href="#">Two</a> </li>
<li><a href="#">Three</a> </li>
</ul>
</div>
</div>
</nav>
<!-- Start containter for everything south of navbar -->
<div class="container-fluid">
<div class="container" style="padding-top: 20px;">
<h1>Content so the page scrolls</h1>
<h1>Content so the page scrolls</h1>
<h1>Content so the page scrolls</h1>
<h1>Content so the page scrolls</h1>
<h1>Content so the page scrolls</h1>
<h1>Content so the page scrolls</h1>
<h1>Content so the page scrolls</h1>
<h1>Content so the page scrolls</h1>
<h1>Content so the page scrolls</h1> </div>
</div>
<div class="panel panel-default" style="font-family: 'Cabin', sans- serif;">
<div class="panel-footer">
<center>
<p>This is the footer</p>
</center>
</div>
</div>
</body>

</html>

Answer

As you probably know, the reason why your content is not "jumping" while navbar is collapsed is in this style:

.affix + .container-fluid {
    padding-top: 70px;
}

But when you are extending navbar, padding remains the same, but navbar itself becames taller. So, we have to somehow distingush those situations.

We can add some javascript to add an extra class to the <nav> element:

<script type="text/javascript">
    $(document).ready(function() {
        var navBar = $('#myNavbar');
        $('.navbar-toggle').click(function(e) {
            if (!navBar.is(':visible')) {
                // #myNavbar is about to be shown, add extra class to parent <nav>
                navBar.parents('nav').addClass('affix-visible-navbar');
            } else {
                // #myNavbar is about to be hidden, remove extra class from parent <nav>
                navBar.parents('nav').removeClass('affix-visible-navbar');
            }
        });
    });
</script>

and define new css-class:

.affix.affix-visible-navbar + .container-fluid  {
    padding-top: 155px !important;
}

So the complete working solution will look like this:

<!DOCTYPE html>
<html>

<head>
    <title>Example</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
    <link href="https://fonts.googleapis.com/css?family=Cabin" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css?family=Lobster" rel="stylesheet">
    <script type="text/javascript">
    </script>
    <style>
        .affix {
            top: 0;
            width: 100%;
        }
        .affix + .container-fluid {
            padding-top: 70px;
        }
        .affix.affix-visible-navbar + .container-fluid  {
            padding-top: 155px !important;
        }
        nav {
            z-index: 9;
        }
        .emoji p:hover {
            text-decoration: none;
        }
    </style>
    <script type="text/javascript">
        $(document).ready(function() {
            var navBar = $('#myNavbar');
            $('.navbar-toggle').click(function(e) {
                if (!navBar.is(':visible')) {
                    // #myNavbar is about to be shown, add extra class to parent <nav>
                    navBar.parents('nav').addClass('affix-visible-navbar');
                } else {
                    // #myNavbar is about to be hidden, remove extra class from parent <nav>
                    navBar.parents('nav').removeClass('affix-visible-navbar');
                }
            });
        });
    </script>
</head>

<body>
    <div class="container-fluid" style="background-color:#f64e09; color:#fff; height:200px;">
        <div class="container text-center" style="color: white;">
            <div>
                <h1 style="font-family: 'Lobster', cursive;">Website</h1> </div>
            <h1 style="font-size: 30px; font-family: 'Cabin', sans-serif;">

    </h1> </div>
    </div>
    <nav class="navbar navbar-inverse" data-spy="affix" data-offset-top="197">
        <div class="container-fluid">
            <div class="navbar-static-top">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a id="navId" class="navbar-brand" style="color:white;" href="#">Navbar Title</a> </div>
            <div class="collapse navbar-collapse" id="myNavbar">
                <ul class="nav navbar-nav">
                    <li><a href="#">One</a> </li>
                    <li class="active"><a href="#">Two</a> </li>
                    <li><a href="#">Three</a> </li>
                </ul>
            </div>
        </div>
    </nav>
    <!-- Start containter for everything south of navbar -->
    <div class="container-fluid">
        <div class="container" style="padding-top: 20px;">
            <h1>Content so the page scrolls</h1>
            <h1>Content so the page scrolls</h1>
            <h1>Content so the page scrolls</h1>
            <h1>Content so the page scrolls</h1>
            <h1>Content so the page scrolls</h1>
            <h1>Content so the page scrolls</h1>
            <h1>Content so the page scrolls</h1>
            <h1>Content so the page scrolls</h1>
            <h1>Content so the page scrolls</h1> </div>
    </div>
    <div class="panel panel-default" style="font-family: 'Cabin', sans-    serif;">
        <div class="panel-footer">
            <center>
                <p>This is the footer</p>
            </center>
        </div>
    </div>
</body>

</html>

Of course, if you are changing #myNavbar elements (e.g. add/remove items), you have to adjust padding in the .affix.affix-visible-navbar + .container-fluid {}