Как стать автором
Обновить

Комментарии 22

Очень много чего правильно, но вот есть моменты нужные только при обучении и очень будут мешать для верстки для продакшена, в частности, нет пункта про картинки, а именно про отзывчивость + в форматах нет современных, в подключении стилей в эпоху хттп2 подключение разными файлами считать за ошибку, нет ни слова про критические стили и вместо этого запрет на подключение стилей через тег. Ну и есть доля непонятной отсебятины - про стили для тегов (на самом деле от них не уйти при наличии пользовательского ввода - комменты на сайте, статьи в админке через редактор и т.д.), от некоторых можно легко уйти, от других - сложно, а если пользоваться вашими требованиями, то получится верстка для страницы, которую нужно будет дорабатывать для продакшена и работодатели не сильно будут рады, если верстальщик им такую верстку «принесёт» как готовую. Но за отсутствие фреймворков плюсик).

Давайте по порядку

нет пункта про картинки, а именно про отзывчивость

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

в форматах нет современных

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

в подключении стилей в эпоху хттп2 подключение разными файлами считать за ошибку

для решаемой задачи (вёрстка с нуля сайта из 2-3 страниц) это скорее ошибка, да даже и в более сложных проектах сборщики всё равно склеивают стили в один файл

нет ни слова про критические стили

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

и есть доля непонятной отсебятины - про стили для тегов (на самом деле от них не уйти при наличии пользовательского ввода - комменты на сайте, статьи в админке через редактор и т.д.)

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

то получится верстка для страницы, которую нужно будет дорабатывать для продакшена и работодатели не сильно будут рады, если верстальщик им такую верстку «принесёт» как готовую

какой вид продакшна вы имеете в виду? продакшн в заказной разработке, когда верстают для клиента, который потом будет натягивать вёрстку на какую-то цмс или продакшн в продуктовой разработке, когда с нуля пилится интерфейс продукта?

мы от части форматов сознательно отказались

Figma, кстати, из коробки умеет в .webp , но мы планировали форматы во второй уровень уносить.

Да, этот момент мы рассматриваем в рамках професии и расскарываем на HTML 2 уровня.

С webp студенты учаться работать, а с avif знакомятся и если захотят, то могут добавить в итоговой проект. webp формат про оптимизацию, а не про эстетику (например у JPG и PNG тут есть отличия в виде прозрачноти). Любой JPG или PNG будет выглядеть также как webp. Оптимизация как раз тема для следующего уровня HTML-курса.

нет ни слова про критические стили

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

pagespeed / lighthouse де-факто обязателен для всех проектов, которые чуть больше админки локалхоста. И там это критическое требование.

Насколько я понимаю, вопросы был именно про critical css

Что касается pagespeed / lighthouse — при разработке критериев мы учитывали и требования этих инструментов, и тот объём задач, который делает студент на этом курсе. Здесь он верстает сайт из двух страниц, поэтому продвинутые техники оптимизации пока не даём. Но базовые вещи требуем, например, про подбор правильного формата для картинок и оптимизацию графики.

HTML Academy респект, спс за статью.
Первые курсы, которые вели: Першин, Симоненко и Макеев - лучшее что было в верстке. :)

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

Спасибо за статью.

Расскажите, пожалуйста, почему для нормализации тега <img> неправильно использовать свойство display: block;

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

А та нормализация, которая допускается в критерии, она про перестраховку, чтобы картинка за пределы своего контейнера не вылезала (даже если кто-то вставил картинку, которая намного шире контейнера).

Спасибо!

Благодарю за этот труд, и за то, что собрали это в такой материал полезны! Теперь есть куда ссылаться : )

HTML-02. Заголовки

На странице должен быть <h1>, который описывает содержимое страницы.

Присутствие на странице заголовка не является обязательным требованием в вебе. Необходимость в заголовке определяется типом и содержимым страницы.

HTML-03. Кнопки и ссылки

Ссылки <a href> должны использоваться для перехода между страницами, а кнопки <button> должны использоваться только для действий на странице.

Очень размыто в нынешних реалиях. Вызов модального окна должен осуществляться кнопкой или ссылкой? Программная навигация? Отображение компонентов в SPA?

CSS-02. Глобальный селектор

Неправильно. Использован универсальный селектор без псевдоэлементов и не для изменения боксовой модели.

Что? Откуда это взято? Лично я всегда сбрасываю стили таким образом. Даже если я начну лепить простыни для reset.css, то html5 позволяет использовать кастомные элементы. И их эти простыни уже не зацепят. А универсальный селектор потому и называется универсальным, что его назначение - установить css-свойства для всех элементов страницы.

CSS-04. ID в селекторах

В селекторах не должно быть #id.

Селекторы по идентификатору обладают большей специфичностью по сравнению с классом и добавляют непредсказуемости в код. Например, чтобы переопределить #id, потребуется несколько селекторов по классу или !important. Это делает код неконтролируемым и сложно читаемым.

Это не критерий. Это просто общепринятая практика. Сами печетесь о корректном каскаде, и сами же игнорируете дополнительные инструменты управления "специфичностью". "Неконтроллируемость" вносят вовсе не идентификаторы или !important, а "говнокод". Ну и никаким количеством "селекторов по классу" вы идентификатор не "перебьёте". Именно в этом и есть его основное назначение. И если пользоваться этим с умом - всё будет контролируемо и читаемо.

CSS-05. Использование !important

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

CONT-01. Текстовые переносы

Текст не должен переноситься с помощью двойного <br>.

Удивили. Думал будет "нельзя использовать <br> для управления переносом".

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

Вы написали такой талмуд с критериями, но даже не удосужились открыть спецификацию? Т.е. вы не в курсе как HTML5 трактует разделение элементов на строчные и блочные? Если мне нужно чтобы все картинки на странице были представленные через блочную модель, почему я не могу использовать img{display:block;}? Да, я именно хочу кардинально поменять их поведение. В чём проблема? Ситуация несколько специфичная, но настолько уж. Точно так же далеко не всегда нужно object-fit:contain. Легко может понадобиться и object-fit:cover. В чём тут разница - не объясните?

Мы писали критерии применительно к следующей задаче: "Вёрстка страницы без адаптивности с нуля в условиях полного контроля разметки верстальщиком". То есть это те условия, в которых можно делать "идеальную вёрстку", и они ближе к вёрстке интерфейсов в продуктовых компаниях.

Зачем понимать, как делать "идеальную вёрстку" и как писать "идеальный код"? Чтобы в подходящих условиях делать максимально качественные интерфейсы, а при наличии специфических требований и задач отступать от идеального решения.

С учётом этого и постараюсь ответить на все вопросы.

Присутствие на странице заголовка не является обязательным требованием в вебе. Необходимость в заголовке определяется типом и содержимым страницы.

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

Очень размыто в нынешних реалиях. Вызов модального окна должен осуществляться кнопкой или ссылкой? Программная навигация? Отображение компонентов в SPA?

Возможно, формулировка и размыта. Вопрос в другом: считаете ли вы, что хороший верстальщик должен уметь разбираться в том, когда ставить ссылку, а когда кнопку? Если да, то критерий нужен.

Общее правило по выбору кнопки/ссылки у нас получилось сформулировать так, что единственное условие для выбора – это возможность потенциального перехода куда-то по щелку или невозможность перехода куда-то. Конечно, иногда данных с макета недостаточно для принятия решения, и в этом случае надо обращаться к тз или к заказчику.

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

Что? Откуда это взято? Лично я всегда сбрасываю стили таким образом. Даже если я начну лепить простыни для reset.css, то html5 позволяет использовать кастомные элементы. И их эти простыни уже не зацепят.

Основной посыл этого критерия - чтобы не использовали где попало селекторы по тегам. Например, не сбрасывали бы отступы у всех списков с помощью `ul {...}`. Вы в своих специфичных задачах можете использовать глобальные селекторы, если понимаете плюсы-минусы.

А универсальный селектор потому и называется универсальным, что его назначение - установить css-свойства для всех элементов страницы.

Да, такая возможность в CSS присутствует. Но это ведь не означает, что её нужно использовать неаккуратно и напропалую?

Это не критерий. Это просто общепринятая практика. Сами печетесь о корректном каскаде, и сами же игнорируете дополнительные инструменты управления "специфичностью". "Неконтроллируемость" вносят вовсе не идентификаторы или !important, а "говнокод". Ну и никаким количеством "селекторов по классу" вы идентификатор не "перебьёте". Именно в этом и есть его основное назначение. И если пользоваться этим с умом - всё будет контролируемо и читаемо.

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

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

А можете подсказать специфичные задачи, где этот инструмент идеально подходит? Мы эти примеры используем в критериях, а также учтём эти применры при обучении этим специфичным задачам.

Удивили. Думал будет "нельзя использовать <br> для управления переносом".

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

Вы написали такой талмуд с критериями, но даже не удосужились открыть спецификацию? Т.е. вы не в курсе как HTML5 трактует разделение элементов на строчные и блочные?

К сожалению (а вообще к счастью), HTML5 уже никак не трактует разделение на блочные и строчные (как когда то было в предыдущей версии). В HTML5 ввели категории элементов: фразовые, потоковые и так далее. А названия типов боксов (а не элементов) остались только в CSS. Мне лично это изменение нравится очень сильно, так как отражает важный принцип: разделение содержания и оформления.

Если мне нужно чтобы все картинки на странице были представленные через блочную модель, почему я не могу использовать img{display:block;}? Да, я именно хочу кардинально поменять их поведение. В чём проблема? Ситуация несколько специфичная, но настолько уж. Точно так же далеко не всегда нужно object-fit:contain. Легко может понадобиться и object-fit:cover. В чём тут разница - не объясните?

Всё правильно, вы сами написали, что ситуация специфичная. И если вам для специфичной задачи нужно для всех картинок задать блочные боксы, то это ок. Наша же задача была в этом примере показать один из распространенных способов нормализации картинок, когда можно и глобальный селектор по тегу использовать. И чаще всего для нормализации картинок задают `max-width: 100%`. `object-fit` тоже, думаю, допустим для нормализации

Начертания шрифтов, подключенных с помощью @font-face, должны меняться с помощью font-weight и font-style и не должны меняться с помощью подключения отдельного семейства шрифтов.

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

Немного не понял про что вы.

Критерий защищает от следующей ситуации

@font-face {
  font-family: "OpenSans";
  src: url("fonts/opensans.woff2");
  font-display: swap;
}

@font-face {
  font-family: "OpenSans-Bold";
  src: url("fonts/opensans-bold.woff2");
  font-display: swap;
}

body {
  font-family: "OpenSans", sans-serif;
}

h1 {
  font-family: "OpenSans-Bold", sans-serif;
}

Мы же просим использовать шрифты

@font-face {
  font-family: "OpenSans";
  src: url("fonts/opensans.woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: OpenSans;
  src: url("fonts/opensans-bold.woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

body {
  font-family: "OpenSans", sans-serif;
}

h1 {
  font-weight: 700;
}

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

Неправильно. Начертание семейства изменяется именем шрифта, а не свойствами font-weight и font-style.

Если я буду начертание менять свойством font-weight то браузер будет решать как отрисовать начертание (например 400 или 700), а если я буду менять начертание именем шрифта font-family: "OpenSans Bold", то будет подключаться то начертание которое нарисовал дизайнер и которое лежит в файле "fonts/opensans-bold.woff2".

В случае с

@font-face {
  font-family: "OpenSans";
  src: url("fonts/opensans.woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: OpenSans;
  src: url("fonts/opensans-bold.woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

body {
  font-family: "OpenSans", sans-serif;
}

h1 {
  font-weight: 700;
}

У <h1> будет отображён OpenSans из файла opensans-bold.woff2 , то есть то что и планировал дизайнер

Посмотрите как Google Fonts генерит стилевой файл с подключением шрифтов

https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300;0,400;0,600;0,700;0,800;1,300;1,400;1,600;1,700;1,800&display=swap

ровно таким же способом

спасибо, теперь стало ясно

Для тега form атрибут action давно стал необязательным. Зачем его обязательно указывать?

Зарегистрируйтесь на Хабре, чтобы оставить комментарий