Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What HTML element for semantic sidenotes?

I like to add responsive sidenotes to my blog posts. Responsive as in: hidden on small viewports, visible in the margin on wide viewports.

When hidden on small screens, a visible element ('link') is needed indicating there's more to read. My solution for this so far is:

<p>Some sentence with
<span class="sidenote" onclick="this.classList.toggle('active');">
  underlined text
  <span class="sidenote__content">
    Sidenote content
  </span>
</span>, which is clickable on small viewports.</p>

(with added line breaks for readability)

With CSS I add asterisks to both the underlined text and the sidenote content to visually connect them on large screens.

The problems with this solution are that the sidenote__content correct display depends on CSS. It's shown in readers like Pocket, with:

  • The sidenote content showing up mid sentence without any visual cues
  • No space between the underlined text and the sidenote content.

I'm hoping that there's a more semantic solution than simple spans. <aside> and <section> can't be used as they're block elements and can automatically close the parent's p element.

A solution could be to separate the sidenote content from the link. However I'd prefer to keep the set of sidenote and its link as one set or pair, so they can be inserted as such into posts. Splitting them up would require javascript logic to match links with their content and can cause maintenance issues when one half of the set is missing.

like image 573
kslstn Avatar asked Jul 30 '19 13:07

kslstn


3 Answers

The problems has 5 challenges:

  1. Pick the correct HTML element for the span that the sidenote refers to.
  2. Pick the correct HTML element for the content of the sidenote:
    • Sidenote content must be stylable
    • Sidenote content may contain clickable elements that can receive keyboard focus
  3. Make sure the chosen elements don't cause auto closing of their parent <p> tag.
  4. Make sure that reader modes and readers like Pocket show sidenote content in typographically acceptable way.
  5. Make sure sidenote content is read by screen readers, in a flow that makes sense.

** Solution to challenge 1** The appearance of the link is mainly presentational, as it provides no interaction on wide viewports. A <label> seems to be the tag best suited for this purpose. If the sidenote appears right next to the 'link' (and it will), I don't see the need or a purpose for including an href or id like with footnotes.

Solution to challenge 2 and 3

Use the <small> tag for the sidenote content (MDN, W3C).

Solution to challenge 4 and 5

Add spans with a space before and parentheses around the sidenote content for the unstyled appearance in reader modes. For screen readers, add 'sidenote: ' too. The result will look like:

(sidenote: here's a sidenote)

Hide those with CSS.

Solutions combined

HTML:

<!-- line breaks added for readability.
Remove them to avoid rendering of superfluous spaces. -->
<p> A paragraph with a
  <span class="sidenote">
    <label
      tabindex="0"
      title="The content of the sidenote."
      aria-describedby="sidenote-1"
      class="sidenote__button onclick="this.classList.toggle('active');"
      onKeypress="if(event.key === 'Enter' || event.key === ' '){event.preventDefault(); this.parentNode.classList.toggle('active');
    >
      clickable element
    </label>
    <small class="sidenote__content" >
      <span class="sidenote__content-parenthesis"> (sidenote: </span>
      The content of the sidenote.
      <span class="sidenote__content-parenthesis">)</span>
    </small>
  </span>
that can be clicked to show more details.
</p>

The content in .sidenote__parenthesis is for screen readers. Not all screen readers pronounce parentheses, hence the text sidenote: inside the first span with that class.

CSS:

.sidenote__content-parenthesis{
  // Hide from view, but not from screen readers.
  text-indent: -99999px;
}

@media (max-width: 1000px){
  .sidenote__content{
    // Hide from view, but not from screen readers.
    // The vertical position doesn't change, which is better for handling keyboard focus than 'text-indent: -99999px;'
    position: absolute;
    left: -99999px;
    top: auto;
  }
  .sidenote.active .sidenote__content{
    position: relative;
    left: auto;
  }
}

@media (min-width: 1000px){
  .sidenote__content{
    display: block;
    position: absolute;
    right: 0;
    margin-right: -300px;
    width: 200px;
  }
}
like image 154
kslstn Avatar answered Nov 05 '22 08:11

kslstn


From my point of view you should use the details tag.

The HTML Details Element () creates a disclosure widget in which information is visible only when the widget is toggled into an "open" state. A summary or label can be provided using the element.

The tag is intended, from a semantic point of view to do exactly what you need.

More info can be found on on MDN

The problem is that right now, Edge does not support the tag, but it is "in development" according to Microsoft.

like image 1
Cosmin Staicu Avatar answered Nov 05 '22 08:11

Cosmin Staicu


I think an abbreviation tag is what you're looking for

The <abbr> element is used along with a title attribute to associate a full-text explanation with an abbreviation or acronym. Website visitors do not see the text in the title attribute, but browsers, search engines, and assistive technologies do use this information [source]

See more:

  • View in JSFiddle
  • Abbreviations: Understanding Success Criterion from WCAG
  • MDN Usage Notes
like image 1
nntrn Avatar answered Nov 05 '22 08:11

nntrn