【问题标题】:Fixed header and sidebar using flexbox without manually setting offset margin使用 flexbox 修复标题和侧边栏,无需手动设置偏移边距
【发布时间】:2021-09-15 14:59:09
【问题描述】:

如何使用 flexbox 对带有页眉和边栏的页面进行布局,并使它们都固定,而无需在我的主要内容上应用静态边距以防止它被覆盖?

我正在查看https://keep.google.com/,他们使用 flexbox 布置了所有内容,但是在滚动内容 div 并检查它时仍然有一个固定的标题和边栏,并且没有显示偏移,只是普通的 flexbox。

我无法重现这个...我有这个 flexbox 布局的代码笔,但是如果 <div class="content"> 的顶部没有被覆盖,我无法让页眉和边栏保持固定。

【问题讨论】:

  • 是否可以将两个元素放在同一个容器中并使该容器位置:固定; ?

标签: html css flexbox


【解决方案1】:

body 元素调整为视口大小,并确保您的弹性项目是不会溢出body 的滚动容器。

你应该可以用普通的 flexbox 来实现这个布局。

我们将有两个弹性容器:

  • 垂直布局我们的 headersidebar+content
  • 在上面水平放置我们的 sidebarcontent

您可以使用height: 100vh 确保body 元素占据视口的高度。

默认情况下,Flex 项目希望保持其最小内容大小 (min-height: auto)。但是因为我们希望内容在 inside 中滚动,所以我们希望 flex 项目本身总是填充其 flex 容器中可用的任何空间。我们可以使用min-height: 0 重置此自动行为。

然后,我们使用overflow-y: auto 将侧边栏和内容区域变成滚动容器。

这是一个工作示例:

body {
  margin: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
}

header {
  background-color: whitesmoke;
  padding: 0 24px;
}

section {
  display: flex;
  flex: auto;
  min-height: 0;
}

nav,
main {
  overflow-y: auto;
}

nav {
  min-width: max-content;
}

ul {
  padding: 16px;
  list-style-type: none;
}
<header><h1>Header</h1></header>
<section>
  <nav>
    <ul>
      <li>Home</li>
      <li>About</li>
      <li>Clients</li>
      <li>Contact us</li>
    </ul>
  </nav>
  <main>
    <p>
      Spicy jalapeno andouille salami tenderloin capicola meatball pig ham
      chuck doner cupim. Cupim capicola brisket landjaeger, ground round
      pork loin leberkas tail porchetta salami bacon beef ribs turkey pig
      short loin. Bresaola landjaeger biltong, pork belly andouille
      porchetta shoulder sausage cow bacon short loin doner pancetta tongue
      jerky. Flank chislic short loin strip steak fatback.
    </p>

    <p>
      Tongue pastrami biltong pork. T-bone ham hock kielbasa beef ribs
      salami. Ham turkey meatloaf strip steak kielbasa corned beef meatball
      tail beef salami alcatra filet mignon shankle cow. Rump ball tip
      venison, picanha frankfurter t-bone beef ribs spare ribs landjaeger
      beef ham hock. Short loin pork belly shankle turducken kevin pork loin
      tenderloin buffalo biltong shank alcatra. Kevin chuck swine meatball
      pork chop shoulder capicola spare ribs tri-tip.
    </p>

    <p>
      Bacon sirloin pastrami alcatra. Bacon flank shankle bresaola pig. Ham
      hock bresaola tenderloin swine shankle chuck jowl landjaeger porchetta
      beef ribs chicken short loin tri-tip turkey. Picanha ball tip short
      ribs ribeye sirloin drumstick prosciutto doner. Andouille alcatra
      shoulder, filet mignon pig chislic jerky kevin swine shank picanha
      prosciutto tenderloin pork chop. Pancetta shoulder landjaeger, flank
      capicola boudin ball tip leberkas swine venison tri-tip pork chop
      kevin.
    </p>

    <p>
      Doner pork kevin fatback sausage picanha filet mignon leberkas ham
      chislic short loin tongue andouille drumstick spare ribs. Turkey chuck
      filet mignon, chicken strip steak ground round buffalo bresaola. Short
      loin corned beef andouille, landjaeger t-bone strip steak tri-tip
      meatball. Hamburger alcatra bresaola ball tip, pork loin ground round
      short ribs. Landjaeger boudin alcatra andouille.
    </p>

    <p>
      Ribeye pork chop picanha biltong, rump pork belly chislic flank
      sirloin ham hock fatback buffalo chuck bresaola porchetta. Boudin ham
      cupim, beef ribs corned beef doner brisket landjaeger fatback t-bone.
      Tri-tip beef ribs chislic turducken short loin bacon. Cow landjaeger
      prosciutto jowl, fatback shank beef brisket tri-tip sausage short ribs
      strip steak meatball hamburger sirloin. Chuck corned beef cupim cow
      pork picanha, drumstick salami chislic brisket pancetta tail swine.
      Meatloaf kielbasa fatback t-bone hamburger jowl porchetta turducken
      rump ham cow salami. Pork belly pig boudin landjaeger beef shoulder.
    </p>
  </main>
</section>

【讨论】:

    【解决方案2】:

    我说过一种选择是设置页眉的高度,然后根据该高度计算侧边栏的高度以及主要部分的高度(参见下面的示例)。

    如果我可以补充的话,“keep.google”并没有冒犯,但我认为网格对于这种布局来说会是一个更好的选择。

    * {
      margin: 0;
      padding: 0;
    }
    
    html {
      --header-height: 80px;
      --main-height: calc(100vh - var(--header-height));
    }
    
    body {
      display: flex;
      flex-wrap: wrap;
    }
    
    header {
      background-color: green;
      height: var(--header-height);
      flex-grow: 1;
      width: 100%;
    }
    
    aside {
      background-color: blue;
      width: 200px;
      height: var(--main-height);
    }
    
    main {
      height: var(--main-height);
      overflow: auto;
      box-sizing: border-box;
      padding: 2em;
      flex: 1 0;
    }
    
    div {
      margin-bottom: 1em;
    }
    <header></header>
    <aside></aside>
    <main>
      <div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cumque non nisi reiciendis quos modi cupiditate id laboriosam alias iusto! Rerum totam accusantium ratione iusto nostrum alias atque, repellat repudiandae rem!</div>
      <div>Nostrum rerum quia quas, corporis alias voluptatibus aspernatur, similique nobis culpa ex, laborum facilis esse optio. Consectetur praesentium expedita ducimus quae molestiae quod quisquam quo, ea vel quibusdam odio. Labore.</div>
      <div>Facilis iste quibusdam, culpa ipsum impedit! Quidem consequuntur maiores quo illum enim dicta soluta molestias adipisci provident. Consectetur magni, similique porro at, deserunt cupiditate? Vero dolores iste id magni, illum!</div>
      <div>Quae impedit optio hic est vel mollitia libero, repellat doloremque similique. Similique porro officiis reiciendis at magnam, aliquid tenetur, amet harum doloremque rerum? Hic voluptas tempora atque quam obcaecati dignissimos!</div>
      <div>Soluta earum, assumenda quod laudantium ipsum totam fugiat distinctio? Obcaecati optio aut odio temporibus corporis voluptatem ullam non, earum consectetur aperiam illo, laudantium, reiciendis soluta. Doloribus dolorem, quas praesentium labore!</div>
      <div>Dolor, temporibus. Ratione accusantium cumque perferendis esse laborum est nesciunt, qui tempora cum, natus tenetur pariatur doloribus vero aperiam unde debitis dolor, exercitationem, minima corporis quae magni dignissimos reprehenderit. Perferendis!</div>
      <div>Veniam quia culpa ipsum consequatur unde nostrum nihil dicta placeat itaque obcaecati. Quia temporibus totam omnis! Quas reprehenderit, consectetur ducimus optio porro, quisquam distinctio, tempore culpa numquam nam repellat voluptatum.</div>
      <div>Quae beatae ipsam fuga magni similique facilis, reprehenderit dolores, hic eveniet totam quas recusandae mollitia consectetur inventore iste pariatur. Facere iusto, praesentium dicta aspernatur recusandae earum quisquam, at explicabo laboriosam.</div>
      <div>Eveniet repellendus, facilis, culpa nemo cupiditate provident modi ratione doloremque cum quisquam aliquam quis praesentium ad non reiciendis quod necessitatibus nobis, dolorem tempora ex. Similique, quis laborum sapiente accusamus quidem!</div>
      <div>Possimus ratione ex quos error excepturi dolores alias voluptates, voluptas dignissimos dicta, libero placeat, ad inventore harum ipsum ipsa, eveniet quo ullam impedit adipisci. A qui ratione, eligendi accusamus ad.</div>
      <div>Dolorem et natus magni, neque eum pariatur quis doloribus cum porro hic blanditiis! Iste ipsa sapiente, et nesciunt vero, non inventore recusandae sunt quam, eligendi nulla voluptas? Eum, possimus obcaecati!</div>
      <div>Esse, quas eligendi exercitationem magnam quam ut odit eius numquam, quibusdam voluptatum dolore deserunt maiores et deleniti nihil suscipit est inventore voluptates fugit. Dolor blanditiis adipisci obcaecati quae, eius commodi!</div>
      <div>Asperiores soluta amet officia. Dicta ipsa quia nesciunt blanditiis, ex culpa, repellendus praesentium cum repellat, officia natus debitis voluptatibus delectus! A amet aliquam asperiores minima distinctio adipisci illo modi saepe?</div>
      <div>Eum error tempore temporibus, doloribus incidunt, laudantium tenetur facilis. Quia aperiam aspernatur, obcaecati cumque excepturi nostrum sint earum quidem, dolor laboriosam blanditiis dignissimos delectus numquam, consectetur eaque praesentium quaerat!
        Facere.</div>
      <div>Dicta, eos, doloribus. Ad voluptates, maxime esse odit voluptate corrupti ducimus veritatis deleniti beatae quasi quam asperiores aspernatur neque aut debitis nesciunt quis est, sequi veniam! Ipsum aperiam, mollitia cum.</div>
      <div>Alias labore, quod consectetur error earum at aliquam veniam quidem animi sint fugiat est, recusandae adipisci perferendis fugit officia. Quasi quaerat numquam quod iusto exercitationem culpa repellendus, ab aspernatur! Esse.</div>
      <div>Porro, voluptates saepe ipsa deleniti perspiciatis dignissimos cumque? Optio culpa tenetur ullam neque a fugiat, tempora velit, sed ipsa maxime ut commodi quaerat. Quas error incidunt eaque sit distinctio iure!</div>
      <div>Asperiores quaerat consequuntur distinctio nostrum alias fuga quasi nemo similique sint animi, inventore officia. Asperiores et labore quibusdam, recusandae a maxime, minima omnis error ab tenetur quia est fugit, delectus?</div>
      <div>Rerum, reprehenderit, itaque. A, dolorum esse veritatis quas dicta enim soluta, qui sunt eos deserunt debitis cumque impedit quibusdam repudiandae laboriosam dolore. Laudantium quia quo reiciendis eos voluptatum omnis illum.</div>
      <div>Facere, nesciunt? Tempore, obcaecati, ullam adipisci excepturi placeat sed perferendis odit quibusdam ab quo dicta quasi laudantium nobis fugit, officiis, itaque dolores ex exercitationem? Modi consequatur consectetur pariatur at sint.</div>
    </main>

    【讨论】:

    • 我注意到在 Google Keep 和 Stack Overflow 上,右侧滚动条一直到页面顶部,在标题旁边。知道他们是如何获得这种外观的吗?
    • @pyjamas 这是因为它们让主要内容区域扩展了 HTML 元素的整体高度,即主页滚动容器。因此,从技术上讲,当您看起来只是在滚动内容并且标题和侧边栏保持在原位时,您实际上是在滚动整个页面。标题和侧边栏有position: fixed 以保持它们的位置。
    猜你喜欢
    • 2018-08-06
    • 2016-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-26
    • 2021-09-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多