Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to align columns in nested HTML using CSS grid

Tags:

html

css

css-grid

I need to use a grid, but my columns are not direct children of the grid. The grid has two columns:

  1. Column 1 contains the label.
  2. Column 2 contains the input box.

The label column should be as large (but not larger) than the largest column. The input column should use all remaining space. I attempted the following CSS/HTML combo.

* {
  border: 1px solid black;
  background: #2222;
}

.container {
  display: grid;
  width: 550px;
  grid-gap: 10px;
  grid-template-rows: [a] auto [b] auto [c] auto;
  grid-template-columns: [label] auto [input] 1fr;
  align-items: stretch;
}

label { grid-column-start: label; }
input { grid-column-start: input; }

.a { grid-row-start: a; }
.b { grid-row-start: b; }
.c { grid-row-start: c; }
<div class="container">
  <div class="a">
    <label>A</label>
    <input>
  </div>
  <div class="b">
    <label>Label B</label>
    <input>
  </div>
  <div class="c">
    <label>Longest C label</label>
    <input>
  </div>
</div>

I understand that the grid-column-start isn't used, because the elements are not direct children of the grid. But how can I accomplish this functionality without hardcoding the label width or use Javascript?

Using multiple grids (one per row) would be fine, but I would need to synchronized the widths of the first column. I have read about subgrids, but it's not implemented by any major browser yet. Do I have other alternatives to solve this issue?

like image 564
Ramon de Klein Avatar asked Sep 10 '25 09:09

Ramon de Klein


2 Answers

This seems to be more suitable for table layout than CSS grid:

* {
 box-sizing:border-box;
}
.container {
  display: table;
  width: 550px;
  border:1px solid;
}

.container>div {
  display: table-row;
}

label,
input {
  display: table-cell;
  border:1px solid green;
}
label {
  width:5%; /*a small value*/
  white-space:nowrap;
}
input {
 width:100%;
}
<div class="container">
  <div class="a">
    <label>A</label>
    <input>
  </div>
  <div class="b">
    <label>Label B</label>
    <input>
  </div>
  <div class="c">
    <label>Longest C label</label>
    <input>
  </div>
</div>
like image 104
Temani Afif Avatar answered Sep 12 '25 23:09

Temani Afif


If the browser support is enough for you, there is the display: contents to 'exclude' the wrapper elements from the rendering and only shows their content (similar to display: none, none of any other properties will appear on the parent (like background, margin, padding.. etc), but it will keep the child elements in play) -> the children will use the parent's grid layout references to align themself.

* {
  border: 1px solid black;
  background: #2222;
}

.container {
  display: grid;
  width: 550px;
  grid-gap: 10px;
  grid-template-rows: [a] auto [b] auto [c] auto;
  grid-template-columns: [label] auto [input] 1fr;
  align-items: stretch;
}

label { grid-column-start: label; }
input { grid-column-start: input; }

.a { grid-row-start: a; display: contents; }
.b { grid-row-start: b; display: contents; }
.c { grid-row-start: c; display: contents; }
<div class="container">
  <div class="a">
    <label>A</label>
    <input>
  </div>
  <div class="b">
    <label>Label B</label>
    <input>
  </div>
  <div class="c">
    <label>Longest C label</label>
    <input>
  </div>
</div>
like image 34
TWS Avatar answered Sep 12 '25 23:09

TWS