Skip to content

SilentImp/html

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

37 Commits
 
 
 
 
 
 
 
 

Repository files navigation

English | Українська | Pусский

HTML recommendations and best practices

Prefer fewer elements over more elements

It is harder to read, understand, and maintain large HTML blocks. Another reason — large DOM can influence performance.

Avoid

<div class="outer-margin">
  <div class="inner-padding">
    <p>We are the working dead</p>
  </div>
</div>

Prefer

<div class="description">
  <p>We are the working dead</p>
</div>

Prefer semantic elements over non-semantic

It is easier to read, understand, and maintain semantic HTML. Also, it's better for accessibility, for example, screen readers. And all kinds of robots and parsers. Including search engine spiders.

Avoid

<span>20 minutes ago.</span>

Prefer

<time datetime="2020-09-01T20:00:00">20 minutes ago.</time>

Prefer progressive enhancement and simplification over hacky or complex solutions

This way, we would get more stable and solid solutions while delivering the user's best possible experience.

Avoid

<p data-lines="3" class="abstract">Deadlights jack lad schooner scallywag dance the hempen jig carouser broadside cable strike colors. Bring a spring upon her cable holystone blow the man down spanker Shiver me timbers to go on account lookout wherry doubloon chase. Belay yo-ho-ho keelhaul squiffy black spot yardarm spyglass sheet transom heave to.</p>
<style>
  .abstract {
    width: 20rem;
    font-size: 0.75rem;
    line-height: 1rem;
  }
</style>
<script>
  const truncateElement = document.querySelector('.abstract');
  const truncateText=truncateElement.textContent;
  const lines = parseInt(truncateElement.dataset.lines);
  const getLineHeight = function(element) {
    const lineHeight = window.getComputedStyle(truncateElement)['line-height'];
    if (lineHeight === 'normal') {
      return 1.16 * parseFloat(window.getComputedStyle(truncateElement)['font-size']);
    } else {
      return parseFloat(lineHeight);
    }
  }
  truncateElement.innerHTML= truncateText;
  const truncateTextParts= truncateText.split(' ');
  const lineHeight = getLineHeight(truncateElement);
  
  while(lines * lineHeight < truncateElement.clientHeight) {
    truncateTextParts.pop();
    truncateElement.innerHTML = truncateTextParts.join(' ') + '…';
  }
</script>

Prefer

<p class="abstract">Deadlights jack lad schooner scallywag dance the hempen jig carouser broadside cable strike colors. Bring a spring upon her cable holystone blow the man down spanker Shiver me timbers to go on account lookout wherry doubloon chase. Belay yo-ho-ho keelhaul squiffy black spot yardarm spyglass sheet transom heave to.</p>
<style>
  .abstract {
    width: 20rem;
    font-size: 0.75rem;
    line-height: 1rem;
    max-height: 3rem;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
  }
</style>

Prefer native over custom

It next to impossible deliver better UX than one, which was provided by browser vendors. You don't have vendor resources, both time and human, and rarely see all underwater rocks and aspects related to the specific problem. Also, native elements usually have much better performance.

  1. It takes significantly more time to build a custom solution than use the native one.
  2. You can't integrate into system custom components in the same way native does.
  3. We can't control 3rd party dependencies.
  4. 3rd party libs often add size to the bundle.
  5. You can't predict where 3rd party will fail and don't know to what degree it accessible or support localization and internationalization.
  6. Native components don't require to load the JS bundle to work. So they are ready for interaction as soon as HTML loaded.
  7. The performance of a native component would generally be much better than a custom one.
  8. New features and updates arrive with browser update.
  9. Both user agents and developers would be more efficient in working with native solutions that custom one. Because it is standard, standards-based, well and widely known.

Avoid

<div class="details">
  <h2>We are the working dead</h2>
  <div class="details-content">
    Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro. De carne lumbering animata corpora quaeritis. Summus brains sit, morbo vel maleficia? De apocalypsi gorger omero undead survivor dictum mauris. Hi mindless mortuis soulless creaturas, imo evil stalking monstra adventus resi dentevil vultus comedat cerebella viventium. Qui animated corpse, cricket bat max brucks terribilem incessu zomby. The voodoo sacerdos flesh eater, suscitat mortuos comedere carnem virus. Zonbi tattered for solum oculi eorum defunctis go lum cerebro.
  </div>
</div>
<script>
  const toggler = (event) => {
    event.currentTarget.parentNode.classList.toggle("details-open");
  }
  document.querySelectorAll(".details").forEach((element) => {
    element.querySelector("h2").addEventListener("click", toggler);
  });
</script>
<style>
  .details h2 {
    all: unset;
  }
  .details h2::before {
    content: "►";
    margin-right: .5em;
    font-size: small;
    display: inline;
  }
  .details .details-content {
    display: none;
  }
  .details.details-open .details-content {
    display: block;
  }
  .details.details-open h2::before {
    content: "▼";
  }
</style>

Prefer

<details>
  <summary>We are the working dead</summary>
  Zombie Ipsum reversus ab viral inferno, nam rick grimes malum cerebro. De carne lumbering animata corpora quaeritis. Summus brains sit​​, morbo vel maleficia? De apocalypsi gorger omero undead survivor dictum mauris. Hi mindless mortuis soulless creaturas, imo evil stalking monstra adventus resi dentevil vultus comedat cerebella viventium. Qui animated corpse, cricket bat max brucks terribilem incessu zomby. The voodoo sacerdos flesh eater, suscitat mortuos comedere carnem virus. Zonbi tattered for solum oculi eorum defunctis go lum cerebro.
</details>

Prefer valid over invalid

Even if it looks fine in your browser, it can look broken entirely in users' one because error correction can work differently in different browsers. Also, it could be misleading for developers who will maintain this code. Potentially valid HTML could be better for SEO and accessibility.

Avoid

<dl>
  <h1>Dictionary</h1>

  <dt>Beast of Bodmin</dt>
  <dd>A large feline inhabiting Bodmin Moor.</dd>

  <dt>Morgawr</dt>
  <dd>A sea serpent.</dd>

  <dt>Owlman</dt>
  <dd>A giant owl-like creature.</dd>
</dl>

Prefer

<h1>Dictionary</h1>

<dl>
  <dt>Beast of Bodmin</dt>
  <dd>A large feline inhabiting Bodmin Moor.</dd>

  <dt>Morgawr</dt>
  <dd>A sea serpent.</dd>

  <dt>Owlman</dt>
  <dd>A giant owl-like creature.</dd>
</dl>

Prefer presentation separated from the structure

It is easier to maintain code where structure and presentation are separated. Easier to read and understand it. It is better from an accessibility perspective. Better for SEO.

Avoid

<nav class="breadcrumbs">
  <ol>
    <li><a href="/home/">Home</a></li>
    <li>&rarr;</li>
    <li><a href="/home/cluster/">Cluster</a></li>
    <li>&rarr;</li>
    <li>Service</li>
  </ol>
</nav>

<style>
  .breadcrumbs ol{
    display: flex;
    list-style: none;
    align-items: center;
  }
  .breadcrumbs li{
    margin: 0 5px 0 0;
  }
</style>

Prefer

<nav class="breadcrumbs">
  <ol>
    <li><a href="/home/">Home</a></li>
    <li><a href="/home/cluster/">Cluster</a></li>
    <li>Service</li>
  </ol>
</nav>

<style>
  .breadcrumbs ol{
    display: flex;
    list-style: none;
    align-items: center;
  }
  .breadcrumbs li:not(:last-child):after {
    content: "→";
    margin: 0 5px;
    pointer-events: none;
  }
</style>