当第二列不存在时如何使一列跨越整个宽度?(CSS Grid)

20

我知道有类似的问题,但这个问题特别询问如何使用CSS Grid布局来实现。

所以我们有这个基本的网格设置:

HTML(带侧边栏):

<div class="grid">

  <div class="content">
    <p>content</p>
  </div>

  <div class="sidebar">
    <p>sidebar</p>
  </div>

</div>

CSS:

.grid {
  display: grid;
  grid-template-columns: 1fr 200px;
}
为了创建一个类似下面这样的布局:
| content               | sidebar |
如果页面没有侧边栏,即HTML代码看起来像这样,但与相同的CSS一起使用: HTML(无侧边栏):
<div class="grid">

  <div class="content">
    <p>content</p>
  </div>

</div>

页面布局如下所示(短横线表示空白区域)

| content               | ------- |

我知道为什么会这样,那是因为网格列仍在grid-template-columns规则中定义。

我只是想知道如何告诉网格如果没有内容,则填充类似于flexboxflex-grow工作方式的剩余空间。

如果没有侧边栏,期望的结果将如下所示。

| content                         |
3个回答

12
不要使用grid-template-columns显式定义列。
相反,使列成为隐式的,然后使用grid-auto-columns来定义它们的宽度。
这将允许第一列(.content)在第二列(.sidebar)不存在时占据行中所有的空间。
.grid {
  display: grid;
  grid-auto-columns: 1fr 200px;
}

.content {
  grid-column: 1;
}

.sidebar {
  grid-column: 2;
}

.grid > * {
  border: 1px dashed red; /* demo only */
}
<p>With side bar:</p>

<div class="grid">

  <div class="content">
    <p>content</p>
  </div>
  
  <div class="sidebar">
    <p>sidebar</p>
  </div>

</div>

<p>No side bar:</p>

<div class="grid">

  <div class="content">
    <p>content</p>
  </div>
  
</div>


2
这是一个很好的答案,但不幸的是,如果侧边栏<div>在内容<div>之前(以及更新网格列以匹配新布局),它就无法工作。我无法弄清楚为什么会出现这种情况。 - Sean Beck
内容(没有侧边栏)不会跨越网格扩展。 - evolutionxbox
你使用的是哪个浏览器?在我上面的演示中,内容会展开,没有侧边栏。刚刚测试了Chrome、Firefox和Edge。@evolutionxbox - Michael Benjamin
1
FFx 60 (osx), Chrome 66 (osx) --- 无论是否有侧边栏,内容列的宽度都是相同的。 - evolutionxbox
@callback,正如您在我的演示中所看到的那样,它确实会扩展。但也许您的设置不同。考虑发布一个新问题并附上您的代码。 - Michael Benjamin
显示剩余5条评论

8
您可以使用内容大小调整关键字来实现更接近的效果,例如:
.grid {
  display: grid;
  grid-template-columns: 1fr fit-content(200px);
}

.sidebar {
  width: 100%;
}
fit-content关键字会查看内容的大小,并像max-content一样运行,直到达到您传递的值。
实际上,您可能不需要在侧边栏上贴上尺寸,因为内容很可能至少占据200像素的空间(例如),但您可以尝试调整此设置。

我认为在侧边栏上设置width: 100%可能会使侧边栏的宽度基于网格布局值而不是两次声明200px。 - Daniel Tonon
如果你不想设置任何东西,就不要在它上面设置。 - Rachel Andrew
那不是意味着如果侧边栏中没有200像素的内容,侧边栏可能会小于200像素宽吗? - Daniel Tonon

5

我认为现在我知道这个问题的明确答案了。到目前为止,答案存在的问题是它们没有解释如何处理在主要内容左侧的边栏(主要是因为我在最初的问题中没有提到它)。

<div class="grid">

  <nav>
    <p>navigation</p>
  </nav>

  <main>
    <p>content</p>
  </main>

  <aside>
    <p>sidebar</p>
  </aside>

</div>

You can use this CSS:

.grid {
  display: grid;
  grid-template-columns: fit-content(200px) 1fr fit-content(200px);
}

nav, aside {
  width: 100%;
}

/* ensures that the content will always be placed in the correct column */
nav { grid-column: 1; }
main { grid-column: 2; }
aside { grid-column: 3; }

这也是grid-areas的一个很好的使用案例。
.grid {
  display: grid;
  grid-template-columns: fit-content(200px) 1fr fit-content(200px);
  grid-template-areas: "nav content sidebar";
}

nav, aside {
  width: 100%;
}

/* ensures that the content will always be placed in the correct column */
nav { grid-area: nav; }
main { grid-area: content; }
aside { grid-area: sidebar; }

一个兼容IE的版本应该是这样的:
.grid {
  display: -ms-grid;
  display: grid;
  -ms-grid-columns: auto 1fr auto;
  grid-template-columns: auto 1fr auto;
}

nav, aside {
  width: 100%; /* Ensures that if the content exists, it takes up max-width */
  max-width: 200px; /* Prevents the content exceeding 200px in width */
}

/* ensures that the content will always be placed in the correct column */
nav {
  -ms-grid-column: 1;
  grid-column: 1;
}

main {
  -ms-grid-column: 2;
  grid-column: 2;
}

aside {
  -ms-grid-column: 3;
  grid-column: 3;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接