Расскажу Вам о том, как использовать чудо-юдо под названием "Кастомные HTML-теги" понятным языком.

Предисловие

Причины создания данной статьи таковы:

  • Никто, за редчайшими исключениями, не использует кастомные теги, не говоря уже про их API. А очень зря.

  • Почти весь материал по ним либо на английском языке, либо написан так, что лучше бы не писали. А иногда и то и другое.

Я попробую изложить суть кастомных html-элементов наиболее доступно.

Просто используйте их!

<div class='my-block' data-block-number="15">
  <div class='my-block__header'>
    <span class='my-block__title'>Заголовок</span>
  </div>

  <div class='my-block__main my-block__main--smaller'>
    <div class='centring'>
      <p class='my-block__content'>
        ...
      </p>
    <div class='my-block__decor'>ΫΫΫ</div>
    </div>
  </div>

  <div class='my-block__footer'>
    <span>@ Права не защищены.</span>
  </div>
</div>

Красивая портянка, не правда ли? Предлагаю сделать её проще и понятней:

<my-block block-number="15">
  <my-block-header>
    <my-block-title>Заголовок</my-block-title>
  </my-block-header>


  <my-block-main class='smaller'>
    <centered-content>
      <p class='content'>
        ...
      </p>
      <my-block-decor>ΫΫΫ</my-block-decor>
    </centered-content>
  </my-block-main>

  <my-block-footer>
    <span>@ Права не защищены.</span>
  </my-block-footer>
</my-block>

Красиво, не правда ли? А ещё, для того чтобы этот код работал, вам не нужно делать ничего. Он работает «из коробки». Никаких React-ов и уличной магии.
Вы можете поиграть с кастомными html‑элементами в этом codepen.

Подробнее

Почти сразу оговорюсь об их поддержке. На момент написания статьи: полная поддержка — 79%, частичная — 97.3%. Вы можете смело использовать кастомные html‑элементы, просто игнорируя функции, что описаны в разделе «О модифицированных встроенных элементах», пользуясь поддержкой в 97.3%. И не волнуйтесь, до того раздела я использовать плохо поддерживаемые функции не буду.

Уверен, что вы периодически используете теги div и span когда создаёте разметку сайта. Эти теги наиболее ходовые, потому как арсенал зарезервированных html-тегов не велик (о большинстве из них и вовсе не догадываются), а делать структуру из чего-то надо. Сами по себе теги div и span не представляют из себя ничто, ни семантики, ни функционала. Отличие лишь в том, что div - блочный, а span - строчный.

Чтобы не утонуть в коллизиях, например, в процессе стилизации, к ним применяют классы и уже через них стилизуют: 

<div class='my-block'></div>

В 80% случаев (цифры взяты навскидку) кастомные html-элементы позволяют заменить использование класса и даже атрибута, защищая уникальным именем от коллизий: 

<my-block></my-block> 

А ещё, это банально читабельней и короче.

Полезно знать

  • Для работы кастомных html-тегов вам не требуется ничего, кроме браузера.

  • Стили применяются к ним, как к обычным тегам с соответствующей специфичностью.

  • JavaScript работает с ними, как и с другими элементами - “из коробки”.

  • Имя кастомного тега должно иметь дефис где-то внутри названия (ни в начале, ни в конце).

  • Кастомные теги не могут быть самозакрывающимися, как например img.

  • Задавать атрибуты для кастомных тегов можно без data- префикса.

Семантика и стили

С точки зрения семантики, стилей и функционала кастомные html-элементы равноценны тегу span целиком и полностью. То бишь не имеют семантики и стилей. Если вместо них использовать нагромождение span-ов, с этой точки зрения, ничего не не изменится.
Да да, все ваши кастомные элементы изначально строчные. Учитывайте это при стилизации.

Расширенное использование или JS API

Впрочем, это не всё. Кастомные html-элементы могут больше, чем просто теги.
К слову, ошибка почти всех материалов по этой теме в том, что начинают они рассказ по теме именно с этой части, а не той, что выше.

Вы когда нибудь задумывались о том, как работает элемент dialog или details? Самое время задуматься, ибо вы можете сделать из кастомных html-элементов нечто схожее, а то и большее по масштабу и сложности. Для этого сделали API, который сейчас рассмотрим.
Использование API не обязательно, они и без него работают, с.м примеры выше.

Чтобы работать с API, необходимо немного потанцевать с бубном написать следующий код, где расписано всё, с чем предстоит работать:
(все методы - не обязательны)

/** Имя Вашего класса может быть произвольным. */
class HTMLMyElement extends HTMLElement {
  /** Заменяет функцию observedAttributes(), с.м ниже. */
  static observedAttributes = [/* имена атрибутов */]
  
  constructor() {
    super()
  }

  /**
   * Срабатывает всякий раз, когда элемент попадает в документ (включая инициализацию).
   */
  connectedCallback() { }
  
  /**
   * Срабатывает всякий раз, когда элемент удаляется из документа.
   */
  disconnectedCallback() { }

  /**
   * С его помощью можно задать группу атрибутов, изменение которых вызовет метод ниже.
   */
  static get observedAttributes() {
    return [/* массив имён атрибутов */]
  }

  /**
   * Срабатывает всякий раз при изменении одного из атрибутов перечисленных в observedAttributes.
   */
  attributeChangedCallback(name, oldValue, newValue) { }

  /**
   * Срабатывает всякий раз при перемещении элемента в иной документ (почти никогда не нужен).
   */
  adoptedCallback() {
  }

  // Произвольное количество иных методов и всеразличных свойств.
}

/** Регистрация элемента. Без этого ничего толком работать не будет. */
customElements.define('my-element', HTMLMyElement)

После того, как вы напишете вышеуказанный код, экземпляр класса будет создан для каждого my-element в вашем документе и для них будут работать методы.

Разберу каждый метод по отдельности:

  • constructor()
    Вызывается первым из всей братии. Крайне желательно вызвать внутри функцию super() и лишь потом писать оставшийся внутренний код.
    В нём можно задать значения по умолчанию (например, задать стили), зарегистрировать прослушиватели событий и даже построить коммунизм создать теневую разметку
    В нём не следует проверять атрибуты элемента или дочерние элементы (их на момент срабатывания ещё может не быть), а также добавлять новые атрибуты или дочерние элементы.

  • connectedCallback()
    Срабатывает всякий раз, когда элемент попадает в документ (включая инициализацию/чтение документа).
    Согласно спецификации, всю настройку/инициализацию элемента (атрибуты, работу с детишками и иже с ними) нужно проводить именно в этом методе, а не в конструкторе.

  • disconnectedCallback()
    Срабатывает всякий раз, когда элемент удаляется из документа. Здесь можно взять и указать, что произойдёт в этих случаях.

  • adoptedCallback()
    Срабатывает всякий раз при перемещении элемента в иной документ (почти никогда не нужен).

  • observedAttributes
    Это может быть функция:
    static get observedAttributes() {
        return [/* массив имён атрибутов */]
    }
    А может быть свойство:
    static observedAttributes = [/* массив имён атрибутов */]

    Через него можно задать атрибуты, изменение которых вызывает attributeChangedCallback().

  • attributeChangedCallback(name, oldValue, newValue)
    Срабатывает всякий раз при изменении одного из атрибутов элемента, перечисленных в observedAttributes.
    Получает имя изменяемого атрибута, старое и новое значения.

Полезно знать о JS API

Во первых: можно ссылаться на текущий кастомный элемент, используя this:

connectedCallback() {    
  this.hasAttribute('some-attr')
}

Во вторых: рендеринг элементов происходит от родителей к потомкам сверху вниз. Попытки обратиться к потомкам через конструктор или connectedCallback() чреваты ошибками. Чтобы избежать этого, рекомендую использовать вспомогательные методы и событие DOMContentLoaded:

connectedCallback() {
  // некий код...

  document.addEventListener('DOMContentLoaded', this.init.bind(this))
}
init() {
  // Запуститься только тогда, когда будет загружен и проанализирован весь DOM.
  // Манипуляции с потомками и так далее.
}

Пример использования JS API

class MyCustomElement extends HTMLElement {
  static observedAttributes = ['attr-1', 'attr-2'];

  constructor() {
    super();
  }

  connectedCallback() {
    console.log('Кастомный элемент добавлен на страницу!');
    this.role = 'tabpanel'

    document.addEventListener('DOMContentLoaded', this.init.bind(this))
  }
  init() {
    // Тут можно спокойно обращаться к потомкам.
    for (let child of this.children) {
      child.setAttribute('data-tab-item', '')
    }
  }

  disconnectedCallback() {
    console.log('Кастомный элемент был бесчеловечно... удалён.');
  }

  adoptedCallback() {
    console.log('Кастомный элемент был перемещён в глубинные глубины иного документа.');
  }

  attributeChangedCallback(name, oldValue, newValue) {
    console.log(`Атрибут ${name} взял и изменился.`);
    
    switch (name) {
      case 'attr-1':
        if (newValue == 'true') {
          this.setAttribute('attr-2', 'false')
        }
        break;
    }
  }
}

customElements.define('my-custom-element', MyCustomElement);

О модифицированных встроенных элементах

Спецификация подразумевает два типа кастомных html-элементов:

  • Автономные элементы.

  • Кастомизированные встроенные элементы.

Всё, что описывалось выше не учитывало кастомизированные встроенные элементы, автор их игнорировал до сего момента. 
Вкратце: второй вариант использования позволяет модифицировать встроенные по умолчанию элементы, такие как button и section , расширяя их функционал.

Для этого предполагается использование атрибута is:

<button is='hello-button'>...</button>

Инициализация класса видоизменяется и выглядит так:

class HelloButton extends HTMLButtonElement 

А регистрация элемента:

customElements.define('hello-button', HelloButton, {extends: 'button'})

О кастомизации встроенных элементов можно было бы порассуждать, но есть нюанс: их поддержка оставляет желать лучшего. Нет, ну что там, 79% на момент написания статьи - казалось бы, ещё чучуть и можно использовать! Но у разработчиков Safari есть своё, и ещё раз своё мнение о том, что реализовать нужно, а что - нет.
Рассчитывать, что на них снизойдёт благодать и они изменят своё решение не стоит, ибо кастомные html-элементы реализованы уже давно (года с 2016 в отдельных браузерах), а их решение по прежнему неизменно.
Безусловно, вы можете воспользоваться полифилом, но это уже не уровень “из коробки”.

Итого

Арсенал html‑тегов неплох, но его следует расширить. Используя кастомные теги вы можете избавится от львиной доли классов в вашей разметке, заменив их на уникальные имена тегов (особенно хорошо это будет смотреться в рамках Systematic CSS, где элементы блока обозначаются без классов).
Полезны будут и атрибуты, что можно задать без data- префикса, может заменить модификаторы в части случаев.

Если же вы решитесь сделать нечто вроде слайдера или табов, кастомные теги и их API позволит сделать это чрезвычайно гибко и удобно (автор подтверждает, скрипты для табов стали раза в два меньше и раза в три проще), сделав на уровне встроенных элементов вроде dialog.

Существует и возможность кастомизировать встроенные по-умолчанию элементы, но пока это не поддерживается в Safari и на это нет даже намёков, наоборот, есть признаки того, что это не будет реализовано никогда.

Не стесняйтесь использовать кастомные html-элементы, это легко, весело, полезно и поддержка у них хорошая.

Источники

Комментарии (38)


  1. alexnozer
    14.01.2024 16:10
    +8

    Статья о веб-компонентах. Лайк!

    Сделаю несколько уточнений.

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

    Это кажется так. Их используют, просто об этом никто не знает. Ну и используют их крупные компании в основном. Из примеров: интерфейс Chrome, Edge и Firefox, включая DevTools, YouTube, VS Code, GitHub, Photoshop Web, MSN, Windows Store, Bing, Epic Games Store и т.д.

    Красивая портянка, не правда ли? Предлагаю сделать её проще и понятней

    Замена div + class на кастомный элемент может и сделало код читабельнее и понятнее, но семантика потеряна. Все же заголовок должен быть h*, вводная часть в header, копирайт в footer, а сам компонент - section, article, aside или чем-то ещё в зависимости от контекста. Семантика нужна поисковым роботам, ассистивным технологиям (для доступности), плагинам и т.д.

    Даже если это div-ы, у которых нет семантики, роботы все равно умеют анализировать их по другим эвристикам. Я думаю, что за столько лет существования миллиардов сайтов с div-ами, роботов научили определять контент, в том числе по классам, вложенности, каким-то повторяющимся паттернам, даже с div. Утверждать это на 100% я не могу, никто не знает алгоритмов. Но я думаю, что это так.

    Отличие лишь в том, что div - блочный, а span - строчный.

    div - потоковый и ощутимый (Flow и Palpable), а span - потоковый, фразовый и ощутимый (Flow, Phrasing и Palpable). Блочный и строчный - это термины из HTML4, в HTML5 их упразднили в пользу категорий и контентных моделей.

    С точки зрения семантики, стилей и функционала кастомные html-элементы равноценны тегу span целиком и полностью.

    Не совсем. С точки зрения категорий - да. С точки зрения базовых стилей - да (оба display: inline). Но у кастомных элементов контентная модель - прозрачная, а у span - фразовый контент. Это значит, что в span нельзя вложить div, ul, section (любой не фразовый контент), а в кастомный элемент можно вложить все, что можно в его родителя.


  1. sshikov
    14.01.2024 16:10
    +1

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

    Насколько я помню, кастомные тэги были одной из ключевых концепций в Google Polymer. Ну т.е. не то чтобы их совсем-совсем не применяли, нет. Но во второй уже кажется версии все изменилось. И да, я согласен, что зря.


  1. delphinpro
    14.01.2024 16:10
    +4

    Кастомный тег ради красивого (сомнительно) именования – это так себе идея.

    Когда речь идёт о полноценном использовании web-компонентов (включая теневой DOM) – это совсем другое дело. Но об этом не написано.


    1. LeninIvanov Автор
      14.01.2024 16:10
      +3

      Думайте над прочтённым, я привёл аргументы в пользу того, зачем их использовать.
      1: Кастомные теги в ~80% случаев заменяют классы, особенно при использовании атрибутов. Это не столько красиво, сколько короче.
      И да, дублирование кода (даже такими вещами как атрибут class) - не есть хорошо, хоть и терпимо. Логика тут такая же, как и при необязательных точках с запятой в JS.
      2: "Но об этом не написано" - читайте прежде чем писать или очки снимите. Я и про JS API упомянул, и про теневой DOM, и про кастомизацию встроенных тегов.


      1. delphinpro
        14.01.2024 16:10

        1. Вопрос о целесообразности остается открытым. Семантической нагрузки кастомные теги не несут. Экономия на символах тоже выглядит сомнительной. Сейчас вы сэкономили 2 килобайта, а потом подключили библиотеку на 50к. Ну и в чем смысл?
          Ремарку о дублировании кода в виде атрибутов class я честно говоря не понял. Вы говорите именно о названии атрибута, или о его содержимом? В первом случае это какой-то бред, во втором я не вижу разницы между дублированием в коде названия класса и дублированием названия тега.

        2. Если я сниму очки, то вообще не смогу ничего прочитать, к сожалению.
          Я читал вашу статью, будьте уверены. Но сейчас все же выполнил поиск по странице. Слова "web", "shadow", "DOM" и "компонент" в вашей статье не встречаются. Они появились только в комментариях.


        1. LeninIvanov Автор
          14.01.2024 16:10

          1: Вопрос о целесообразности - закрыт. Использовать кастомные теги без семантики заместо вместо div-ов и span-ов без семантики, что бы не было необходимости прописывать классы. Если есть встроенные теги с семантикой - следует использовать их. Я не писал о том, что и про них нужно забыть.
          Смысл не в экономии килобайт (вы серьёзно подумали, что для работы кастомных тегов нужна библиотека?), смысл в том, что бы писать меньше (атрибут class, как и data-* не используется), а значит - быстрее. Нет, правда, почему я должен доносить настолько очевидные вещи!?
          Бонусом частичное решение проблем каскада (переопределить тег классом проще, чем другой класс).
          Если вы и в правду не смогли понять, почему теги предпочтительней классов в ~80% случаев, перечитайте статью, вас интересует первая половина.
          2: Прошу, наденьте очки обратно и удалите затемняющий слой, или что там у вас на очках - вы даже с ними плохо видите.
          Прочтите статью ЦЕЛИКОМ, вас интересует раздел "Расширенное использование или JS API". Уделите время и вы всё найдёте.

          И да, вы не нашли слово "shadow" в тексте потому, что я использовал вместо него слово "теневую" (теневую разметку). Пересмотрите свой опыт использования поиска по словам.


          1. delphinpro
            14.01.2024 16:10

            Нет, все же вопрос закрыт только в вашей голове. Совершенно не понятно, почему нужно уходить от классов, и почему это вдруг дата-атрибуты станут не нужными?
            У каскада вообще нет никаких проблем. Может быть вы имели ввиду специфичность селекторов?

            В комментариях правильно отметили, и я это же пытаюсь вам донести – в кастомных тегах самим по себе нет смысла, они не нужны. Смысл есть в web-компонентах, инкапсулирующих в себе некую функциональность. А кастомные теги являются всего лишь частью этой подсистемы.

            Прошу, наденьте очки обратно 

            Видимо, вы не догадались, что у меня плохое зрение. Иначе ваша реплика выглядит хамством.


            1. LeninIvanov Автор
              14.01.2024 16:10

              Что же, попробую ещё раз.

              Значительную часть структуры сайтов делают не из семантических тегов, а из тегов общего назначения - div, span, даже section и article туда можно отнести.

              Что бы использовать их в целях стилизации и не “промахнуться", дав стили другому тегу, для них назначают классы и даже атрибуты. Про результату имеется нагромождение div и span, смысл которых понятен только из их класса.

              Кастомные теги, если не использовать их API, позволяют использовать их уникальное имя для стилизации и прочего, минуя необходимость писать атрибут class, и в некоторых случаях data-*. Уникальное имя выполняет функции выделения блока среди других, а за счёт отсутствия необходимости писать атрибуты для этого позволяет писать разметку быстрее, а сама разметка становится короче.

              Ты же логика и с атрибутами - порой проще написать атрибут без data-*, чём подписать класс, а эффект будет такой же.


              1. delphinpro
                14.01.2024 16:10
                -1

                Вы одно и то же повторяете. Лучше объясните нормально, чем вам так насолили классы? Если это ваше субъективное отторжение, так и напишите. В противном случае покажите, какие реальные проблемы решает перенос имен селекторов из классов в теги.


          1. delphinpro
            14.01.2024 16:10

            Придумал!

            С кастомными тегами селектор :nth-of-type можно заставить работать так, как ожидают от него многие новички =) Больше ничего в голову не приходит.


  1. LeninIvanov Автор
    14.01.2024 16:10
    +1

    Прошу прощения у автора комментария, который задал вопрос про SEO, я тупо промахнулся и вместо написания ответа отклонил его. :с

    Касаемо влияния кастомных тегов на SEO и подобного - они равнозначны span, а значит семантики не имеют. Роботы их не учитывают.
    Безусловно, им можно задать семантику через атрибут role, но это сомнительно. Если есть возможность - используйте семантические встроенные теги вместо кастомных.


  1. noavarice
    14.01.2024 16:10

    Я не фронтенд, только пишу свое приложение с фронтом и как-то получилось, что пишу на web components (через Lit). Я так понимаю, что web components хороши для дизайн-систем - создания каких-то базовых компонентов, которые снаружи стилизовать почти невозможно. В частности, нельзя адекватно какие-нибудь иконки прикрутить через внешний CSS. То есть, видимо, для создания приложений надо использовать комбинацию web components (для всяких примитивов - кнопок/табов/прочего) и фреймворка (для компонентов с бизнес-логикой)?


    1. LeninIvanov Автор
      14.01.2024 16:10

      Не в курсе про Lit, но использование веб-компонентов вообще необязательно. Существует нескромный арсенал встроенных, как семантических тегов (вроде section, hr и header) так и возможность стилизовать общие теги (div, span) через классы.
      Те же кнопки прекрасно реализованы через тег button.
      И да, для использования веб-компонентов, как и других тегов использование JS API обязательно чуть менее, чем полностью.


  1. rutexd
    14.01.2024 16:10
    +1

    Осталось прикрутить реактивность и будет великое чудо


    1. LeninIvanov Автор
      14.01.2024 16:10

      В какой то степени, реакцию на изменение атрибутов можно так рассматривать, но да, этого не всегда достаточно.


    1. JerryI
      14.01.2024 16:10
      +1

      Там кстати это можно через расширения класса HTMLElement как показано в статье. Вещь интересная


  1. alexnozer
    14.01.2024 16:10
    +8

    Статья о веб-компонентах. Лайк!

    Сделаю несколько уточнений.

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

    Это кажется так. Их используют, просто об этом никто не знает. Ну и используют их крупные компании в основном. Из примеров: интерфейс Chrome, Edge и Firefox, включая DevTools, YouTube, VS Code, GitHub, Photoshop Web, MSN, Windows Store, Bing, Epic Games Store и т.д.

    Красивая портянка, не правда ли? Предлагаю сделать её проще и понятней

    Замена div + class на кастомный элемент может и сделало код читабельнее и понятнее, но семантика потеряна. Все же заголовок должен быть h*, вводная часть в header, копирайт в footer, а сам компонент - section, article, aside или чем-то ещё в зависимости от контекста. Семантика нужна поисковым роботам, ассистивным технологиям (для доступности), плагинам и т.д.

    Даже если это div-ы, у которых нет семантики, роботы все равно умеют анализировать их по другим эвристикам. Я думаю, что за столько лет существования миллиардов сайтов с div-ами, роботов научили определять контент, в том числе по классам, вложенности, каким-то повторяющимся паттернам, даже с div. Утверждать это на 100% я не могу, никто не знает алгоритмов. Но я думаю, что это так.

    Отличие лишь в том, что div - блочный, а span - строчный.

    div - потоковый и ощутимый (Flow и Palpable), а span - потоковый, фразовый и ощутимый (Flow, Phrasing и Palpable). Блочный и строчный - это термины из HTML4, в HTML5 их упразднили в пользу категорий и контентных моделей.

    С точки зрения семантики, стилей и функционала кастомные html-элементы равноценны тегу span целиком и полностью.

    Не совсем. С точки зрения категорий - да. С точки зрения базовых стилей - да (оба display: inline). Но у кастомных элементов контентная модель - прозрачная, а у span - фразовый контент. Это значит, что в span нельзя вложить div, ul, section (любой не фразовый контент), а в кастомный элемент можно вложить все, что можно в его родителя.


    1. LeninIvanov Автор
      14.01.2024 16:10

      Это кажется так. Их используют, просто об этом никто не знает. 

      Крупнейшие компании мира делают и поддерживают очень малый объём сайтов, их творения вполне можно считать редкостью.

      div-ы я использовал нарочито, специально. О том, что существуют семантические теги для соответствующих целей я знаю, но нужно же было дать понять всю глубину глубин.


      1. alexnozer
        14.01.2024 16:10

        Крупнейшие компании мира делают и поддерживают очень малый объём сайтов, их творения вполне можно считать редкостью.

        В количественном отношении да, их мало. Но размер аудитории, которая пользуется этими сайтами и приложениями, очень велик.

        В остальном да, веб-компоненты не так распространены.


  1. Abirvalg1
    14.01.2024 16:10

    Один из трёх популярнейших фреймворков, angular, это шутка такая для вас?


    1. LeninIvanov Автор
      14.01.2024 16:10
      +1

      Angular работает как сторонняя библиотека, ей даже пользоваться надо уметь. Кастомные элементы работают из коробки, как и другие теги, и если не трогать API - даже изучать не надо.


      1. strokoff
        14.01.2024 16:10
        +1

        Использовать веб-компоненты просто как замену div это глупая идея и плохой пример. Вы сравниваете нарочно плохую верстку с нарочно еще более плохой версткой. + Браузер и поисковик только теряют в семантике от того, что вы свои header и аналоги div придумываете и призываете их использовать ради красоты не используя js. + вам нужно свойство display как минимум прописать для корректного отображения.

        Использовать веб-компоненты нужно обязательно вместе с их возможностями, а не просто ради именования тегов. Я тоже делал несколько статей про веб-компоненты
        https://webislife.ru/strokoff/polnoe-pogruzhenie-v-veb-komponenty-v-2023-godu/ а также по крупицам собираю цикл статей про веб-компоненты https://webislife.ru/strokoff/czikl-statej-pro-veb-komponenty/ и на хабре еще публиковал пример веб-компонента на хабре Пишем собственный WYSIWYG редактор на основе веб-компонентов и textarea.


        1. LeninIvanov Автор
          14.01.2024 16:10
          -3

          Использование веб-компонентов должно быть не для замены div-ов, а для замены их классов, в следствии чего улучшается читаемость и уменьшается объем кода, да и некоторые проблемы каскада от этого решаются. Это не только красиво, но и практично.

          Вы сравниваете нарочно плохую верстку с нарочно еще более плохой версткой.

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

          вам нужно свойство display как минимум прописать для корректного отображения.

          И без него будет корректно отображаться, а про их изначальный стиль в статье упомянул:

          Да да, все ваши кастомные элементы изначально строчные. Учитывайте это при стилизации.

          И да, посмотрел вашу статью про веб-компоненты. Вам непременно нужны хотя бы два курса журналистского факультета, содержание нормальное, структуру нужно дорабатывать.


          1. strokoff
            14.01.2024 16:10
            +1

            Это не только красиво, но и практично.

            Верстка должна быть в первую очередь семантичной для поисковиков и машин которые ее будут обрабатывать. Вопросы красоты не должны стоять на первом месте при выборе HTML элементов для разных ситуаций. Практичность тоже очень субъективное понятие.

            Специально сделал такой пример, что бы показать разницу наиболее наглядно.

            Выходит вы показали разницу как делать не надо и как делать совсем не надо.

            И без него будет корректно отображаться

            Все будет инлайновыми элементами - это не нормально, разве что вы не пытаетесь верстать текст и выдумывать свои аналоги span\em\b\strong\mark etc..

            Вам непременно нужны хотя бы два курса журналистского факультета, содержание нормальное, структуру нужно дорабатывать.

            Всего лишь 2 курса? Переход на оценку личных качеств это грязный прием, когда по существую и содержанию сказать нечего, а по форме хочется докопаться.

            Еще раз веб-компоненты это не замена для семантических тегов существующих, страница сверстанная красиво и практично по вашим понятиям, в выдаче поисковой проиграет странице сверстанной по канонам семантики и доступности. Веб-компоненты это история, когда вам мало 1 тега для вашего элемента или вашему элементу нужен интерактив в виде js. Яркими примерами веб-компонентов можно считать <audio> и <video> теги, там и стили внутри свои и shadow dom присутствует.


            1. LeninIvanov Автор
              14.01.2024 16:10
              -5

              Верстка должна быть в первую очередь семантичной для поисковиков и машин которые ее будут обрабатывать

              В таком случае, переход веба на машинный код или тотальное использование веб-фреймворков в вашей логике является совершенно практичным... О людях подумайте.

              Практичность тоже очень субъективное понятие.

              Принцип DRY, как и время - очень субъективная штука!

              Выходит вы показали разницу как делать не надо и как делать совсем не надо.

              Вы небось когда читали учебник физики, пребывали в ярости - ну к чему эти абстрактные примеры в вакууме!? Где искажение времени, вызванное гравитацией!?

              Вам непременно нужны хотя бы два курса журналистского факультета

              Всего лишь 2 курса? 

              АХАХАХА, вы умеете себя в грязь затаптывать. Да, журфак не повредит. Да что уж там, вам не повредит дополнительное образование в любом объёме и количестве.


              1. strokoff
                14.01.2024 16:10
                +2

                Вы бы остановились, вас уже понесло

                В таком случае, переход веба на машинный код или тотальное использование веб-фреймворков в вашей логике является совершенно практичным... О людях подумайте.

                Веб давно на фреймворках сидит, на велосипедах сидят только их изобретатели. Все более менее серьезные проекты формируются с большим комьюнити. Мне бы не хотелось попасть после вас на проект, где в место css классов написаны веб-компоненты просто потому что автор так мог себе позволить.

                Принцип DRY, как и время - очень субъективная штука!

                Использование стандартных тегов и веб-компонентов не противоречит DRY в целом. Кажется что вам просто нечего было написать, а ответить хотелось.

                Вы небось когда читали учебник физики, пребывали в ярости - ну к чему эти абстрактные примеры в вакууме!? Где искажение времени, вызванное гравитацией!?

                И очередной переход на личности, от новорега с НЛО приглашением

                АХАХАХА, вы умеете себя в грязь затаптывать.

                Пожалуй эту ветку комментариев действительно стоит остановить, слишком много грязи которую в целом уже и комментировать противно.


        1. VADemon
          14.01.2024 16:10

          вам нужно свойство display как минимум прописать для корректного отображения.

          Я не вебдева, но вроде:

          If no inner display type value is specified, the principal box’s inner display type defaults to flow. If no outer display type value is specified, the principal box’s outer display type defaults to block.

          При этом: "Initial: inline". Но так как вы ниже пишите "Все будет инлайновыми элементами - это не нормально", то всё сходится? То есть, изначально inline, а вот если в стилях указан один из inner/outer, то второй применяется как из процитированного параграфа?

          https://drafts.csswg.org/css-display/#inner-display-type


  1. vanxant
    14.01.2024 16:10

    Статья отличная, не хватает только пары слов про CSS. А именно, для каждого такого тега в стилях обязательно нужно указать display (block, flex, inline, чё там у вас). Тогда это даже в IE 7 заработает.


    1. LeninIvanov Автор
      14.01.2024 16:10

      Упомянуто в тексте:

      Да да, все ваши кастомные элементы изначально строчные. Учитывайте это при стилизации.


      1. vanxant
        14.01.2024 16:10

        Не, вы не поняли. Я уж не помню деталей, но не во всех (старых?) браузерах они именно строчные, некоторые просто игнорируют тег целиком как будто это два коммента (<!--my-tag-->...<!--/my-tag-->). Указать свойство display нужно обязательно.


        1. LeninIvanov Автор
          14.01.2024 16:10

          Хм, не знал о таком. Благодарю, информация полезная.


  1. 127
    14.01.2024 16:10

    Раньше, кстати, можно было расширять DTD. Что-нибудь типа
    <!ELEMENT widget (value|preset|default|state)*>


    1. VADemon
      14.01.2024 16:10

      Покуда я именно на эту страницу засмотрелся, вот она: https://www.w3.org/TR/html4/intro/sgmltut.html#h-3.3.3


      1. 127
        14.01.2024 16:10

        Да это можно было делать еще в xhtml и xml-версии html 5 емнип, что активно делали в epub3.


  1. Aquahawk
    14.01.2024 16:10

    попробуйте узнать у бизнеса, готов ли он просто так выкинуть 2.7 процента аудитории. Особенно когда принимается ряд решений, типа тут пол процента, тут 2 процента, там 5 процентов, а потом люди удивляются, что это все ушли к конкуренту.


    1. LeninIvanov Автор
      14.01.2024 16:10

      Вы небось до сих пор гриды не используете из-за их не 100% поддержки?


      1. Aquahawk
        14.01.2024 16:10

        я до сих пор часто в es5 компилю из тайпскрипта, просто потому что никакого прироста скорости новые конструкции не дают, а часто приводит к снижению, и заколебёшься это отлавливать


  1. MinaiFenume
    14.01.2024 16:10
    +1

    Несколько моментов из моего опыта с кастомными элементами:

    • к кастомным элементам часто называют веб-компонентами, но они являются только одной составляющей набора API веб-компонентов (другие вещи включают в себя shadow DOM, HTML templates и тд) - подробнее тут

    • с помощью aria- аттрибутов кастомные элементы можно наделять семантикой, для лучшей SEO и accessibility (если вы уже активно используете их или другие аттрибуты, то кастомные компоненты могут помочь вам еще больше сократить объем кода и улучшить читаемость)

    • среди важных проблем - server-side rendering. Кастомные элементы требуют исполнения JS кода на стороне клиента для рендера, соответственно их сложнее использовать в контексте SRR-приложений. Аспекты типа локализации, server-side авторизации, использования CMS могут усложняться, и вам придется придумать как это решать. Поэтому предпочтительно может быть использовать web-component библиотеки которые уже это делают, но в ущерб минимализма и нативности API :)


    1. LeninIvanov Автор
      14.01.2024 16:10

      Вы видимо очепятались, aria-* атрибуты задают состояние элементов, что важно для программ чтения с экрана, но это не семантика. Семантика это атрибут role.