【问题标题】:Don't reserve space in a CSS Grid if the element doesn't exist / is optional如果元素不存在/是可选的,则不要在 CSS 网格中保留空间
【发布时间】:2021-10-13 23:12:53
【问题描述】:

我正在使用 grid-template 为一行四列设置一个简单的网格结构。最左边的两列有固定的宽度,剩下的两列应该填满剩余的空间。

但是,第二列可选 - 它可能根本不存在。在这种情况下,我不想为它保留任何空间。最右边的两列应该填满空间。

这对于网格模板显然是不可能的。有可能吗?

.grid {
  display: grid;
  grid-template-areas: "one two three four";
  grid-template-columns: 8rem 8rem 1fr 1fr;
}

.one   { background: #404788aa; grid-area: one;   }
.two   { background: #287d8eaa; grid-area: two;   }
.three { background: #3cbb75aa; grid-area: three; }
.four  { background: #dce319aa; grid-area: four;  }
<div class="grid">
  <div class="one">One</div>
  <div class="two">Two</div>
  <div class="three">Three</div>
  <div class="four">Four</div>
</div>
<hr><p>Three and Four should fill the space:</p>
<div class="grid">
  <div class="one">One</div>
  <div class="three">Three</div>
  <div class="four">Four</div>
</div>

【问题讨论】:

  • 如果你有一个固定的宽度,那么你就是在对浏览器说“保持我的空间”!
  • Grid 是为您提前知道布局而设计的,因此在您提前不知道布局的情况下,它不是正确的布局技术。

标签: html css css-grid


【解决方案1】:

尝试使用display: flexflex 属性,如下所示:

.flex {
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
}

.one   { background: #404788aa; flex: 0 1 8rem; }
.two   { background: #287d8eaa; flex: 0 1 8rem; }
.three { background: #3cbb75aa; flex: 1 1 auto; }
.four  { background: #dce319aa; flex: 1 1 auto; }
<div class="flex">
  <div class="one">One</div>
  <div class="two">Two</div>
  <div class="three">Three</div>
  <div class="four">Four</div>
</div>
<hr><p>Three and Four should fill the space:</p>
<div class="flex">
  <div class="one">One</div>
  <div class="three">Three</div>
  <div class="four">Four</div>
</div>

【讨论】:

    【解决方案2】:

    此方案将 3 列和 4 列布局合并为 5 列布局,并使用 css 技巧根据一定的存在和顺序检测在 div 上使用哪个类。然后使用 grid-column 属性手动调整 div 以根据需要对齐。

    这太可怕了,它绝对不是scalabe,但它只使用grid和css来解决问题。

    在查看了我的解决方案后,我根本不想分享它,但后来我认为这将是展示 flex 解决方案(由@ng-hobby 提供)如何比这更好的一个很好的选择。

    正如@TylerH 所说,网格系统并不是一个完美的解决方案,因为您必须先定义一个结构,然后才能真正知道要在该结构中容纳多少元素。

    这是一个展示 3 列和 4 列布局合并在一起时如何结束的视觉效果。垂直线表示网格线,下面的数字是它们的名称。

    4 column layout
    
    |  8rem  |  8rem  |  1fr (50% - 8rem)  |  1fr (50% - 8rem)  |
    |        |        |                    |                    |
    
    3 column layout
    
    |  8rem  |    1fr (50% - 4rem)    |    1fr (50% - 4rem)     |
    |        |                        |                         |
    
    5 column (mixed) layout
    
    |        |        |               |    |                    |
    1        2        3               4    5                    6
    |  8rem  |  8rem  |  50% - 12rem  |4rem|    50% - 8rem      |
    

    由此我们可以计算 grid-template-columns 属性。 请注意,我需要切换到百分比,因为 calc() 不适用于 fr。

    css 中的 (+) 称为“相邻兄弟选择器”,在这种情况下,它用于在某些 div 彼此相邻时应用 css 规则。

    .grid {
      display: grid;
      grid-template-columns: 8rem 8rem calc(50% - 12rem) 4rem calc(50% - 8rem) ;
    }
    
    .one   { background: #404788aa; grid-column: 1 / 2; }
    .two   { background: #287d8eaa; grid-column: 2 / 3; }
    .two + .three { background: #3cbb75aa; grid-column: 3 / 5; }
    .three { background: #3cbb75aa; grid-column: 2 / 4; }
    .four  { background: #dce319aa; grid-column: 4 / 6; }
    .two + .three + .four { background: #dce319aa; grid-column: 5 / 6; }
    <div class="grid">
      <div class="one">One</div>
      <div class="two">Two</div>
      <div class="three">Three</div>
      <div class="four">Four</div>
      </div>
    </div>
    
    <hr><p>Three and Four should fill the space:</p>
    <div class="grid">
      <div class="one">One</div>
      <div class="three">Three</div>
      <div class="four">Four</div>
      </div>
    </div>

    【讨论】:

      猜你喜欢
      • 2021-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-14
      • 1970-01-01
      • 1970-01-01
      • 2019-03-13
      • 2023-03-22
      相关资源
      最近更新 更多