首页 > 解决方案 > CSS网格模板区域;有时为空的网格区域 - 令人惊讶的行为

问题描述

我有一个使用网格模板区域设置的 CSS 网格。我有四行;一行有两个按钮,然后是一行,div根据是否单击第一个按钮有条件地呈现(使用 jsx)。最后两行的设置相同。

HTML

<div className='wrapper'>
  <button className='button1'/>
  <button className='button2'/>
  {isDiv1Showing && (
  <div className='div1'>Content</div>
  )}
  <button className='button3'/>
  <button className='button4'/>
  {isDiv2Showing && (
  <div className='div2'>Content</div>
  )}
</div>

CSS

.wrapper {
  display: grid;
  grid-template-columns: 5fr 1fr;
  grid-template-rows: auto;
  grid-template-areas:
  "a1 a2"
  "a3 a3"
  "b1 b2"
  "b3 b3"
  ;
}

.button1 {
  grid-area: 'a1';
}

.button2 {
  grid-area: 'a2';
}

.div1 {
  grid-area: 'a3';
}

.. and the same for the next two rows.


我期望发生的事情:

场景1:没有按下按钮:

Row1; button1 button2
Row2: 
Row3: button3 button4
Row4: 

场景 2:row1 中的按钮被按下:

Row1; button1 button2
Row2: div1
Row3: button3 button4
Row4: 

但这不是发生的事情 - 而是发生了这种情况:

场景一:

Row1; button1 button2
Row2: button3 button4
Row3: 
Row4: 

方案 2

Row1; button1 button2
Row2: <div/> button3
Row3: button4
Row4: 

我想我不完全理解网格模板区域的行为,特别是当区域为空时。同样令我惊讶的是,button3 和 button4 离开了它们分配的网格区域以占用 a3 中的空间,我想知道如何防止这种情况发生?

我知道我可以通过其他方式达到预期的结果,例如 flexbox 或不同的网格设置。我这里的例子显然是一个简化的例子,我的具体问题包括更多的行,这就是我要使用网格的原因。

标签: csscss-grid

解决方案


属性不被尊重的原因grid-area是因为您将它们用引号括起来。如果您检查该元素,您会发现浏览器报告了一个无效值。

.button1 {
  grid-area: 'a1';
}

无效的属性值[1]

它们应该看起来像这样:

.button1 {
  grid-area: a1;
}

此外,您的网格行在高度上折叠的原因是因为您缺少该grid-auto-rows属性:当行中的所有元素都没有内容时(例如,您.div1的没有在第二行中呈现),它会折叠到 0 的高度。您将需要使用它来分配最小高度,例如grid-auto-rows: 20px它之类的。

.wrapper {
  display: grid;
  grid-template-columns: 5fr 1fr;
  grid-auto-rows: 20px;
  grid-template-areas:
  "a1 a2"
  "a3 a3"
  "b1 b2"
  "b3 b3"
  ;
}

.button1 {
  grid-area: a1;
}

.button2 {
  grid-area: a2;
}

.div1 {
  grid-area: a3;
}

.button3 {
  grid-area: b1;
}

.button4 {
  grid-area: b2;
}

.div2 {
  grid-area: b3;
}
<div class='wrapper'>
  <button class='button1'>Btn1</button>
  <button class='button2'>Btn2</button>

  <!-- Let's choose not to render it -->
  <!--
  <div class='div1'>Content</div>
  -->

  <button class='button3'>Btn3</button>
  <button class='button4'>Btn4</button>

  <div class='div2'>Content</div>

</div>


推荐阅读