I have markup with the following structure. I would like to have a responsive layout with three break points that works as follows:
"....... nav ........"
"toc-pkg preamble toc-page"
"toc-pkg content toc-page"
toc
grid area both toc-page
and toc-pkg
following one after the other:
" nav ..."
" preamble toc"
" content toc"
" 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>
@Paulie_D suggested using display: contents
(thanks!). By tweaking the markup to
<div class="grid medium">
<div class="nav">NAV</div>
<div class="preamble">PRE</div>
<div class="tocs"
<div class="toc-page">TOC-PAGE</div>
<div class="toc-pkg">TOC-PKG</div>
</div>
<div class="content">TXT</div>
</div>
Allows this to be made to work as:
.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: 5em; background: #F3F3E3; grid-area: preamble; }
.grid { grid-template-rows: auto; display: grid; gap: 1rem;}
.tocs { display: contents; grid-area: unset; }
.grid {
grid-template-areas:
". nav ."
"toc-page preamble toc-pkg"
"toc-page content toc-pkg";
}
@media (max-width: 80em) {
.toc-page { grid-area: unset; }
.toc-pkg { grid-area: unset; }
.tocs { display: block; grid-area: toc }
.grid {
grid-template-areas:
"nav ."
"preamble toc"
"content toc";
}
}
@media (max-width: 60em) {
.toc-page { grid-area: toc-page; }
.toc-pkg { grid-area: toc-pkg; }
.tocs { display: contents; grid-area: unset }
.grid {
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="tocs">
<div class="toc-page">TOC-PAGE</div>
<div class="toc-pkg">TOC-PKG</div>
</div>
<div class="content">TXT</div>
</div>