Callouts and inlays and headings

January 22, 2024 | Work: 2024-01

The client had requested some small ad-promo like teasers – what we would call “callouts” when I worked in Marketing & Communications, years ago. Callouts were typically 200-300px wide, square, dominantly a graphic, and were a clickable link to some call-to-action. Simple, functional, direct.

One of the callouts we needed was on the homepage. Specifically, the client wanted callouts that would display different medium each time the page loaded. This is tricky to do with Jekyll (it will require JS) and is sadly a limitation of using a static site generator, but we agreed that for now at least they could be static callouts and be made dynamic later.

Structuring the content

I went through a few iterations, design-wise, but I knew roughly the structure of the content that I wanted.

Semantic HTML has a few contextual meanings (meta-semantics, if you will):

Semantics refers to the meaning of a piece of code — for example “what effect does running that line of JavaScript have?”, or “what purpose or role does that HTML element have” (rather than “what does it look like?”.)

To put it another way – it means using a hammer as a hammer and not as a shim to prop up a table with a damaged leg, just because it happens to be the right size. I would call that either “clever” or “kludge” depending on how effective it was, but both cases are non-semantic usage.

In HTML, for example, the h1 element is a semantic element, which gives the text it wraps around the role (or meaning) of “a top level heading on your page.”

Exactly how to use heading tags has actually been a somewhat contentious discussion topic in web circles, at various points in history. These disagreements tend to often coincide with periods where things overall are in a place of ephemeral stability, which has reinforced my belief that we are all problem-solvers in search of problems.

Digression into the history of heading usage in document structure

~That said, I think it would be fair to say that while there are several acceptable ways to use headings~ Today I learned! On the MDN page for [heading elements]](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Heading_Elements), it says:

While using multiple <h1> elements on one page is allowed by the HTML standard (as long as they are not nested), this is not considered a best practice. A page should generally have a single <h1> element that describes the content of the page (similar to the document’s element).

So back in the beforetimes, I was on team “one H1 for the document, representing the site, a single H2 representing the page title, and then all article content begins at <h3>. This new recommendation is suggesting that the (solitary) H1 be the page title and then on down from there. I actually like this even more and think it feels more intuitive.

with a followup:

Nesting multiple <h1> elements in nested sectioning elements was allowed in older versions of the HTML standard. However, this was never considered a best practice and is now non-conforming.

So back in the beforetimes, during a blissful lull when SCSS was first gaining traction, BEM was a new hotness, and we were somewhere between the dominance of jQuery and the emergence of Reactive pattern frontend frameworks (React, Angular, Ember, etc.), there was a contingent of people that advocated for multiple <h1> tags in a single page. ie. documents like this:

<body>
  <h1>Site title</h1>
  <header>
    <h1>Primary Nav</h2>
    <nav>{ ... }</nav>
  </header>
  <main>
    <h1>Page Title</h1>
    <article>
      <h2>Article headline</h2>
      { ... }
    </article>
  </main>
  <footer>
    <h1>Site name again</h1>
    <nav>{ ... }</nav>
  </footer>
</body>

The premise is that at each primary-document level (header, main, footer), the heading levels can reset. This always bugged me, but I tried to accommodate it to a point. There is a fantastic history, including recommendations against the “lots of H1s” approach, in the article “There is no document outline”.

Conversely, moz.com sez (date of article indeterminate):

Can a page have multiple H1 tags? Yes, anything is possible! However, generally speaking, your content should have a single H1 at the top of the page. In some circumstances, where a page truly covers multiple high-level topics, multiple H1s can be used. Google’s John Muller has stated that it will not penalize pages with multiple H1 tags. However, we recommend sticking to one H1 tag per page in order to keep your content topically focused, to prevent confusion for users of all abilities and issues with keyword cannibalization on your site more generally.

This seems contrary to the relatively-recent advisory regarding the removal of the document outline algorithm.

The best way to test things out is to navigate the siste using assistive technology or use an accessibility auditing program.

I’m glad to have found this recommendation because it aligns with what my gut says the should be done with the headings, but I will need to actually go back and fix a few sites now (including this one)! 😥

Back to callouts

So!! I know the semantic structure I wanted was roughly this:

<a class="callout">
  <aside>
    <header>text at top</header>
    <p>optional middle text</p>
    <footer>text at bottom</footer>
  </aside>
</a>

The <aside> tag was chosen because:

The <aside> HTML element represents a portion of a document whose content is only indirectly related to the document’s main content. Asides are frequently presented as sidebars or call-out boxes.

I’m not loving the solitary <a> wrapper around it, but I would rather do it this way than use JS to make it clickable. (Also, initially I had <h1> tags inside of that <header> but…)

The <header> tag is treated as non-banner landmark when it’s a descendant of an <aside> tag. Banner landmarks have special functions in assistive technology and document interpretation. So using it here, since it’s a descendant of an <aside>, it’s “safe” to use in that it won’t appear to be more prominent than it should be.

Styling

The MDN notes on semantics of CSS say:

In CSS, consider styling a list with li elements representing different types of fruits. Would you know what part of the DOM is being selected with div > ul > li, or .fruits__item?

There are different ways to interpret this, I suppose. For me, it begins with a semantic understanding of what the HTML tags mean when they are used semantically. From this, if I can define my CSS selectors using those semantic HTML tags first, then I don’t need to use classes.

In other words, I only use classes or other specificity-selectors when it is absolutely necessary because I can’t differentiate the tag any other way.

mk1 Initial code

Using the above code:

<a class="callout">
  <aside>
    <header>text at top</header>
    <p>optional middle text</p>
    <footer>text at bottom</footer>
  </aside>
</a>

I only need to specify callout as the class in the <a> tag, because underneath that I can root all further stylings under that node.

a.callout {
  aside {
    header { }
    p { }
    footer { }
  }
}

As it stands, that HTML displays like this:

mk 1

mk2 Adding a background

By default, <a> tags are display: inline, and have no implicit width or height, so the background won’t show up. I’ll make that display: block for now, then I can slap a background into the callout and make it look mostly done:

  <a class="callout" style="background: url('/assets/img/post_images/2024-01-10-space-bg.jpg');">
    <aside>
      <header>text at top</header>
      <p>optional middle text</p>
      <footer>text at bottom</footer>
    </aside>
  </a>
mk 2

mk3 Spacing the text out better with flex

I absolutely love flexbox styling. I’m going to apply that here:

a.callout {
  aside {
    display: flex;
    flex-direction: column;
    justify-content: space-evenly;
    min-height: 250px;
    max-width: 300px;
  }
}
mk 3

Getting there!

Let’s give the header and footer a bit more breathing room and make the text more prominent. I’ll use real text now too.

a.callout {
  aside {
    display: flex;
    flex-direction: column;
    justify-content: space-evenly;
    min-height: 250px;
    max-width: 300px;

    header,
    footer {
      margin: 0.5rem;
      font-size: 1.5rem;
      color: white;
      font-weight: bold;
    }
  }
}
mk 4

mk5 Tweak middle text

The inside text should be centered and have more breathign room as well:

a.callout {
  aside {
    display: flex;
    flex-direction: column;
    justify-content: space-evenly;
    min-height: 250px;
    max-width: 300px;

    p {
      margin: 0 auto;
      padding: 1rem;
      color: #CCC;
      font-size: 1.2rem;
      font-family: courier;
    }

    header,
    footer {
      margin: 0.5rem;
      font-size: 1.5rem;
      color: white;
      font-weight: bold;
    }
    header {
      text-align: left;
    }
    footer {
      text-align: right;
    }
  }
}
mk 5

mk6 Add hover effects

I don’t like the default underline when it hovers. It’s not noticeable enough. Let’s make the text subtly change color instead.

a.callout {
  color: white;
  transition: 0.75s;

  &:hover {
    text-decoration: none !important;
    color: red;
    transition: 0.75s;
  }
  aside {
    display: flex;
    flex-direction: column;
    justify-content: space-evenly;
    min-height: 250px;
    max-width: 300px;

    p {
      margin: 0 auto;
      padding: 1rem;
      color: #CCC;
      font-size: 1.2rem;
      font-family: courier;
    }

    header,
    footer {
      margin: 0.5rem;
      font-size: 1.5rem;
      font-weight: bold;
    }
    header {
      text-align: left;
    }
    footer {
      text-align: right;
    }
  }
}
mk 6

mk6.5 Add really cool hover effects

Let’s make the background shift when you hover over it. We can do this by changing the background-position on hover, with a transition duration set for it.

a.callout {
  color: white;
  text-decoration: none;

  aside {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    min-height: 250px;
    max-width: 300px;
    background: url('/assets/img/post_images/2024-01-10-space-bg.jpg');
    background-position: left top;

    p {
      margin: 0 auto;
      padding: 1rem;
      color: #CCC;
      font-size: 1.2rem;
      font-family: courier;
    }

    header,
    footer {
      margin: 0.5rem;
      font-size: 1.5rem;
      font-weight: bold;
    }
    header {
      text-align: left;
    }
    footer {
      text-align: right;
    }
  }

  &:hover {
    text-decoration: none !important;
    color: red;

    aside {
      background-position: right bottom;
      transition: 6s;
    }
  }
}
mk 6

Responsiveness

There was a final pass of responsiveness that I can’t replicate here because I don’t have all the responsiveness classes copied over to this site. But the idea is to use media queries to make the callouts display in a stacked or row formation depending on the width of the viewport.