【问题标题】:Share 100vh between div and position:sticky navbar在 div 和 position:sticky navbar 之间共享 100vh
【发布时间】:2018-03-22 09:25:25
【问题描述】:

我想在幻灯片和导航栏之间共享页面的初始可见区域,如下图所示,然后当您向下滚动文档时,该区域将停留在顶部。这是我遇到问题的地方。

我已经尝试为我的幻灯片做类似height: 90vh 和我的导航栏的height: 10vh 但我希望网站是动态的并且能够适应大多数分辨率,直到你达到手机级别或至少像 200% 缩放在 Microsoft 边缘,其中将使用另一个样式表。

我也尝试将它们放在同一个 div 中,将 height: 90% 设置为幻灯片,height: auto 设置为导航栏。这在动态性方面效果最好,但position: sticky 显然不起作用,因为它只遍历父 div 的高度。

最好的方法是将幻灯片高度设置为height: 90vh,并允许导航栏相应地移动。它有点工作,但对我来说还不够好。

导航栏必须最初位于底部,然后粘在顶部。如果可能的话,我宁愿有一个纯粹的 CSS 解决方案,但我对 javascript 持开放态度。虽然我宁愿使用纯 javascript 而不是 jQuery,但如果解释得很好,我可以接受。

实际问题是:如何让导航栏和幻灯片动态共享初始可见高度?

以下是所有相关代码:

        #container {
        display: flex;
        flex-direction: column;
        height: 100vh;
    }
    .slideshow-base {
        flex-grow: 1;
        width: 100%;
        margin: 0px;
    }
    .slideshow-container {
        height: 100%;
        width: 100%;
        position: relative;
        overflow: hidden;
    }
    .Slides {
        position: absolute;
        transform: translateX(-100%);
        transition: transform 2s;
        display: inline-block;
        width: 100%;
        height: 100%;
        margin: 0;
    }
    .Slides-Images {
        width: 100%;
        height: 100%;
        object-fit: cover;
    }
    .navbar-base {
        font-weight: bold;
        z-index: 2;
        font-variant: small-caps;
        height: 100%;
        width: auto;
        top: 0px;
        background-color: rgba(50, 64, 147, 0.9);
        display: block;
        border-bottom: 1px solid rgb(226, 208, 0);
    }
        <div id="container"> 
        <!--Slideshow-->
        <div class="slideshow-base" style="background-color: rgb(50, 64, 147); height: 90vh">
          <div class="slideshow-container">
    
            <div class="Slides">
              <img src="~/Images/Slideshow/Gallery-1.jpg" class="Slides-Images">
            </div>
    
            <div class="Slides">
              <img src="~/Images/Slideshow/Gallery-2.jpg" class="Slides-Images">
            </div>
    
            <div class="Slides">
              <img src="~/Images/Slideshow/Gallery-3.jpg" class="Slides-Images">
            </div>
    
            <a class="prev" onclick="plusSlides(-1)">&#10094;</a>
            <a class="next" onclick="plusSlides(1)">&#10095;</a>
    
            <div class="dot-base">
              <span class="dot" onclick="currentSlide(1)">&#5867;</span>
              <span class="dot" onclick="currentSlide(2)">&#5867;</span>
              <span class="dot" onclick="currentSlide(3)">&#5867;</span>
            </div>
          </div>
        </div>
    
        <hr />
    
        <!--Sticky Navbar-->
        <div class="navbar-base" style="width: 100%; height: auto; position: sticky;">
          <ul>
            <li class="navbar-button" style="display: inline-block;"> @Html.ActionLink("main page", "MainPage", "Home") </li>
            <li class="navbar-button" style="display: inline-block;">
              @Html.ActionLink("about", "About", "About")
              <ul class="navbar-ddmenu">
                <li class="navbar-ddcontent" style="display: inline-block;">@Html.ActionLink("academy", "Academy", "About")</li>
                <li class="navbar-ddcontent" style="display: inline-block;">@Html.ActionLink("the club", "DKClub", "About")</li>
                <li class="navbar-ddcontent" style="display: inline-block;">@Html.ActionLink("taebo", "TaeBo", "About")</li>
                <li class="navbar-ddcontent" style="display: inline-block;">@Html.ActionLink("founders and staff", "Staff", "About")</li>
              </ul>
            </li>
            <li class="navbar-button" style="float:right"> @Html.ActionLink("contacts", "Contacts")</li>
            <li class="navbar-button" style="float:right"> @Html.ActionLink("gallery", "Gallery")</li>
            <li class="navbar-button" style="float:right"> @Html.ActionLink("shop dk", "Index", "Shop")</li>
          </ul>
        </div>
     </div>

【问题讨论】:

  • flex 是你的朋友
  • 你可以试试 CSS-Grid。
  • @gavgrif 你们会推荐哪一个?我只会将两者中的一个用于文档的第一部分,如果我确实返回它,我对它们的使用将非常少。你们也可以给我一个关于我将如何去做的事情吗?
  • @WaleedIqbal 见上面的评论 :)
  • 如果您的项目将来很可能扩展,那么 IMO,请使用 CSS-Grid。如果它可能保持原样,请使用 FlexBox。

标签: javascript html css


【解决方案1】:

使用 CSS 网格

body {
  margin: 0;
}

#container {
  width: 100vw;
  background: #ccc;
  padding: 10px;
  height: 100vh;
  display: grid;
  grid-template-rows: 90vh 10vh;
  grid-gap: 10px;
}

#container>div {
  background: #999;
}
<section id="container">
  <div>Sticky</div>
  <div>NavBar</div>
</section>

【讨论】:

  • 这个解决方案不会让position: sticky 变得多余吗?我希望我的导航栏在您向下滚动一点后粘在顶部。
  • 哦,好的。是的,那将是多余的。我最初认为你的问题是让导航栏粘在底部。如果我理解正确,您希望导航栏在页面加载时位于底部并在滚动后保持在顶部?
【解决方案2】:

好的,我会为您的初始视图使用 flexbox 方法,然后使用一些 js 在滚动上添加一个类:

window.onscroll = function() {
  var nav = document.getElementById('nav');
  var scrollTop = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;
  
  if (scrollTop > 100) {               // not sure how much you want it to scroll before it is made sticky
    nav.classList.add("fixed");
  } else {
    nav.classList.remove("fixed");
  }
}
body {
  margin:0;
  
  height:200vh; /* just so there is some scrolling */
}
.container {
  height:100vh;  
  display:flex;
  flex-direction:column;
}

.slideshow-base {
  flex-grow:1;    /* this will make shadow base take the rest of the available height to start with */
}

.fixed {
  position:fixed; 
  top:0;
  left:0;
  right:0;
}
<div class="container">
  <div class="slideshow-base" style="background-color: rgb(50, 64, 147); height: 90vh">
    <div class="slideshow-container">

      <div class="Slides">
        <img src="~/Images/Slideshow/Gallery-1.jpg" class="Slides-Images">
      </div>

      <div class="Slides">
        <img src="~/Images/Slideshow/Gallery-2.jpg" class="Slides-Images">
      </div>

      <div class="Slides">
        <img src="~/Images/Slideshow/Gallery-3.jpg" class="Slides-Images">
      </div>

      <a class="prev" onclick="plusSlides(-1)">&#10094;</a>
      <a class="next" onclick="plusSlides(1)">&#10095;</a>

      <div class="dot-base">
        <span class="dot" onclick="currentSlide(1)">&#5867;</span>
        <span class="dot" onclick="currentSlide(2)">&#5867;</span>
        <span class="dot" onclick="currentSlide(3)">&#5867;</span>
      </div>
    </div>
  </div>

  <hr />

  <!--Sticky Navbar-->
  <div id="nav" class="navbar-base">
    <ul>
      <li class="navbar-button" style="display: inline-block;"> @Html.ActionLink("main page", "MainPage", "Home") </li>
      <li class="navbar-button" style="display: inline-block;">
        @Html.ActionLink("about", "About", "About")
        <ul class="navbar-ddmenu">
          <li class="navbar-ddcontent" style="display: inline-block;">@Html.ActionLink("academy", "Academy", "About")</li>
          <li class="navbar-ddcontent" style="display: inline-block;">@Html.ActionLink("the club", "DKClub", "About")</li>
          <li class="navbar-ddcontent" style="display: inline-block;">@Html.ActionLink("taebo", "TaeBo", "About")</li>
          <li class="navbar-ddcontent" style="display: inline-block;">@Html.ActionLink("founders and staff", "Staff", "About")</li>
        </ul>
      </li>
      <li class="navbar-button" style="float:right"> @Html.ActionLink("contacts", "Contacts")</li>
      <li class="navbar-button" style="float:right"> @Html.ActionLink("gallery", "Gallery")</li>
      <li class="navbar-button" style="float:right"> @Html.ActionLink("shop dk", "Index", "Shop")</li>
    </ul>
  </div>
</div>

【讨论】:

  • 一个问题:&lt;div class="slideshow-base"&gt; 上应该有style="height: 90vh" 吗?
  • 啊不,你可以删除它(复制和粘贴错误) - flex-grow:1 将使底部填充高度的其余部分
  • 好的,我刚刚添加了其余代码,因为flex-grow=1 使幻灯片消失了。我将它应用于slideshow-baseslideshow-container。原因是当我将它添加到 slideshow-base 时它没有任何影响
  • 你做了 = 还是冒号 - 它似乎在上面的 sn-p 中工作
  • 好的,我修好了!我也将slideshow-base 的显示设置为flex 并在slideshow-container 上设置flex-grow: 1 并且它可以工作!!很抱歉占用了你这么多时间。不过我非常感谢!
【解决方案3】:

您可以将这两个元素包装在一个包装器中(并且可以选择给它一个高度)并使用 flexbox 让它们共享空间。

在下面的示例中,幻灯片将始终覆盖 90% 的 wrapper 高度,而 nav 将覆盖 10% 的高度。

.slideshow,
.nav {
  border: 2px solid #000
}

.wrapper {
  display: flex;
  flex-direction: column;
  height: 90vh
}
   
.nav {
  /* An arbitrary value to start with */
  flex-grow: 1;
}

.slideshow {
  /* Grow this element 9 times more than the other element. */
  flex-grow: 9;
}
<div class="wrapper">
  <div class="slideshow">
    Slideshow content
  </div>

  <nav class="nav">
    Navigation content
  </nav>
</div>

【讨论】:

  • 我认为这也会使position: sticky 变得多余,不是吗> 导航栏在向下滚动后必须固定在页面顶部
  • 如果这是您所要求的,您仍然必须指定导航应在其顶部接触视口时粘在顶部。所以是的,position:sticky 将是多余的。
  • 表示javascript D_:
  • CSS 网格解决方案也会强制你使用 JS :)
猜你喜欢
  • 2017-10-27
  • 1970-01-01
  • 1970-01-01
  • 2013-07-20
  • 2014-05-30
  • 2012-09-12
  • 1970-01-01
  • 2019-05-06
  • 2018-10-18
相关资源
最近更新 更多