7

If I have the following, the link text wraps to the next line beautifuly:

<div class="sidenav" id="site-navbar">
<ul class="nav nav-pills nav-stacked" >
      <li><a href="#h0">A very very very very very very very very very long thing</a></li>

However, if I add affix, the text stays on the same line and overlaps onto the main content column:

<div class="sidenav" id="site-navbar">
<ul class="nav nav-pills nav-stacked" data-spy="affix">
      <li><a href="#h0">A very very very very very very very very very long thing</a></li>

Is there a way to fix this with css? Also, can I do it without editing the current CSS.

Here is a fiddle to demonstrate the overflow: https://jsfiddle.net/75nLbwyb/

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<title>Example of navbar overflow</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">

<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>



<body data-spy="scroll" data-target="#navbar-example">
  <div class="row">
    <div class="container">
      <div class="col-sm-3">
        <div class="sidenav" id="navbar-example" data-spy="affix">
          <ul class="nav nav-pills nav-stacked" data-offset-top="1">
            <li><a href="#headline0">Section 1</a></li>
            <li><a href="#headline1">Section 2 - a very very long thing</a></li>
            <li><a href="#headline2">Section 3</a></li>
          </ul>
        </div>
      </div>
      <div class="col-sm-9">
        <div id="headline0">
          <h1>Section 1</h1>
        </div>
        <p>
          blah </p>
        <div id="headline1">
          <h2>Section 2</h2>
        </div>
        <p> blah blah blah blah </p>
        <p> blah blah blah blah </p>
        <p> blah blah blah blah </p>
        <p> blah blah blah blah </p>
        <p> blah blah blah blah </p>
        <p> blah blah blah blah </p>
        <p> blah blah blah blah </p>
        <p> blah blah blah blah </p>
        <p> blah blah blah blah </p>
        <p> blah blah blah blah </p>
        <p> blah blah blah blah </p>
        <p> blah blah blah blah </p>
        <p> blah blah blah blah </p>
        <p> blah blah blah blah </p>
        <p> blah blah blah blah </p>
        <div id="headline2">
          <h2>Section 3</h2>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
        </div>
        <p>
          fddf
      </div>
    </div>
  </div>
</body>
Farhad
  • 4,119
  • 8
  • 43
  • 66
Robben_Ford_Fan_boy
  • 8,494
  • 11
  • 64
  • 85
  • it's not from my side. But one question. The issue appear only at scroll start right? – Sagar V Aug 14 '17 at 09:56
  • @ErrorinException Take a look at the updated fiddle - https://jsfiddle.net/75nLbwyb/ it should be present without scroll now – Robben_Ford_Fan_boy Aug 14 '17 at 09:58
  • in the fiddle, even if I removed the data-spy, it's still not breaking – Sagar V Aug 14 '17 at 10:00
  • 1
    ```.affix``` is made fixed on scroll, causing its width to be defined by inner content, and not by outer ```.col-sm-3``` container column (which has a ```width: 25%``` set on it). To fix this you need to specify ```max-width``` for ```.nav.affix```, like nstungcom mentioned. But the additional problem is that ```.col-sm-3``` is fluid, and layout is responsive. So you can not just set a fixed ```max-width``` in CSS, you will need to use JS to update ```max-width``` according to the current ```.col-sm-3``` width. – Andrey Aug 14 '17 at 10:20
  • And you will need to adapt the whole thing accordingly when responsive layout is changed (i.e. on narrow screens) – Andrey Aug 14 '17 at 10:20

5 Answers5

5

Main problem you face is that your .nav container (which own the .affix class) gets position:fixed as soon you scroll. Fixed elements orientate themselves to the browser viewport, this is the reason why its ignoring the width of the parent .col-sm-3 container from bootstrap (the 25% of the container width) and overlapping the text to the right.

Your only solution is to add a width value to the .affix class therefor your nav container wont break layout. HTML markup is fine so far! Maybe you need to make some adjustments for mobile styling (keep that in mind):

.nav.affix {  
  width: 150px;
  background: #fff; 
  z-index: 1;
  /* background and zindex for mobile styles, currently layout breaks  */
}

Check the sidebar of the bootstrap documentation. They adding a width to the affix class element too! — https://getbootstrap.com/docs/3.3/css/#code

Gerrit Halfmann
  • 1,332
  • 8
  • 17
1

Try use flexbox

.container-new {
 display: flex;
}
    <title>Example of navbar overflow</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>


  <body data-spy="scroll" data-target="#navbar-example">
    <div class="row">
      <div class="container container-new">
        <div class="col">
          <div class="sidenav" id="navbar-example">
            <ul class="nav nav-pills nav-stacked" data-spy="affix"  data-offset-top="1">
              <li><a href="#headline0">Section 1</a></li>
              <li><a href="#headline1">Section 2 - a very very long thing asd as das das das das d</a></li>
              <li><a href="#headline2">Section 3</a></li>
            </ul>
          </div>
        </div>
        <div class="col">
          <div id="headline0">
            <h1>Section 1</h1></div>
          <p>
            blah </p>
          <div id="headline1">
            <h2>Section 2</h2></div>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <p> blah blah blah blah </p>
          <div id="headline2">
            <h2>Section 3</h2>
            <p> blah blah blah blah </p>
            <p> blah blah blah blah </p>
            <p> blah blah blah blah </p>
            <p> blah blah blah blah </p>
            <p> blah blah blah blah </p>
            <p> blah blah blah blah </p>
            <p> blah blah blah blah </p>
            <p> blah blah blah blah </p>
            <p> blah blah blah blah </p>
            <p> blah blah blah blah </p>
            <p> blah blah blah blah </p>
            <p> blah blah blah blah </p>
            <p> blah blah blah blah </p>
            <p> blah blah blah blah </p>
            <p> blah blah blah blah </p>
          </div>
          <p>
            fddf
        </div>
      </div>
    </div>
  </body>

https://jsfiddle.net/75nLbwyb/4/

grinmax
  • 1,835
  • 1
  • 10
  • 13
0
 css:

  body {
  position: relative;
  }
  .affix {
  top: 20px;
   }
  div.col-sm-9 div {
  height: 250px;
  font-size: 28px;
   }

 @media screen and (max-width: 810px) {
 #section1, #section2, #section3, #section41, #section42  {
    margin-left: 150px;
    }
  }


 <body data-spy="scroll" data-target="#myScrollspy" data-offset="15">


<div class="container">
  <div class="row">
    <nav class="col-sm-3" >
      <ul class="nav nav-pills nav-stacked" data-spy="affix" data-offset-top="205">
        <li><a href="#section1">Section 1</a></li>
        <li><a href="#section2">Section 2</a></li>
        <li><a href="#section3">Section 3</a></li>
        <li class="dropdown">
          <a class="dropdown-toggle" data-toggle="dropdown" href="#">Section 4 <span class="caret"></span></a>
          <ul class="dropdown-menu">
        <li><a href="#section41">Section 4-1</a></li>
        <li><a href="#section42">Section 4-2</a></li>
      </ul>
    </li>
  </ul>
</nav>
<div class="col-sm-9">
  <div id="section1">    
    <h1>Section 1</h1>
    <p>Try to scroll this section and look at the navigation list while scrolling!</p>
  </div>
  <div id="section2"> 
    <h1>Section 2</h1>
    <p>Try to scroll this section and look at the navigation list while scrolling!</p>
  </div>        
  <div id="section3">
    <h1>Section 3</h1>
    <p>Try to scroll this section and look at the navigation list while scrolling!</p>
  </div>
  <div id="section41">
    <h1>Section 4-1</h1>
    <p>Try to scroll this section and look at the navigation list while scrolling!</p>
  </div>      
  <div id="section42">
    <h1>Section 4-2</h1>
    <p>Try to scroll this section and look at the navigation list while scrolling!</p>
  </div>
    </div>
  </div>
    </div>

Try this

Sagar Betkar
  • 26
  • 1
  • 5
0

A fixed element can still inherit its width from its parent, width: inherit seems to do the trick, no need to dynamically calculate it:

.sidenav.affix {
  width: inherit;
}

.sidenav.affix .nav-pills {
  width: calc(80% - 30px);
}

Updated fiddle here.

I had to move data-spy="affix" from ul to .sidenav. Sorry for not being able to test it cross browser from where I am. Let me know if it works.

Kostas Siabanis
  • 2,989
  • 2
  • 20
  • 22
  • It can not properly inherit widths in percentages. – Andrey Aug 17 '17 at 20:00
  • What do you mean by _properly_? – Kostas Siabanis Aug 17 '17 at 20:09
  • This: http://i.imgur.com/HBFcPYP.png (parent ```.col-sm-3``` has different width which should be inherited, but it is not). – Andrey Aug 17 '17 at 20:54
  • Well this is what meant by _adjust this to your needs_. It definitely needs some tuning, but the idea of inheriting width from `.col-sm-3` is much cleaner and dynamic – Kostas Siabanis Aug 17 '17 at 21:11
  • If you adjust it to a new value every 50-100px of screen width with media queries then probably it will be tolerable to some degree, depending on requirements. In some cases you may need to adjust it with 1-2 pixel increments. This is manual width recalculation, in worst scenario — for every pixel of screen width. How is that clean? And you do not know yet how other browsers treat it, you may end up using browser sniffing/hacks to manually recalculate it cross-browser. It is not viable and bulletproof solution, but a momentary cosmetic hack. – Andrey Aug 17 '17 at 21:36
  • Thank you for your constructive feedback. I have updated my answer, where as you see not a single media query is necessary. Let me know what you think. – Kostas Siabanis Aug 17 '17 at 22:07
  • If a proper width is not inherited, then css can't do much about it. Only if you write a ton of css for all screen widths with 1-pixel increments it may be sufficient, but I would not even try. For a smooth transition to fixed state on scroll, you need to have the exact same widths for ```.sidenav``` contents between normal state and ```position: fixed``` state, for every possible screen width, think about it – Andrey Aug 18 '17 at 08:31
-1

I had the same problem and got it fixed by setting a max-width to the affix element.

In your case:

.nav.affix {
  max-width: 145px;
}

https://jsfiddle.net/75nLbwyb/2/

nstungcom
  • 347
  • 2
  • 13