My dilemma can be summarised with the following:
- I want to preserve the semantic structure of the first example
- I want to lay it out as per the second example
The semantically correct HTML would be to have the <header>
nested within the <article>
element, as the heading belongs to the article.
However, for CSS grid to work, the <header>
has to be a child of the grid container.
Is there a solution to this conflict?
Semantically correct, doesn't work
.layout {
display: grid;
grid-template-columns: 4fr 8fr;
grid-template-rows: auto 1fr;
gap: var(--grid-gap);
grid-template-areas:
"top top"
"menu content";
}
.layout nav {
border: 1px solid aqua;
grid-area: menu;
}
.layout main {
border: 1px solid green;
grid-area: content;
}
.layout header {
border: 1px solid red;
grid-area: top;
}
<div >
<nav>
<p>nav</p>
</nav>
<main>
<article>
<header>
<h1>Title</h1>
<p>Subtitle</p>
</header>
<p>Lorum ipsum content etc</p>
</article>
</main>
</div>
Semantically wrong, layout is correct
.layout {
display: grid;
grid-template-columns: 4fr 8fr;
grid-template-rows: auto 1fr;
gap: var(--grid-gap);
grid-template-areas:
"top top"
"menu content";
}
.layout nav {
border: 1px solid aqua;
grid-area: menu;
}
.layout main {
border: 1px solid green;
grid-area: content;
}
.layout header {
border: 1px solid red;
grid-area: top;
}
<div >
<nav>
<p>nav</p>
</nav>
<header>
<h1>Title</h1>
<p>Subtitle</p>
</header>
<main>
<article>
<p>Lorum ipsum content etc</p>
</article>
</main>
</div>
CodePudding user response:
You can use display: contents
.layout {
display: grid;
grid-template-columns: 4fr 8fr;
grid-template-rows: auto 1fr;
gap: var(--grid-gap);
grid-template-areas:
"top top"
"menu content";
}
.layout nav {
border: 1px solid aqua;
grid-area: menu;
}
.layout main,
.layout article {
display: contents;
}
.layout header {
border: 1px solid red;
grid-area: top;
}
.layout article > p {
grid-area: content;
border: 1px solid green;
margin: 0;
}
<div >
<nav>
<p>nav</p>
</nav>
<main>
<article>
<header>
<h1>Title</h1>
<p>Subtitle</p>
</header>
<p>Lorum ipsum content etc</p>
</article>
</main>
</div>
CodePudding user response:
Steve, your non-semantic approach is only non-semantic in as much as the <article>
is missing a heading... i.e. an <h2>
in this context.
There's no issue with every <header>
on your site having a unique <h1>
on every page. See MDN docs for header element
So I would use that approach.
CodePudding user response:
This is a tentative solution, but I'm sure about moving the navigation to within the article (the article could also have TOC navigation, so this feels wrong).
.layout {
display: grid;
grid-template-columns: 4fr 8fr;
grid-template-rows: auto 1fr;
gap: var(--grid-gap);
grid-template-areas:
"top top"
"menu content";
}
.layout nav {
border: 1px solid aqua;
grid-area: menu;
}
.layout div{
border: 1px solid green;
grid-area: content;
}
.layout header {
border: 1px solid red;
grid-area: top;
}
<article >
<nav>
<p>nav</p>
</nav>
<header>
<h1>Title</h1>
<p>Subtitle</p>
</header>
<div>
<p>Lorum ipsum content etc</p>
</div>
</article>