【问题标题】:CSS-Grid: Stretch main if sidebar is emptyCSS-Grid:如果侧边栏为空,则拉伸主
【发布时间】:2021-04-14 09:35:03
【问题描述】:

我在简单的网格布局中遇到了一些样式问题,其中包含边栏 (aside) 和一些 main 内容。

<body>
  <header>Header</header>
  <nav>Navigation Links</nav>
  <aside>Sidebar</aside>
  <main>Some main content</main>
  <footer>Footer</footer>
</body>

在某些页面上,我的 html 中没有 aside

<body>
  <header>Header</header>
  <nav>Navigation Links</nav>

  <main>Some main content</main>
  <footer>Footer</footer>
</body>

这是我的代码

body {
  height: 100%;
  display: grid;
  /* mobile layout */
  grid-template: auto auto auto 1fr auto / 1fr;
  grid-template-areas:
    "header"
    "nav"
    "aside"
    "main"
    "footer";
}

header {
  background-color: blue;
  grid-area: header;
}

nav {
  background-color: aquamarine;
  grid-area: nav;
}

aside {
  background-color: green;
  grid-area: aside;
}

main {
  background-color: yellow;
  grid-area: main;
}

footer {
  background-color: orange;
  grid-area: footer;
}

/* desktop layout */
@media (min-width: 768px) {
  body {
    grid-template: auto auto 1fr auto / minmax(300px, 25%) 1fr;
    grid-template-areas:
      "header header"
      "nav nav"
      "aside main"
      "footer footer";
  }
}
<body>
  <header>Header</header>
  <nav>Navigation Links</nav>
  <!-- if aside is deleted main should strech whole space-->
  <aside>Sidebar</aside>
  <main>Some main content</main>
  <footer>Footer</footer>
</body>

如果显示侧边栏,它的最小宽度应为 300 像素。如果侧边栏没有显示,主要内容应该占据整个宽度。然而这是不可能的,它仍然只占宽度的 75%(aside 最大为 25%)。

我想到的一些解决方案:

  1. 如果没有显示aside,我可以调整grid-template 以仅使用一个网格列:
    grid-template: auto auto auto 1fr auto / 1fr;
    
    但是,我不知道如何使用 CSS 完成此操作。 :has 选择器仍在草稿中。
  2. 将第一个网格列的宽度设置为 0。
    grid-template: auto auto 1fr auto / 0 1fr;
    
    但是,如果显示了一边,我该如何覆盖此设置?

感谢您的帮助!

【问题讨论】:

  • 我也认为这可能是解决方案,但它不起作用。 grid-template: auto auto 1fr auto / minmax(0px, 25%) 1fr; 可能是因为声明了 2 个网格列?

标签: css css-grid


【解决方案1】:

aside 元素内定义宽度并将auto 保留在模板中。由于您正在处理全宽/高网格,您可以考虑使用25vw 而不是25%

您还必须考虑移动布局并正确放置主要和页脚

body {
  height: 100vh;
  margin: 0;
  display: grid;
  grid-template: auto auto auto 1fr auto / 1fr;
}

header { background-color: blue;}
nav { background-color: aquamarine;}
aside { background-color: green;}
main { background-color: yellow;grid-row:4}
footer { background-color: orange;grid-row:5}

/* desktop layout */

@media (min-width: 768px) {
  body {
    grid-template: auto auto 1fr auto / auto 1fr;
    grid-template-areas: "header header" "nav nav" "aside main" "footer footer";
  }
  aside {
    width: min(300px, 25vw);
  }
  header { grid-area: header;}
  nav { grid-area: nav; }
  aside { grid-area: aside;}
  main { grid-area: main;}
  footer {grid-area: footer;}
}
<body>
  <header>Header</header>
  <nav>Navigation Links</nav>
  <!-- if aside is deleted main should strech whole space-->
  <aside>Sidebar</aside>
  <main>Some main content</main>
  <footer>Footer</footer>
</body>

【讨论】:

  • 感谢您的解决方案。但是aside 的宽度应该是max(300px, 25vw); 以避免缩小。
  • @Theiaz 是的,基于您想要的逻辑的最小值或最大值;) .. 我没有注意那部分。我只是专注于将宽度移到一边的技巧
  • 标记为解决方案,因为我认为它比@connexo 和fit-content() 的解决方案要容易一些。
【解决方案2】:

使用fit-content() 并为aside 指定min-width

body {
  margin: 0;
  min-height: 100vh;
}

.grid {
  height: 100vh;
  display: grid;
  /* mobile layout */
  grid-template-columns: 1fr;
  grid-template-rows: repeat(3, auto) 1fr auto;
  grid-template-areas: 
    "header"
    "nav"
    "aside"
    "main"
    "footer";
}

header {
  background-color: blue;
  grid-area: header;
}

nav {
  background-color: aquamarine;
  grid-area: nav;
}

aside {
  background-color: green;
  grid-area: aside;
  min-width: 300px;
}

main {
  background-color: yellow;
  grid-area: main;
}

footer {
  background-color: orange;
  grid-area: footer;
}


/* desktop layout */

@media (min-width: 768px) {
  .grid {
    grid-template-columns: fit-content(300px) 1fr;
    grid-template-rows: repeat(2, auto) 1fr auto;
    grid-template-areas: 
      "header header"
      "nav nav"
      "aside main"
      "footer footer";
  }
}
<div class="grid">
  <header>Header</header>
  <nav>Navigation Links</nav>
  <!-- if aside is deleted main should strech whole space-->
  <aside>Sidebar</aside>
  <main>Some main content</main>
  <footer>Footer</footer>
</div>

<div class="grid">
  <header>Header</header>
  <nav>Navigation Links</nav>
  <main>Some main content</main>
  <footer>Footer</footer>
</div>

【讨论】:

  • 谢谢!但是,您的解决方案内部有一个小错误。对于较小的屏幕,不会占用整个宽度。
  • 已更正,再次检查。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-21
  • 1970-01-01
  • 1970-01-01
  • 2020-04-15
相关资源
最近更新 更多