Skip to content

Latest commit

 

History

History
265 lines (224 loc) · 14.5 KB

README.ru.md

File metadata and controls

265 lines (224 loc) · 14.5 KB

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

HTML рекомендации и наилучшие практики

Предпочитайте меньшее количество элементов большему

Большие блоки HTML сложнее читать, понимать и поддерживать. Кроме того, большой DOM может негативно сказаться на производительности.

Нежелательно

<div class="outer-margin">
  <div class="inner-padding">
    <p>Мы рабы на галерах.</p>
  </div>
</div>

Предпочтительно

<div class="description">
  <p>Мы рабы на галерах.</p>
</div>

Cемантически корректные элементы предпочтительнее элементов общего назначения

Семантически корректный HTML легче читать, понимать и поддерживать. Это лучше с точки зрения доступности, например для программ чтения с экрана. Не говоря уже о роботах и парсерах всевозможных мастей, включая поисковых ботов.

Нежелательно

<span>20 минут назад.</span>

Предпочтительно

<time datetime="2020-09-01T20:00:00">20 минут назад.</time>

Прогрессивное улучшение и упрощение предпочтительнее, чем сложное или костыльное решение

Таким образом у нас будет максимально надежное решение, в то время как пользователь получит максимум от использования программного продукта.

Нежелательно

<p data-lines="3" class="abstract">Из сорока двух осужденных повстанцев, привезенных одновременно с Бладом на «Ямайском купце», двадцать пять купил Бишоп. Остальные были проданы другим плантаторам — в Спейгстаун и еще дальше на север. Какова была их судьба, Блад не знал; с рабами же Бишопа он общался все время и видел ужасные их страдания.</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>

Предпочтительно

<p class="abstract">Из сорока двух осужденных повстанцев, привезенных одновременно с Бладом на «Ямайском купце», двадцать пять купил Бишоп. Остальные были проданы другим плантаторам — в Спейгстаун и еще дальше на север. Какова была их судьба, Блад не знал; с рабами же Бишопа он общался все время и видел ужасные их страдания.</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>

Предпочитайте нативное кастомному

Практически невозможно создать UX лучше, чем тот, который обеспечивают разработчики браузеров. У вас нет их ресурсов, ни временных, ни человеческих. Нет возможности найти все подводные камни, связанные с решением конкретной проблемы. Не говоря уже о том, что нативные элементы обычно обладают значительно лучшей производительностью.

  1. Создание кастомного решения требует значительно больше времени, чем использование нативного.
  2. Кастомное решение нельзя так же глубоко интегрировать с системой, как нативное.
  3. Мы не контролируем сторонние зависимости.
  4. Сторонние решения часто негативно сказываются на размере бандла.
  5. Нельзя предсказать, где возникнут проблемы в стороннем решении, насколько оно доступно, что с локализацией и интернационализацией.
  6. Нативным элементам не нужна загрузка JS-бандлов. А это значит, что их можно использовать, как только загружен HTML.
  7. Производительность нативных элементов обычно значительно лучше, чем у кастомных.
  8. Новые возможности появляются с обновлением браузера.
  9. Разработчикам значительно легче работать с нативным решением, чем с кастомным. Нативное решение стандартизовано, а также хорошо и широко известно.

Нежелательно

<div class="details">
  <h2>Алчность</h2>
  <div class="details-content">
    Каузак равнодушным и циничным взглядом окинул корчившееся в судорогах тело своего вожака. Возможно, дело кончилось бы совсем не так, будь Левасер человеком другого склада. Но тогда, очевидно, и капитан Блад применил бы к нему другую тактику. Сейчас же люди Левасера не питали к нему ни любви, ни жалости. Единственным их побуждением была алчность. Блад искусно сыграл на этой черте их характера, обвинив капитана «Ла Фудр» в самом тяжком преступлении — в присвоении того, что могло быть обращено в золото и поделено между ними.
  </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>

Предпочтительно

<details>
  <summary>Алчность</summary>
  Каузак равнодушным и циничным взглядом окинул корчившееся в судорогах тело своего вожака. Возможно, дело кончилось бы совсем не так, будь Левасер человеком другого склада. Но тогда, очевидно, и капитан Блад применил бы к нему другую тактику. Сейчас же люди Левасера не питали к нему ни любви, ни жалости. Единственным их побуждением была алчность. Блад искусно сыграл на этой черте их характера, обвинив капитана «Ла Фудр» в самом тяжком преступлении — в присвоении того, что могло быть обращено в золото и поделено между ними.
</details>

Валидный код предпочтительнее невалидного

Даже если в вашем браузере всё выглядит хорошо, в браузере пользователя страница может выглядеть сломанной, так как коррекция ошибок работает по-разному в разных браузерах. Кроме того, это может сбить с толку разработчиков, которые будут поддерживать этот код. Потенциально валидный HTML может быть лучше с точки зрения поисковой оптимизации и доступности.

Нежелательно

<dl>
  <h1>Словарь</h1>

  <dt>Секстант</dt>
  <dd>Навигационный измерительный инструмент, используемый для определения высоты Солнца и других космических объектов над горизонтом</dd>

  <dt>Ванты</dt>
  <dd>Снасти стоячего такелажа, которыми укрепляются мачты, стеньги и брам-стеньги с бортов судна</dd>

  <dt>Стаксель</dt>
  <dd>Треугольный парус</dd>
</dl>

Предпочтительно

<h1>Словарь</h1>

<dl>
  <dt>Секстант</dt>
  <dd>Навигационный измерительный инструмент, используемый для определения высоты Солнца и других космических объектов над горизонтом</dd>

  <dt>Ванты</dt>
  <dd>Снасти стоячего такелажа, которыми укрепляются мачты, стеньги и брам-стеньги с бортов судна</dd>

  <dt>Стаксель</dt>
  <dd>Треугольный парус</dd>
</dl>

Предпочтительно разделять структуру и представление

Легче поддерживать код, в котором структура и представление разделены. Его проще читать и понимать. Это лучше с точки зрения доступности. Лучше с точки зрения поисковой оптимизации.

Нежелательно

<nav class="breadcrumbs">
  <ol>
    <li><a href="/home/">Главная</a></li>
    <li>&rarr;</li>
    <li><a href="/home/cluster/">Кластер</a></li>
    <li>&rarr;</li>
    <li>Сервис</li>
  </ol>
</nav>

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

Предпочтительно

<nav class="breadcrumbs">
  <ol>
    <li><a href="/home/">Главная</a></li>
    <li><a href="/home/cluster/">Кластер</a></li>
    <li>Сервис</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>