4

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?

1
  • 2
    why you need to use css-grid? this a clear table layout Commented Jan 10, 2019 at 21:52

2 Answers 2

3

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>

Sign up to request clarification or add additional context in comments.

1 Comment

@hyperdrive add you solution using CSS grid or flexbox if it's possible
1

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>

2 Comments

just want to point out that though display: contents may work for simple use cases, it effectively removes the box of the element it's set on. this has many implications but as an example: if the container has display: grid and the children display: contents, you cannot dictate the height of the children because they don't have a box! height is just one property, but there are many more that fail. it's just something to be aware of as once you add any amount of complexity this solution quickly degrades.
seems like few things are not needed: grid-template-rows & grid-row-start per child & grid-column-start for the label... still works the same without them

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.