Home > OS >  Pull title out with semantic HTML and CSS grid
Pull title out with semantic HTML and CSS grid

Time:11-12

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>

  • Related