У HTML-элементов на HTML-странице может быть необязательный глобальный атрибут class. Например:

<div class="имя-класса1 имя-класса2 имя-класса3">
  Какой-то текст.
</div>

Здесь у HTML-элемента div есть интересующий нас атрибут class.

С точки зрения стандарта языка HTML

По действующему стандарту языка HTML атрибут class HTML-элементов должен содержать значение, состоящее из набора (множества) названий (токенов) классов CSS, разделенных пробельными символами (символ пробела, символ горизонтальной табуляции, символы новой строки). В примере выше атрибут class содержит значение-строку имя-класса1 имя-класса2 имя-класса3, представляющее собой набор из трех названий классов CSS, разделенных символом пробела.

Понятие, о котором тут идет речь — набор из слов (токенов), разделенных пробельными символами (по-английски «set of space-separated tokens»). Само это понятие определено в стандарте языка HTML отдельно от определения атрибута class.

В определении понятия «set of space-separated tokens» сказано, что это строка, содержащая ноль или более слов (токенов), разделенных пробельными символами. Из этого я сделал вывод, что атрибут class по действующему стандарту HTML может не содержать ничего (содержать пустую строку). Также не будет нарушением действующего стандарта HTML, если этот атрибут будет содержать только пробельные символы (символ пробела, символ горизонтальной табуляции, символы новой строки).

Действующий стандарт HTML вообще практически не накладывает на набор названий классов CSS в атрибуте class HTML-элементов каких-либо ограничений. Не накладывается ограничение на дублирование названий классов CSS внутри атрибута class. Не накладывается каких-либо ограничений, касающихся порядка перечисления названий классов CSS внутри атрибута class.

То есть с точки зрения действующего стандарта HTML (в отличие от стандарта CSS, о чем речь пойдет далее) название класса, перечисленное в наборе названий классов внутри атрибута class HTML-элемента раньше (левее, выше), ничем не отличается от названия класса, перечисленного в том же наборе названий классов внутри атрибута class HTML-элемента позже (правее, ниже).

В примере выше с точки зрения действующего стандарта HTML названия классов имя-класса1имя-класса2 и имя-класса3 в наборе названий имя-класса1 имя-класса2 имя-класса3 полностью равноправны, несмотря на то, что, к примеру, название имя-класса1 перечислено раньше (левее), чем имя-класса2 или имя-класса3. То же самое касается названия имя-класса2 по сравнению с названием имя-класса3.

Во что это выливается на практике?

Рассмотрим такой код на языке HTML (многоточием заменен неинтересный для предмета этой статьи код):

...
<head>
  ...
  <style>
    .имя-класса1 { color: green; }
    .имя-класса2 { color: red; }
    .имя-класса3 { border: 2px solid blue; }
  </style>
</head>
<body>
  <p class="имя-класса1 имя-класса2 имя-класса3">
    Какой-то текст1.
  </p>
  <p class="имя-класса2 имя-класса1 имя-класса3">
    Какой-то текст2.
  </p>
</body>
...

В теле этой HTML-страницы есть два параграфа (HTML-элемент p). Каждый из этих параграфов содержит атрибут class с набором из одних и тех же трех названий классов CSS, только перечисленных в разном порядке.

Описание стилей в классе имя-класса3 не конфликтует с другими классами. А вот описания стилей в классах имя-класса1 и имя-класса2 конфликтуют друг с другом (приписывают разные значения одному и тому же свойству HTML-элемента).

В итоге при любой перестановке названий классов CSS в атрибуте class HTML-элементов p браузер отобразит параграфы одинаково, в данном случае — с синей границей и текстом красного цвета. Это подтверждает наши выводы, сделанные выше из определений действующего стандарта HTML.

Почему же в данном случае в конфликте описаний стилей в классах имя-класса1 и имя-класса2 «победил» класс имя-класса2 (текст в параграфах отразился красным цветом)? Потому что при определении классов CSS внутри HTML-элемента style класс имя-класса2 описан позже (ниже), чем класс имя-класса1. Внутри HTML-элемента style действуют правила (стандарт) языка CSS. Это действие того самого «каскада», давшего первую букву аббревиатуре CSS (Cascading Style Sheets). Если менять местами определения классов CSS внутри HTML-элемента style (или внутри файла с кодом на языке CSS, если определения стилей вынесены в отдельный файл или файлы), то отображение HTML-страницы в браузере будет изменяться.

Влияние правил языка CSS

Всегда ли порядок названий классов в атрибуте «class» HTML-элемента не влияет на отображение HTML-страницы?

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

Дело в том, что в языке CSS можно определить селектор (отборщик) HTML-элементов так, что отбор HTML-элементов селектором будет зависеть от порядка перечисления названий классов CSS в атрибуте class HTML-элементов. Это сделает порядок перечисления названий классов в атрибуте class HTML-элементов значимым для отображения HTML-страницы в браузере.

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

В качестве примера рассмотрим такой код на языке HTML:

...
<head>
  ...
  <style>
    [class^="имя-класса1 имя-класса2"] { color: green; }
    [class^="имя-класса2 имя-класса1"] { color: red; }
    .имя-класса3 { border: 2px solid blue; }
  </style>
</head>
<body>
  <p class="имя-класса1 имя-класса2 имя-класса3">
    Какой-то текст1.
  </p>
  <p class="имя-класса2 имя-класса1 имя-класса3">
    Какой-то текст2.
  </p>
</body>
...

Это тот же код HTML, что и в первом примере, только здесь изменены два первых селектора внутри HTML-элемента style. Даже описания стилей остались нетронутыми. Однако, теперь браузер отображает в первом параграфе текст зеленым цветом, а во втором параграфе — красным цветом.

В этом примере порядок названий классов внутри атрибута class HTML-элементов стал значимым для отображения HTML-страницы в браузере, но это действие не правил языка HTML, а правил языка CSS.

Заключение

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

Порядок названий классов CSS в атрибуте class HTML-элементов на HTML-странице может влиять (может быть важным) на отображение этой HTML-страницы в браузере. Но следует понимать, что это влияние определяется не правилами (стандартом) языка HTML, а тем, как описаны стили для данной HTML-страницы с помощью языка CSS (они могут быть описаны в разных местах — внутри HTML-элемента style, внутри внешнего файла (нескольких файлов) и так далее).

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


  1. alvltab
    02.09.2022 12:32
    +12

    Давайте придумаем искусственную проблему, сформулируем по ней вопрос и напишем статью, о которой никто не просил.


  1. lan-mak
    02.09.2022 18:32

    Какая-то очевидная вещь


  1. mSnus
    02.09.2022 23:36

    Да вы издеваетесь? То ФёстВДС учит запускать Постгресс в контейнере, раздувая статью из одной строчки, то здесь, оказывается, классы можноо пробелами разделять! Это обострение какое-то?


  1. Farmatique
    03.09.2022 02:23

    Хм, не знаю почему минусов налепили человеку, все довольно грамотно расписал и по существу. Другое дело, какая практическая польза с этого? Я не уверен что селекторы вида [class^='classname1 classname2'] это часто встречающиеся на практике конструкция. По крайней мере, в моем опыте я их видел очень редко


    1. ilyachalov Автор
      03.09.2022 07:41

      какая практическая польза с этого?

      Я пишу что-то вроде валидатора для проверки файлов с кодом HTML (не валидатор HTML). Меня интересуют все случаи, которые могут прийти в голову (даже самые дурацкие) при использовании атрибута class HTML-элементов. Пустой атрибут, дублирующиеся названия классов, использование редких символов Юникода и так далее.

      В случае БЭМ-сущностей - можно ли в атрибуте class сначала прописать названия модификаторов, а потом название блока или элемента.

      Является ли всё перечисленное ошибкой. Если это ошибка, то с точки зрения HTML, или с точки зрения CSS, или с точки зрения методологии БЭМ? И так далее.

      Такой инструмент может пригодиться в обучении. Начинающие придумывают в своих работах всякое.


      1. Farmatique
        03.09.2022 21:49

        Да, думаю для случая "исследования возможностей" и последующего применения для построения чего-то типа "собственного css-фреймворка" это как раз полезная штука.


        1. ilyachalov Автор
          04.09.2022 05:17

          Этот код - просто демонстрация того, что порядок слов в атрибуте class HTML-элемента может быть важен. Многие начинающие кодеры считают, что в этом атрибуте работает CSS-каскад: например тут и вот тут. Собственно, моя статья написана по мотивам этих двух вопросов на сайте "Stack Overflow". Код взят из самого популярного ответа на второй из этих вопросов.


  1. ProRules
    03.09.2022 07:41

    Спец. залогинился (и восстановил пароль) чтобы оставить данный коммент. Я понимаю что, к сожалению комментарием повыше pageRank данной... статьи но: автор, зачем вы опускаете уровень хабра подпольными статьями? ( Но более меня интересует- кто данную статью вообще допустил. Я думал тут раньше вообще даже зарегаться можно было лишь по приглашению а тем более такие "статьи" писать.


    1. ilyachalov Автор
      03.09.2022 07:46

      автор, зачем вы опускаете уровень хабра подпольными статьями?

      Предположим, я написал новую статью. Как мне определить, соответствует моя статья "уровню хабра" или нет? Могу ли я прислать эту статью вам на проверку?


      1. ProRules
        03.09.2022 14:03

        Могу ли я прислать эту статью вам на проверку

        :) Я считаю что я не могу дать ничего того что уже не написано и являлось бы полезным на хабре так-как не занимаюсь исследованиями или изобретением чего либо, либо улучшением существующего

        Как мне определить, соответствует моя статья "уровню хабра" или нет?

        В поисковик вбить ее название и, если там 100500 таких-же, и тем более, если ответ заключается в одном слове (порядок важен? нет) - то статья НЕ соответствует "уровню хабра"...


        1. ilyachalov Автор
          04.09.2022 04:52

          если ответ заключается в одном слове (порядок важен? нет)

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

          Сейчас вбил название этой статьи в Яндексе и там не находится быстрого ответа на вопрос из статьи. Большинство источников просто рассказывают начинающим про классы CSS, не освещая "узкие" места.


  1. ehots
    03.09.2022 16:37

    Помнится на одной конференции фронтендер из Яндекса озвучивал такую же "проблему"... Автор тоже не знает спецификацию, от чего придумывает велосипеды и совершает открытия. Читай базу.


    1. ilyachalov Автор
      04.09.2022 04:41

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


      1. CrazyNiger
        04.09.2022 08:37
        +2

        "Ошибка" в том, что когда вы пишете в css-селекторе вот так: [class^="имя-класса1 имя-класса2"], то это же ни имеет ни какого отношения к css-классам. Это проверка на значение атрибута у элемента, и определения спецификации HTML про перечисления токенов классов не применимы в принципе.

        Ваш селектор проверяет атрибут classкак просто строку, из-за чего на отображение начинает влиять не только порядок классов, на что вы акцентируете внимание, но и то, как вы разделяете название классов - разделите их больше чем одним пробелом или переносом строки и селектор не примениться. Вряд ли это ожидаемое поведение.

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


        1. ilyachalov Автор
          04.09.2022 09:02

          Спасибо, замечание по делу.

          На самом деле я это сам тоже заметил, когда опубликовал уже статью. Подумал, что точнее будет, если писать о порядке слов в атрибуте class, а не о порядке классов CSS.

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