2
\$\begingroup\$

Background

I added a few items to a codepen that displayed a list of beers. One of them was the citation of the brewer who gave tips. Previously the tips were just generated into a <p> but now I have wrapped it inside a blockquote

Code

<blockquote>
  <p>
    <span class="bright">Tips from the brewer:</span> 
    "{{ beer.tips }}"
    <cite>
      &ndash; {{ beer.contributor }} 
      <a style="color: white" :href="`https://www.twitter.com/${beer.twitter}`" target="_blank">{{beer.twitter}}</a>
    </cite>
  </p>
</blockquote>  

Demo

My working demo is available on CodePen

enter image description here

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

I don't know Vue.js then I won't comment about that part.

Overall structure seems OK but maybe few things may be improved. The most obvious one is usage of CSS classes to apply styling without conveying any extra semantic. In your code bright class is applied to text to make it visually distinguishable but:

  • Name describes the applied style instead of its meaning. If you later decide to use dimmed text then you also need to change class name (or to keep them out-of-sync).
  • It does not help screen readers to understand what its content is: effectively just a sub-title.
  • It's applied both to <p>, <span> and...<h3> reinforcing its usage as mere styling instead of carrying any semantic value.

For the tagline I'd use a subheader or a specific class:

<h2>{{ beer.name }}</h2>
<h2 class="subheader">{{ beer.tagline }}</h2>

Alternatively:

<h2>{{ beer.name }}</h2>
<p class="tagline">{{ beer.tagline }}</p>

Note that you can use mixins to avoid CSS duplication then there is no reason to re-use the same class multiple times. Note that you're using <section> for the outer container and there it has little meaning, you may refactor your HTML code to be more HTML5ish:

<div id="app">
  <header>...</header>
  <main>
    <div v-if="beers.length === 0" class="loading">Loading...</div>
    <article v-for="beer in beers">
      <aside>
        <img :src="beer.img" height="350" />
      </aside>
      <hgroup>
        <h2>{{ beer.name }}</h2>
        <h2 class="subheader">{{ beer.tagline }}</h2>
      </hgroup>

Note that I'm using <main> as outer container and <article> with its own <hgroup>. What's for? Screen readers (and search engines) now know what each item is, the element conveys a semantic value and you can, also, directly use it in your CSS. Image is actually a side content of the <article> then you can use <aside>.

Refactored this we should look at the other bright elements. Your paragraphs are some text with a title. Exactly what <dl> is for:

<dl>
    <dt>Description:<dt>
    <dd>{{ beer.desc }}</dd>

    <dt>Tips from the brewer:<dt>
    <dd>...</dd>
</dl>

We finally arrived to the <blockquote>. In this case you're quoting a small inline tweet, also note that usually <blockquote> does not contain any extraneous content (besides a <footer> with the <cite> element). What I think is more appropriate for this citations (which are not a separate standalone block of text) is the <q> element:

<dd>
    <q cite="...">{{ beer.tips }}</q>
</dd>

Few important things here: quotation marks should not be part of your HTML, browser already does it (using the appropriate symbols for the current language - which BTW you should add to your HTML). Also note the cite attribute to reference the source (if it's a twitter than you have an URL to link). <cite> element can follow inside <dd>.

You can (and probably should) style <h3> directly without using bright. You may also like (if required by your CSS) to wrap each section with <section> (in this case you may have <hgroup> instead of the <dl> list).

You may consider to use microdata for some of your content (beer name and author of the tweet).

JS local variables in addBeer() can be const instead of let.


I see absolutely no reason (for this kind of content) to do not support accessibility. It's more complex than one paragraph in this questionthen just to refer to official W3C documentation.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.