【问题标题】:How to force CSS grid column to take as much space as possible within parent container?如何强制 CSS 网格列在父容器中占用尽可能多的空间?
【发布时间】:2020-05-16 17:37:24
【问题描述】:

我有以下布局:

.table {
  display: grid;
  grid-template-columns: fit-content(100%) auto;
}

.grid-item {
  height: 50px;
  padding: 8px;
  border: 1px solid grey;
}

.a {
  background-color: #feb5f5;
}

.b {
  background-color: #76daff;
}
<div style="display: flex; align-items: center; flex-direction: column; background-color: #ddff33">
  <div style="max-width: 1500px; background-color: #ccaa44; display:flex; align-items: first baseline; flex-direction: column;">
    <div class="table">
      <div class="grid-item a">Constant</div>
      <div class="grid-item b">Variable size content that should take as much space as possible</div>
    </div>
  </div>
</div>

它应该按照以下规则运行。我有 WPF 背景,但很难在 HTML/CSS 中完全实现它们:

  1. 页面内容的最大宽度为 1500 像素并且水平居中。如果视口小于 1500 像素,则内容应缩小(即响应上限)。
  2. 居中的内容本身是一个由两列组成的网格:
    1. 左列应占用最小水平空间(WPF 中的Auto 列大小)。
    2. 右栏应占用所有可用空间(WPF 中的* 列大小):
      1. 如果视口足够大,可以达到 1500 像素的限制。
      2. 如果小于 1500 像素,则最多占用所有剩余的视口空间。

如果没有“居中 1500px”规则(1frautomax-content 列大小对我有用),这不会是一个问题,但是正如您在上面的代码中看到的那样,当在父容器中时网格不会占用所有可用的 1500 像素。

StackOverflow 截取的宽度为 800px,这意味着这里根本不应该有黄色空间。

这种行为的问题是(在我的应用程序中)右列的内容可以由 js 代码重新加载,这导致它在几分之一秒内宽度为零。在当前布局下,这意味着左列“跳”向中心并返回一小部分时间,这看起来很糟糕。

我试图通过两种方式实现解决方案:

  1. 尝试不同的网格列大小,使其尽可能占据所有空间(似乎不起作用)。
  2. 在 1500 像素的容器内引入额外的容器,这将占用所有可用空间并将子网格置于左侧。我觉得这应该是可能的,但我不知道具体如何。
  3. 也许我应该在我的 sn-p 中使用 flex 容器以外的东西居中并限制子网格为 1500 像素?

如果 2 可以正常工作,视口 >1500px 的布局将如下所示:

我也有可用的 Bootstrap 4,但希望我可以专门使用 CSS 网格进行布局。

【问题讨论】:

    标签: html css css-grid


    【解决方案1】:

    我们可以简单地使用margin:auto居中

    [container] {
    /*     display: flex; */
    /*     align-items: center; */
    /*     flex-direction: column; */
        background-color: #ddff33
    }
    
    [widthconstraint] {
        max-width: 1500px;
        margin:auto;
        background-color: #ccaa44;
    /*     display: flex; */
    /*     align-items: first baseline; */
    /*     flex-direction: column; */
    }
    
    .table {
        display: grid;
        /*   grid-template-columns: fit-content(100%) auto; */
        grid-template-columns: auto 1fr;
    }
    
    .grid-item {
        height: 50px;
        padding: 8px;
        border: 1px solid grey;
    }
    
    .a {
        background-color: #feb5f5;
    }
    
    .b {
        background-color: #76daff;
    }
    <div container>
      <div widthconstraint>
        <div class="table">
          <div class="grid-item a">Constant</div>
          <div class="grid-item b">Variable size content that should take as much space as possible</div>
        </div>
      </div>
    </div>

    您的代码的问题是弹性项目默认具有flex-shrink:1;flex-grow:0;,因此它们不会增长以填充父项,它们会缩小以适应其内容,如果您想使用弹性框居中,该修复非常明显.

    [container] {
        display: flex;
        /*     align-items: center; */
        /*     flex-direction: column; */
        justify-content: center;
        /* Align horizontally */
        background-color: #ddff33
    }
    
    [widthconstraint] {
        flex: 1 0 0;
        max-width: 1500px;
        background-color: #ccaa44;
        display: flex;
        /* align-items: first baseline; */
        /* flex-direction: column; */
    }
    
    .table {
        flex: 1 0 0;
        display: grid;
        /*       grid-template-columns: fit-content(100%) auto; */
        grid-template-columns: auto 1fr;
    }
    
    .grid-item {
        height: 50px;
        padding: 8px;
        border: 1px solid grey;
    }
    
    .a {
        background-color: #feb5f5;
    }
    
    .b {
        background-color: #76daff;
    }
    <div container>
      <div widthconstraint>
        <div class="table">
          <div class="grid-item a">Constant</div>
          <div class="grid-item b">Variable size content that should take as much space as possible</div>
        </div>
      </div>
    </div>

    注意:代码是不言自明的,但是如果您有任何问题,请尽管提出。 我冒昧地清理了一下代码

    【讨论】:

    • 谢谢!我使用了您的第一个解决方案中的代码(就像简单性一样),它完美地工作,只需要调整 auto -&gt; fit-content(any%) 即可在更改内容时完全消除“跳跃”。我记得尝试过margin: auto,但可能做错了什么,无法让它工作,所以感谢您提供简单而优雅的解决方案。并感谢您花时间解释如何使两种方法(弹性和非弹性)工作!
    • @ArXen42 我将fit-content(100%) auto 更改为auto 1fr,因为fit-content() 上的support 没有那么宽。它不适合你吗?
    • 几乎工作了:) 在我的应用程序右侧面板中包含一些有些复杂的动态内容(嵌入式控件在用户操作时被删除并再次加载)和左列本身的内容稍有反应(空间不足时会缩小)。在右栏内容重新加载期间,auto 1fr 整个网格在几分之一秒内收缩了一点点(尽管比以前少得多)。当我更改为fit-content(100%) 1fr 时,它完全停止了收缩。我猜那是我在某处的内容造成的。
    猜你喜欢
    • 1970-01-01
    • 2010-09-12
    • 1970-01-01
    • 2021-08-14
    • 2020-08-08
    • 1970-01-01
    • 2012-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多