I've been trying out Firefox's implementation of the CSS subgrid spec in Nightly for an add-on, and have what I think is a really basic question that I couldn't find an explicit answer to on the MDN.
If I have a deeply nested element hierarchy, and only want to lay out its terminal nodes (the ones deepest in the hierarchy) on a single grid defined at the top-level element, do I have to make sure grid-template-columns/grid-template-rows is set to "subgrid" for every level inbetween + make sure that they've got grid-column/grid-row set to span the ancestor's entire grid?
In my example below I initially made everything with div's, but then when I introduced the semantics I found myself needing to specify "subgrid that should span its entire parent's grid" over and over in the middle layers, to the point where I just added a single selector to set that by default for every element. (The code below also exists in this fiddle). If I were to start from scratch I think I'd only set grid-column/grid-row specifically for the terminal nodes instead, which led to the question.
<ol class="root">
<li class="topOfPage">
<button>
Read to Top of Page
</button>
</li>
<li class="middleOfPage">
<ol>
<li class="topLine">
<button>
Read Previous Line
</button>
</li>
<li class="middleLineContent">
<ul>
<li class="middleLine">
<button>
Read Current Line
</button>
</li>
<li class="lineContent">
<ol>
<li class="prevWord">
<button>
Read Previous Word
</button>
</li>
<li class="middleWordContent">
<ul>
<li class="middleWord">
<button>
Read Current Word
</button>
</li>
<li class="charContent">
<ol>
<li class="prevChar">
<button>
Read Previous Character
</button>
</li>
<li class="middleChar">
<button>
Read Current Character
</button>
</li>
<li class="nextChar">
<button>
Read Next Character
</button>
</li>
</ol>
</li>
</ul>
</li>
<li class="nextWord">
<button>
Read Next Word
</button>
</li>
</ol>
</li>
</ul>
</li>
<li class="bottomLine">
<button>
Read Next Line
</button>
</li>
</ol>
</li>
<li class="bottomOfPage">
<button>
Read to Bottom of Page
</button>
</li>
</ol>
li {
list-style-type: none;
}
ol,ul {
padding-left: 0;
}
.root {
display: grid;
grid-template-columns: repeat(5, auto);
grid-template-rows: repeat(5, auto);
height: 250px;
}
.root * {
display: grid;
grid-template-columns: subgrid;
grid-template-rows: subgrid;
grid-column: 1/-1;
grid-row: 1/-1;
}
.root .topOfPage {
grid-column: 1 / 6;
grid-row: 1 / 1;
}
.root .bottomOfPage {
grid-column: 1 / 6;
grid-row: 5 / 5;
}
.root .middleOfPage {
display: grid;
grid-template-columns: subgrid;
grid-template-rows: subgrid;
grid-column: 1 / 6;
grid-row: 2 / 6;
}
.root .middleOfPage .topLine {
grid-column: 1 / 6;
grid-row: 1 / 1;
}
.root .middleOfPage .bottomLine {
grid-column: 1 / 6;
grid-row: 3 / 3;
}
.root .middleOfPage .middleLineContent {
display: grid;
grid-template-columns: subgrid;
grid-template-rows: subgrid;
grid-column: 1 / 6;
grid-row: 2 / 2;
}
.root .middleOfPage .middleLineContent .middleLine {
grid-column: 1 / 6;
grid-row: 1 / 1;
}
.root .middleOfPage .middleLineContent .lineContent {
display: grid;
grid-template-columns: subgrid;
grid-template-rows: subgrid;
grid-column: 1 / 6;
grid-row: 1 / 1;
}
.root .middleOfPage .middleLineContent .lineContent .prevWord {
grid-column: 1 / 1;
grid-row: 1 / 1;
}
.root .middleOfPage .middleLineContent .lineContent .nextWord {
grid-column: 6 / 6;
grid-row: 1 / 1;
}
.root .middleOfPage .middleLineContent .lineContent .middleWordContent {
display: grid;
grid-template-columns: subgrid;
grid-template-rows: subgrid;
grid-column: 2 / 5;
grid-row: 1 / 1;
}
.root .middleOfPage .middleLineContent .lineContent .middleWordContent .middleWord {
grid-column: 1 / 4;
grid-row: 1 / 1;
}
.root .middleOfPage .middleLineContent .lineContent .middleWordContent .charContent {
display: grid;
grid-template-columns: subgrid;
grid-template-rows: subgrid;
grid-column: 1 / 4;
grid-row: 1 / 1;
}
.root .middleOfPage .middleLineContent .lineContent .middleWordContent .charContent .prevChar {
grid-column: 1 / 1;
grid-row: 1 / 1;
width: 75px;
}
.root .middleOfPage .middleLineContent .lineContent .middleWordContent .charContent .middleChar {
grid-column: 2 / 2;
grid-row: 1 / 1;
width: 75px;
}
.root .middleOfPage .middleLineContent .lineContent .middleWordContent .charContent .nextChar {
grid-column: 3 / 3;
grid-row: 1 / 1;
width: 75px;
}
Yes, based on my testing, it needs to be specified at every level, but you can set it to "inherit", instead of needing to add the correct values for each level:
<div style="display: grid">
<div style="grid-column: 1; grid-row: 1">Nav (Row 1)</div>
<div style="grid-column: 1; grid-row: 1/99; grid-template-rows: subgrid; display: inherit">
<div style="display: inherit; grid-column: inherit; grid-row: inherit; grid-template-rows: inherit">
<div style="display: inherit; grid-column: inherit; grid-row: inherit; grid-template-rows: inherit">
<div style="grid-row: 1; justify-self: center">Hero (Row 1, centered)</div>
<div style="grid-row: 2">Row 2</div>
<div>Row 3</div>
</div>
</div>
</div>
</div>