Flexbox设计中的粘性侧边栏

时间:2016-06-09 09:48:26

标签: css3 flexbox

如何使用flexbox制作的圣杯布局中的侧边栏变得粘稠?即。当最后一个元素到达时,html的旁边和导航部分应该停止向下滚动。我试过多种方法但收效甚微。

HTML:

<body>
     <header>header</header>
     <div id='main'>
        <article>This area has lot of content </article>`
        <nav> This nav should not scroll</nav>
        <aside>This aside too</div></aside>
     </div>
     <footer>footer</footer>
</body>

CSS:

body {
   /*font: 24px Helvetica;*/
   background: #999999;
  }

  #main {
   min-height: 800px;
   margin: 0px;
   padding: 0px;
   display: -webkit-flex;
   display:         flex;
   -webkit-flex-flow: row;
           flex-flow: row;
   }

  #main > article {
   margin: 4px;
   padding: 5px;
   border: 1px solid #cccc33;
   border-radius: 7pt;
   background: #dddd88;
   -webkit-flex: 3 1 60%;
           flex: 3 1 60%;
   -webkit-order: 2;
           order: 2;
   }

  #main > nav {
   margin: 4px;
   padding: 5px;
   border: 1px solid #8888bb;
   border-radius: 7pt;
   background: #ccccff;
   -webkit-flex: 1 6 20%;
           flex: 1 6 20%;
   -webkit-order: 1;
           order: 1;
   }

  #main > aside {
   margin: 4px;
   padding: 5px;
   border: 1px solid #8888bb;
   border-radius: 7pt;
   background: #ccccff;
   -webkit-flex: 1 6 20%;
           flex: 1 6 20%;
   -webkit-order: 3;
           order: 3;
   }

  header, footer {
   display: block;
   margin: 4px;
   padding: 5px;
   min-height: 100px;
   border: 1px solid #eebb55;
   border-radius: 7pt;
   background: #ffeebb;
   }

4 个答案:

答案 0 :(得分:1)

如何在position: stickynav元素上使用新的CSS3 aside呢?

这种方法的缺点是Internet Explorer不支持它,但它确实需要零Javascript。

我在这里做了这个改变:

&#13;
&#13;
body {
   /*font: 24px Helvetica;*/
   background: #999999;
  }

  #main {
		position: relative;
   min-height: 800px;
   margin: 0px;
   padding: 0px;
   display: -webkit-flex;
   display:         flex;
   -webkit-flex-flow: row;
           flex-flow: row;
   }

  #main > article {
   margin: 4px;
   padding: 5px;
   border: 1px solid #cccc33;
   border-radius: 7pt;
   background: #dddd88;
   -webkit-flex: 3 1 60%;
           flex: 3 1 60%;
   -webkit-order: 2;
           order: 2;
   }

  #main > nav {
	 
   margin: 4px;
   padding: 5px;
   border: 1px solid #8888bb;
   border-radius: 7pt;
   background: #ccccff;
   -webkit-flex: 1 6 20%;
           flex: 1 6 20%;
   -webkit-order: 1;
           order: 1;
   }

  #main > aside {
   margin: 4px;
   padding: 5px;
   border: 1px solid #8888bb;
   border-radius: 7pt;
   background: #ccccff;
   -webkit-flex: 1 6 20%;
           flex: 1 6 20%;
   -webkit-order: 3;
           order: 3;
   }

#main > nav, #main > aside {
	position: sticky;
	top: 0;
	height: 100%;
}

  header, footer {
   display: block;
   margin: 4px;
   padding: 5px;
   min-height: 100px;
   border: 1px solid #eebb55;
   border-radius: 7pt;
   background: #ffeebb;
   }
&#13;
<body>
     <header>header</header>
     <div id='main'>
        <article>This area has lot of content </article>`
        <nav> This nav should not scroll</nav>
        <aside>This aside too</div></aside>
     </div>
     <footer>footer</footer>
</body>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

假设我真的理解了你想要实现的目标,那么这应该与你所寻找的一致。解决方案的关键在于定义三个状态或三个条件来定位元素。按顺序出现:

  1. 如果我们滚动到侧边栏的开头但尚未到达侧边栏的末尾。减去菜单本身的高度。
  2. 如果我们滚动到侧边栏的末尾减去菜单的高度。
  3. 如果页面滚动值小于侧边栏的起始点。即,在我们滚动之前,菜单的自然状态。
  4. if(currentScrollPosition >= sidebarPosition && currentScrollPosition <= threshold)
    {
         $widget.css({top: 10, position:'fixed'});
    }
    else if(currentScrollPosition >= threshold)
    {
        $widget.css({top: threshold, position:'absolute'});
    }
    else if(currentScrollPosition <= sidebarPosition)
    {
        $widget.css({top: 'auto', position:'static'});
    }
    

    http://codepen.io/anon/pen/jByPEJ

答案 2 :(得分:0)

使用简单的步骤,使用javscript和css使侧边栏粘贴。

&#13;
&#13;
$(function(){

var stickySidebar = $('.sticky');

if (stickySidebar.length > 0) {	
  var stickyHeight = stickySidebar.height(),
      sidebarTop = stickySidebar.offset().top;
}

// on scroll move the sidebar
$(window).scroll(function () {
  if (stickySidebar.length > 0) {	
    var scrollTop = $(window).scrollTop();
            
    if (sidebarTop < scrollTop) {
      stickySidebar.css('top', scrollTop - sidebarTop);

      // stop the sticky sidebar at the footer to avoid overlapping
      var sidebarBottom = stickySidebar.offset().top + stickyHeight,
          stickyStop = $('.main-content').offset().top + $('.main-content').height();
      if (stickyStop < sidebarBottom) {
        var stopPosition = $('.main-content').height() - stickyHeight;
        stickySidebar.css('top', stopPosition);
      }
    }
    else {
      stickySidebar.css('top', '0');
    } 
  }
});

$(window).resize(function () {
  if (stickySidebar.length > 0) {	
    stickyHeight = stickySidebar.height();
  }
}); });
&#13;
body {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 14px;
  line-height: 25px;
  background-color: #361039;
  color: #E2E0DE;
  margin: 0;
}

header {
  display: block;
  background-color: #121325;
  font-size: 24px;
  height: 50px;
  padding: 2%;
  text-align: center;
}

section {
  float: left;
  width: 70%;
  padding: 1%;
  margin-right: 1%;
}

aside {
  float: left;
  width: 25%;
  padding: 1%;
  background-color: #5C255A;
}

.sticky {
  position: relative;
  top: 0;
}

footer {
  display: block;
  clear: both;
  background-color: #121325;
  font-size: 24px;
  height: 300px;
  padding: 2%;
  text-align: center;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>This is a header</header>

<section class="main-content">
  <article>
    <h1>This is Paragraph</h1>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis quis nibh gravida, gravida nisl ac, imperdiet sem. Fusce quis malesuada magna. Vivamus dignissim gravida tellus sed pulvinar. Morbi eleifend dolor vel velit viverra aliquam. In pharetra felis non leo congue, id iaculis dui laoreet. Pellentesque accumsan ligula sed nisl eleifend consequat. Proin at orci purus. Praesent dignissim at odio nec fringilla. Nulla lacinia ultricies auctor. Mauris vel diam nunc. Ut lorem arcu, interdum id tortor a, tincidunt vestibulum eros. Vivamus sit amet mattis turpis. Nullam auctor ut velit nec adipiscing. Morbi et vehicula diam.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis quis nibh gravida, gravida nisl ac, imperdiet sem. Fusce quis malesuada magna. Vivamus dignissim gravida tellus sed pulvinar. Morbi eleifend dolor vel velit viverra aliquam. In pharetra felis non leo congue, id iaculis dui laoreet. Pellentesque accumsan ligula sed nisl eleifend consequat. Proin at orci purus. Praesent dignissim at odio nec fringilla. Nulla lacinia ultricies auctor. Mauris vel diam nunc. Ut lorem arcu, interdum id tortor a, tincidunt vestibulum eros. Vivamus sit amet mattis turpis. Nullam auctor ut velit nec adipiscing. Morbi et vehicula diam.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis quis nibh gravida, gravida nisl ac, imperdiet sem. Fusce quis malesuada magna. Vivamus dignissim gravida tellus sed pulvinar. Morbi eleifend dolor vel velit viverra aliquam. In pharetra felis non leo congue, id iaculis dui laoreet. Pellentesque accumsan ligula sed nisl eleifend consequat. Proin at orci purus. Praesent dignissim at odio nec fringilla. Nulla lacinia ultricies auctor. Mauris vel diam nunc. Ut lorem arcu, interdum id tortor a, tincidunt vestibulum eros. Vivamus sit amet mattis turpis. Nullam auctor ut velit nec adipiscing. Morbi et vehicula diam.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis quis nibh gravida, gravida nisl ac, imperdiet sem. Fusce quis malesuada magna. Vivamus dignissim gravida tellus sed pulvinar. Morbi eleifend dolor vel velit viverra aliquam. In pharetra felis non leo congue, id iaculis dui laoreet. Pellentesque accumsan ligula sed nisl eleifend consequat. Proin at orci purus. Praesent dignissim at odio nec fringilla. Nulla lacinia ultricies auctor. Mauris vel diam nunc. Ut lorem arcu, interdum id tortor a, tincidunt vestibulum eros. Vivamus sit amet mattis turpis. Nullam auctor ut velit nec adipiscing. Morbi et vehicula diam.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis quis nibh gravida, gravida nisl ac, imperdiet sem. Fusce quis malesuada magna. Vivamus dignissim gravida tellus sed pulvinar. Morbi eleifend dolor vel velit viverra aliquam. In pharetra felis non leo congue, id iaculis dui laoreet. Pellentesque accumsan ligula sed nisl eleifend consequat. Proin at orci purus. Praesent dignissim at odio nec fringilla. Nulla lacinia ultricies auctor. Mauris vel diam nunc. Ut lorem arcu, interdum id tortor a, tincidunt vestibulum eros. Vivamus sit amet mattis turpis. Nullam auctor ut velit nec adipiscing. Morbi et vehicula diam.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis quis nibh gravida, gravida nisl ac, imperdiet sem. Fusce quis malesuada magna. Vivamus dignissim gravida tellus sed pulvinar. Morbi eleifend dolor vel velit viverra aliquam. In pharetra felis non leo congue, id iaculis dui laoreet. Pellentesque accumsan ligula sed nisl eleifend consequat. Proin at orci purus. Praesent dignissim at odio nec fringilla. Nulla lacinia ultricies auctor. Mauris vel diam nunc. Ut lorem arcu, interdum id tortor a, tincidunt vestibulum eros. Vivamus sit amet mattis turpis. Nullam auctor ut velit nec adipiscing. Morbi et vehicula diam.</p>
  </article>
</section>

<aside class="sticky">
  <h1>This is a sticky sidebar</h1>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
  <p>Duis quis nibh gravida, gravida nisl ac, imperdiet sem. Fusce quis malesuada magna.</p>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</aside>

<footer>This is a footer</footer>
&#13;
&#13;
&#13;

答案 3 :(得分:-1)

我已经从代码笔中取出代码并根据需要用侧边栏重写了 JS代码。希望它有用:)

var stickArea = $('aside ul');
var footArea = $('footer');
margin = 10;
offtop = stickArea.offset().top - margin;
offbtm = footArea.offset().top - (margin * 3 + stickArea.height());

$(window).scroll(function() {
  topScr = $(window).scrollTop();
  if (topScr > offtop && stickArea.hasClass('natural')) {
    stickArea.removeClass('natural').addClass('fixed').css('top', margin);
  }
  if (offtop > topScr && stickArea.hasClass('fixed')) {
    stickArea.removeClass('fixed').addClass('natural').css('top', 'auto');
  }
  if (topScr > offbtm && stickArea.hasClass('fixed')) {
    stickArea.removeClass('fixed').addClass('bottom').css('top', offbtm);
  }
  if (offbtm > topScr && stickArea.hasClass('bottom')) {
    stickArea.removeClass('bottom').addClass('fixed').css('top', margin);
  }
});
* {
  box-sizing: border-box;
}

body {
  min-height: 100vh;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -ms-flex-direction: column;
  flex-direction: column;
}

.master {
  -webkit-box-flex: 1;
  -ms-flex-positive: 1;
  flex-grow: 1;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: center;
  -ms-flex-pack: center;
  justify-content: center;
}

.master .inner-w {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -ms-flex-direction: column;
  flex-direction: column;
  -ms-flex-preferred-size: 960px;
  flex-basis: 960px;
}

.master main {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -ms-flex-direction: column;
  flex-direction: column;
  -webkit-box-flex: 1;
  -ms-flex-positive: 1;
  flex-grow: 1;
}

@media (min-width: 900px) {
  .master main {
    -webkit-box-orient: horizontal;
    -webkit-box-direction: normal;
    -ms-flex-direction: row;
    flex-direction: row;
    -webkit-box-pack: justify;
    -ms-flex-pack: justify;
    justify-content: space-between;
  }
}

.master .content {
  -ms-flex-preferred-size: 70%;
  flex-basis: 70%;
  min-height: 2000px;
}

.master aside {
  -ms-flex-preferred-size: 350px;
  flex-basis: 350px;
  -webkit-box-flex: 0;
  -ms-flex-positive: 0;
  flex-grow: 0;
  -ms-flex-negative: 0;
  flex-shrink: 0;
}

.master aside .widget-list {
  width: 330px;
}

body.sticky-sidebar .master aside .widget-list {
  position: fixed;
  top: 10px;
}

body {
  margin: 0;
  background: #add8e6;
  padding: 10px;
}

.master {
  background: #90ee90;
}

.master .inner-w {
  padding: 10px;
}

.master header,
.master .content,
.master aside,
.master footer {
  padding: 10px;
}

.master header {
  background: #ffc0cb;
  min-height: 120px;
}

.master .content {
  background: #f5deb3;
}

.master aside {
  background: #ffd700;
  min-height: 400px;
}

.master aside .widget-list {
  background: #d3d3d3;
  padding: 10px;
}

.master aside .widget-list .widget {
  background: rgba(0, 0, 0, 0.1);
  padding: 10px;
}

.master aside .widget-list .widget:not(:first-of-type) {
  margin-top: 10px;
}

.master footer {
  background: #808080;
  min-height: 500px;
}

ul {
  margin: 0;
  padding: 0;
  list-style: none;
}


/** additional Css For Sidebar Logic **/

.master aside .widget-list.fixed {
  position: fixed;
}

.master aside .widget-list.bottom {
  position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='master'>
  <div class='inner-w'>

    <header>
      <h1>Attempts at a sticky sidebar for squishy and more-complex flex-box layouts - sorta ~ eh?</h1>
    </header>

    <main>
      <div class='content'>
        content
      </div>

      <aside class="">
        <ul class='widget-list natural'>
          <li class='widget'>
            widget 1
          </li>
          <li class='widget'>
            widget 2
          </li>
          <li class='widget'>
            widget 3
          </li>


        </ul>
      </aside>
    </main>

    <footer>
      footer
    </footer>

  </div>
</div>