I have markup with the following structure. I would like to have a responsive layout with three break points that works as follows:
- Large viewport, three columns:
"....... nav ........" "toc-pkg preamble toc-page" "toc-pkg content toc-page"
- Medium viewport, two columns, with in the
toc
grid area bothtoc-page
andtoc-pkg
following one after the other:" nav ..." " preamble toc" " content toc"
- Narrow viewport one columns:
" nav " " preamble " " toc-page " " content " " toc-pkg "
While it’s easy to get the first and third layout. I can’t get the second one. If I try to assign both toc-page
and toc-pkg
to the toc
grid area they overlap (as expected it seems), but I’d like them to stack.
Is there any solution that involves a single markup structure and only CSS?
.grid>* {
display: flex;
justify-content: center;
align-items: center;
}
.nav {
height: 1em;
background: #3C354F;
color: white;
grid-area: nav;
}
.toc-page {
height: 4em;
width: 100%;
background: #E0695E;
grid-area: toc-page;
}
.toc-pkg {
height: 2em;
width: 100%;
background: #E0695E;
grid-area: toc-pkg;
}
.content {
height: 10em;
background: #DFD4C7;
grid-area: content;
}
.preamble {
height: 6em;
background: #F3F3E3;
grid-area: preamble;
}
.tocs {
display: flex;
grid-area: tocs;
flex-direction: column;
justify-content: start;
align-items: center
}
.grid {
display: grid;
gap: 1rem;
}
.grid {
grid-template-rows: auto;
grid-template-areas: ". nav ." "toc-page preamble toc-pkg" "toc-page content toc-pkg";
}
@media (max-width: 40em) {
.toc-page {
grid-area: toc;
}
.toc-pkg {
grid-area: toc;
}
.grid {
grid-template-rows: auto;
grid-template-areas: "nav ." "preamble toc" "content toc";
}
}
@media (max-width: 30em) {
.toc-page {
grid-area: toc-page;
}
.toc-pkg {
grid-area: toc-pkg;
}
.grid {
grid-template-rows: auto;
grid-template-areas: "nav" "preamble" "toc-page" "content" "toc-pkg";
}
}
body {
margin: 1rem;
}
<div class="grid medium">
<div class="nav">NAV</div>
<div class="preamble">PRE</div>
<div class="toc-page">TOC-PAGE</div>
<div class="toc-pkg">TOC-PKG</div>
<div class="content">TXT</div>
</div>
2
Answers
@Paulie_D suggested using
display: contents
(thanks!). By tweaking the markup toAllows this to be made to work as:
At the required break-point switch the flow to
column
and adjust the areas to extend thepreamble
across two rows.I swapped out the height of the
.preamble
for amin-height: 6em;
but this is just a matter of preference.