如何根据 CSS 网格线对齐 html 孙辈?

How can I align html grandchildren based off CSS Grid Lines?

我想使用 css 网格创建一个部分,分为 3 个区域,header(黄色)、body(红色)和控件(蓝色)。这些区域中的每一个都有自己的 div 网格项,以及这些 div 中的 children 个元素。

有没有一种方法可以根据祖父母 css 网格线在每个 div 中排序 children?例如让 'tick' (row2/3 col3/4),蓝色 div 与 'input' (row2/3 col2/3) 对齐, 在黄色 div.

任何网格item也可以是网格container

我的代码片段包含草图的近似值,定义了一个外部容器,其中行和列分别定义为 px 和 % 值,创建与草图等效的网格线编号(即 4 行/3 个单元格,4行/向下 3 个单元格)

  grid-template-columns: 20% 70% 10%;
  grid-template-rows: 25px 25px 150px;

然后,每个 div 通过参考线定位到网格。例如对于 'blue' 字段:

.blue {
  grid-column-start: 3;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 4;
}

请注意,它现在占据了外网格容器最后 10% 的全部高度。

现在,蓝色字段也可以是网格 容器,其网格定义时考虑到相邻单元格。回想一下用于父网格的行模板,以像素高度定义:

  grid-template-rows: 25px 25px 150px;

我们可以看到这些行的高度比是 1:1:6 并且可以使用这个比率来定义我们希望在蓝色列中 'imagine' 的行。因此,在定义其在父网格中的位置的 blue class 的 css 规则之后,我们可以将其定义为具有自己的内部单元格的网格容器 - 在这种情况下一格宽,三格高,高度占总高度的分数:

  grid-template-columns: 1fr;
  grid-template-rows: 1fr 1fr 6fr;

在 html 中,您要显示刻度的区域嵌套在 .blue 内的 div div:

  <div class="blue">
     <div class="tick">√</div>
  </div>

并且在样式表中,.tick div 在蓝色网格中的位置定义为:

  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 2;
  grid-row-end: 3;

最后,为了将(文本)标记放置在 .tick div 内,我们将其设为弹性框并使用对齐和对齐属性(我们可以将其设为网格再次使用容器,但这可能会造成混淆):

  display: flex;
  justify-content: center;
  align-items: center;

通过对相邻的黄色框应用相同的 flex 样式,我们可以确保输入字段与刻度线很好地对齐。

当然,您可以更改外部容器中行的高度,前提是您对蓝色容器的分数高度进行了相应的调整(如果像素高度的比例发生变化)。您也可以在整个过程中使用像素单位,但我故意混合使用 px、% 和 fr 以强调网格项目内网格容器的独立性质(您几乎必须 'forget' 该项目在网格中并将其视为任何其他页面上的块)。

.container {
  width: 80%;
  margin: auto;
  margin-top: 40px;
  display: grid;
  grid-template-columns: 20% 70% 10%;
  grid-template-rows: 25px 25px 150px;
  grid-gap: 1px;
  padding: 1px;
  background: black;
}

.to {
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 1;
  grid-row-end: 2;
  background: yellow;
}

.from {
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 2;
  grid-row-end: 3;
  background: yellow;
}

.label {
  grid-column-start: 2;
  grid-column-end: 3;
  grid-row-start: 1;
  grid-row-end: 2;
  background: yellow;
}

.input {
  grid-column-start: 2;
  grid-column-end: 3;
  grid-row-start: 2;
  grid-row-end: 3;
  background: yellow;
  
  
  display: flex;
  justify-content: center;
  align-items: center;
}

.red {
  grid-column-start: 1;
  grid-column-end: 3;
  grid-row-start: 3;
  grid-row-end: 4;
  background: red;
}

.blue {
  /* these numbers refer to the grid lines defined in the .container grid */
  grid-column-start: 3;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 4;
  background: blue;

  /*this grid cell can also be a grid *container* */
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 1fr 1fr 6fr;
  grid-gap: 1px;
}

.tick {
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 2;
  grid-row-end: 3;
  color: white;
  display: flex;
  font-size: 1.1em;
  justify-content: center;
  align-items: center;
}

input {
  width: 80%;
  height: 33%;
}
<div class="container">
  <div class="to">One</div>
  <div class="from">Two</div>
  <div class="label">Three</div>

  <div class="input">
    <input type="text"> 
  </div>

  <div class="red">Five</div>

  <div class="blue">
     <div class="tick">√</div>
  </div>
</div>