Будни разработчика
14.5K subscribers
1.38K photos
404 videos
8 files
2.31K links
Download Telegram
#детектив дня

Сегодня в чат пришёл подписчик с забавной проблемой.

Дано: форма с двумя полями, одно просто как HTML-тег, второе — React-компонент. Ну, очевидно, компонент тоже содержит поле ввода.

При нажатию на клавишу Ввод событие onSubmit не происходит, форма не отправляется. Хотя, вроде как, всем известно, что это — стандартное поведение.

Было замечено, что при удалении React-компонента всё отлично работает. И первым предположением стало, что React что-то испортил, или песочница кривая.

Кто-то догадался сделать ванильный пример, поведение сохранилось.

То есть, вот такое:
<form onSubmit="alert('aha')">
<input type="text"/>
<input type="text"/>
</form>

...просто-напросто не работает. Стали копать.

И докопались до спецификации 1995 года для HTML 2.0!

Вот она: https://www.w3.org/MarkUp/html-spec/html-spec_8.html#SEC8.2

И там написано следующее:
When the user indicates that the form should be submitted (using a submit button or image input), the form data set is processed according to its method, action URI and enctype.

Перевожу: чёрным по белому сказано, что форма должна отправляться по кнопке submit (или специальной картинке, но то такое).

То есть, наше предположение о том, что форма всегда должна отправляться по нажатию Ввода — уже неверное.

Но, буквально, в следующем же абзаце:
When there is only one single-line text input field in a form, the user agent should accept Enter in that field as a request to submit the form.

Так-так-так, а что тут у нас? А тут написано, что единственное текстовое поле — это частный случай и нажатие клавиши ввода должно рассматриваться как отправка формы!

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

Короче, так как же решить проблему и не добавлять кнопку?

Очень просто, вставить в форму следующее:
<input type="submit" hidden/>

По-моему, пахнет лёгким бредом, но уж как есть.

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

#html #form #submit
🤩30👍234👎1
#заметка дня

Есть такой элемент — template. Название говорит само за себя: это шаблон.

Пишете в него некий HTML/SVG код, потом клонируете и вставляете куда вам надо.

На этом месте апологеты фреймворков ухмыльнулись, но вы же не одни на свете, да?


const content = template.content. firstElementChild.cloneNode(true);


Важно понимать, что содержимое шаблона — это фрагмент (обёртка над реальными нодами, если грубо), поэтому обращаться с ним надо соответственно.

Почему для этой цели не использовать просто скрытый div или — привет из прошлого — script type="text/template"?

Ну второе вообще не в кассу, это просто абьюз. А первое:
- Контент внутри темплейта не будет загружаться, пока не склонирован явно: ни картинки, ни стили, ни скрипты
- Валидатор игнорирует содержимое, хоть dd храните там, хоть td
- Поисковые системы знают про template и точно не индексируют. А с div hidden всё не так однозначно.
- Ну и именование говорит само за себя. Сахар все любят.

#html #template #бородач
👍113
#фишка дня

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

Места на экране мало, ещё и клавиатура съест.

Очень просто! Использовать атрибут enterkeyhint!

Спека: https://html.spec.whatwg.org/multipage/interaction.html#input-modalities:-the-enterkeyhint-attribute

Поддержка: https://caniuse.com/?search=enterkeyhint

Пользуемся!

#mobile #form #html #бородач
👍301
#статья дня

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

https://ishadeed.com/article/responsive-design-height/

Разработчики часто забывают, что посетители редко используют весь доступный экран. Не только по ширине, но и по высоте. А мода в современных макетах диктует вольготное использование вертикального пространства, но с обязательным условием: “Всё должно влезать в один экран!”. Это, коненчо, бред, но мода есть мода.

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

Статья есть в переводе на Хабре: https://habr.com/ru/company/skillfactory/blog/524996/

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

#css #html #перевод #бородач
7👍7
#фишка дня

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

Буквально — используя параметры строки запроса (query string parameters).

Ну то есть что-то вроде https://buy.that?title=Product&action=buy&config=2&amount=3, классические GET-параметры, но управляемые с фронта.

А вот как позволить клиенту обновить страницу, сохранив эти параметры? Желательно, без лишней работы и без использования JS вообще.

А очень просто!

<a href="">Reload</a>

Да, вот так просто! Самое классное, что абсолютно валидно и есть в спеках: https://stackoverflow.com/questions/5637969/is-an-empty-href-valid/43340108#43340108

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

Не пишите лишнего, котаны!

#http #html #trick #бородач
22👍19
#заметка дня

#css #html #pp #pixelperfect

Один из самых проблемных вопросов верстальщиков — не обязательно начинающих — это так называемый “пиксель пёрфект” (pixel perfect). Проще говоря, свёрстанный макет должен полностью соответствовать дизайну вплоть до последнего пикселя.

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

Но всё немного интереснее.

Давайте сразу определимся: правильно свёрстанный макет точен до пикселя по умолчанию. Точка.

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

У блока стоят поля и отступы по 16 пикселей? Нет ни одной причины ставить 10, чтобы “было легче считать” (и такое бывает), а потом проходить по всему макету заново. Ставьте сразу 16, а чтобы помочь себе — пользуйтесь расширениями для браузера, например https://www.welldonecode.com/perfectpixel/

Конечно, так можно дойти до крайности. Я много раз видел как люди бездумно копируют размеры из Sketch, Avocode или Figma наивно полагая, что уж кому как не им знать о размерах и положении. Это самая большая ошибка, и я уж молчу о том, что редакторы зачастую ставят абсолютное позиционирование всему подряд.

Будьте заранее готовы к тому, что макет – живой. Выделенный блок делится на секции? Используйте проценты во флексах или fr в гридах, делите его относительными единицами. Дизайнер поставил 63 px? Это явно дрогнула рука, не используйте нечётные значения никогда, округляйте до ближайших x4 (в данном случае — 64). Во всех размерах должна просматриваться логика, не могут три кнопки в ряду иметь один размер, а четвёртая – другой.

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

В скором времени я попробую затронуть тему вёрстки изначально неудобных макетов: что делать если вам выдали макет в 1920 пикселей, а большинство ноутбуков до сих пор имеют 1366 и как вести диалог с дизайнером и заказчиком в такой ситуации.
34👍9🤩1
#заметка дня

Сразу с панча: не используйте input[type=“number”].

Он тащит за собой целый ворох проблем:

1. странно выглядит (ниже о том, почему);
2. плохо стилизуется;
3. не подчиняется стандартным атрибутам вроде maxlength (sick!);
4. имеет ARIA-роль spinbutton (ниже поясню, что это);
5. позволяет ввести e (10e9) и валидация даже не заикнётся;
6. в старых Safari и Chrome округляет введённые числа (например, номер кредитки) до мантиссы и экспоненты (по-моему, это уже конец);
7. во время ввода можно случайно нажать стрелку вверх или вниз (или даже тронуть колесо мышки на некоторых ос) и введённое число изменится.

Как видите, минусов немало. А откуда они вообще взялись?

А всё просто: input[type=“number”] создавался для имитации т. н. tally counter, ручного счётчика. Ну вы наверняка видели фильмы, где людей или скот считали надетым на палец устройством. Отсюда и ARIA-роль spinner (счётчик оборотов), и стрелки ввода.

Вот только числа с плавающей запятой или ввод мантиссы и экспоненты — это уже самодеятельность браузеров. Что приводит к идиотичным ситуациям вроде округления чисел.

Так что же делать?

А делать следующее:

<input type="text" inputmode="numeric" pattern="[0-9]*">

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

Да, это не предотвращает ввод букв, только даёт валидацию. Но вы в любом случае должны задать нужное поведение вашей формы скриптом, от этого никуда не деться. даже с number.

За подробностями можно обратиться к блогу разработчиков официального сайта правительства Великобритании: https://technology.blog.gov.uk/2020/02/24/why-the-gov-uk-design-system-team-changed-the-input-type-for-numbers/

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

Я помню подобное было у многих государственных сайтов,. но почти все блоги исчезли со временем...

Подытожим: input[type=“number”] делался не для того, как его применяют.

Подумайте об этом.

#css #html #number #aria #semantics #a11y #бородач
👍375🤩4
#фишка дня

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

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

Но не все знают, что лейбл можно повесить и на элемент button: https://codepen.io/alinaki/pen/XWjLedQ

Да, возможно, кнопке свой ярлык не нужен и даже MDN сообщает нам об этом, но!

Но в лейбл можно добавить дополнительную информацию, которая будет однозначно и семантично связана с кнопкой и поможет, например, скринридерам или при создании тултипа.

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

А вот если вы не используете кнопки и балуетесь role=“button” на div-ах (в лучшем случае) — этой возможности вы лишены в принципе.

#html #button #label #бородач
4
#фишка дня

Давайте что-нибудь наболевшее.

Вот, например, если установить атрибут translate="no" на тег, содержащий название компании, то он не подвергнется автоматическому переводу (типа Google Translate): https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/translate

Удобно, если ваша компания называется "Clean Beam" или ещё какая-то подобная глупость.

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

#html #attribute #translate
19
#фишка дня

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

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

Но не все знают, что лейбл можно повесить и на элемент button: https://codepen.io/alinaki/pen/XWjLedQ

Да, возможно, кнопке свой ярлык не нужен и даже MDN сообщает нам об этом, но!

Но в лейбл можно добавить дополнительную информацию, которая будет однозначно и семантично связана с кнопкой и поможет, например, скринридерам или при создании тултипа.

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

А вот если вы не используете кнопки и балуетесь role=“button” на div-ах (в лучшем случае) — этой возможности вы лишены в принципе.

#html #button #label #бородач
👍12
#инструмент дня

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

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

Тогда я воспользовался https://github.com/cheeriojs/cheerio, написав простой скрипт на node.js. Это похоже на реализацию селекторов в jQuery, но для Node.js. Разобрал данные и сохранил в JSON.

Оказывается, есть и более кондовые утилиты.

Например, https://github.com/mgdm/htmlq и https://stedolan.github.io/jq

Первый, как нетрудно догадаться, может обработать HTML, а второй — JSON. И всё из командной строки :)

Например, найти все ссылки на странице:

curl --silent https://www.rust-lang.org/ | htmlq --attribute href a


Можно и просто целые куски HTML выдирать, и селекторы использовать. А дальше — все возможности командной строки и скриптов для обработки.

Ну а jq может стать частью вашей CI/CD системы, разгребсти ответы от API GitHub, например, и выдать их в читаемом виде.

#tools #html #json #cli #бородач
👍9
#рекомендация дня

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

Есть ребята из компании 53xapps, занимаются созданием сайтов и автоматизацией бизнеса. Ну и вот они решили запилить свой собственный курс по Frontend разработке.

Конкретно: введение в алгоритмы, HTML/CSS, JavaScript и Vue.js.

Разработка курса заняла около полугода. Большое количество видео и практики.

Подход к обучению немного отличается от других курсов: сперва несколько уроков вас учат понимать алгоритмы и рисовать блок-схемы. После этого обучение становится более осмысленным.

Курс довольно плотный, тестовые студенты проходили его по 15-20 часов в неделю 4 месяца, но сейчас есть возможность проходить курс в спокойном собственном темпе. Все для вас 🙂

Освоите JavaScript, HTML/CSS, Vue.js. Познакомитесь с несколькими популярными библиотеками. Для старта во фронте вполне достаточно.

Есть несколько бесплатных уроков, можно попробовать и пощупать.

Итак, цена. 5000 рублей. А подписчикам канала промокод HTMLSHIT даст 1000 рублей скидки.

Программа курса и бесплатные уроки доступны по ссылке.

#frontend #HTML #CSS #JavaScript
🤡11👍82
#день_рождения дня

Сегодня День рождения не только лишь у меня, но и у HTML тегов!

29 октября 1991 года Тим Бернерс-Ли выкатил документ с названием HTML Tags.

И состоял он из описания 18 первых тегов: <title>, <nextid>, <a>, <isindex>, <plaintext>, <listing>, <p>, <h1>…<h6>, <address>, <hp1>, <hp2>…, <dl>, <dt>, <dd>, <ul>, <li>,<menu> и <dir>.

Архивная версия: https://www.w3.org/History/19921103-hypertext/hypertext/WWW/MarkUp/Tags.html

С Днём рождения, HTML! Ну и я :)

#html
🤩2811👍1
Media is too big
VIEW IN TELEGRAM
#ссылка дня

Сегодня день такой, про SVG-фильтры.

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

Ну, вниманием они обделены не только со стороны сообщества веб-разработчиков, но и немного со стороны разработчиков браузеров. У WebGL и WebGPU перспективы шире.

Но это не означает, что у SVG-фильтров нет козырей в рукаве! Один из самых важных — их можно применить прямо на HTML-элемент и он как работал, так и будет работать!

Естественно, этим пользуется не только Ана Тюдор (кстати, не пользуется, она не работает как разработчик, только как художник в этом смысле и консультант).

Глядите, какая демка: https://svg-shaders.vercel.app/
И её код: https://github.com/shuding/svg-shaders

Она позволяет с лёгкостью или нагенерировать нужных фильтров, или вообще принять идею для своих проектов.

Повторю: HTML-элементы продолжают работать как работали и это в разы проще, чем спользовать решения на Three.js.

Кстати, прикольный и уместный вариант использования SVG-фильтров на контенте мы с вами уже наблюдали на примере... PornHub: https://xn--r1a.website/htmlshit/1416

#svg #filters #html #shaders
👍52
#такое дня

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

Теперь в Chrome дефолтные стили для тегов b и strong не bold, а... bolder!

Пруф: https://github.com/chromium/chromium/commit/0f34660cbc02352d5deabbf135c4b07303979df5

Судя по дате изменения, это как раз улетело в последнюю (135) версию Chromium и Chrome, соответственно.

Казалось бы, какое мелкое изменение, но уже принесло людям проблем :) А главное, посмотрите сколько тестов!

Да-да, тестов там сильно больше, чем в твоём PR, который меняет вообще всё в проекте.

Ладно, а что кроется-то за этим изменением?

А кроется имплементация последних изменений в спеке: https://html.spec.whatwg.org/multipage/rendering.html#phrasing-content-3

Ведь задача strong и b — выделить текст во что бы то ни стало. А если он уже полужирный? То-то и оно.

Или ещё хуже, глядите, на span стоит font-weight: 100: https://codepen.io/alinaki/pen/XJJrEPo

Видите отличия? Я — нет.

Ладно, кроме шуток, объяснение на MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight#meaning_of_relative_weights

Если 700 на родителе — то 800 на strong/b и так далее.

Чудны дела твои, HTML. Упёрлось же кому-то...

Да, кстати, ещё существует lighter :)

P. S. Safari всё ещё использует bold, а Firefox — тоже bolder. Но когда конкретно Firefox внёс это изменение я пока не знаю.

P. P. S. normalize.css тоже всё приводит к bolder.

#html #bolder #bold
10👍4🤬4🫡3
#фишка дня

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

Буквально — используя параметры строки запроса (query string parameters).

Ну то есть что-то вроде https://buy.that?title=Product&action=buy&config=2&amount=3, классические GET-параметры, но управляемые с фронта.

А вот как позволить клиенту обновить страницу, сохранив эти параметры? Желательно, без лишней работы и без использования JS вообще.

А очень просто!

<a href="">Reload</a>

Да, вот так просто! Самое классное, что абсолютно валидно и есть в спеках: https://stackoverflow.com/questions/5637969/is-an-empty-href-valid/43340108#43340108

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

Не пишите лишнего, котаны!

#http #html #trick #бородач
👍224🤩1
#день_рождения дня

Сегодня День рождения не только лишь у меня, но и у HTML тегов!

29 октября 1991 года Тим Бернерс-Ли выкатил документ с названием HTML Tags.

И состоял он из описания 18 первых тегов: <title>, <nextid>, <a>, <isindex>, <plaintext>, <listing>, <p>, <h1>…<h6>, <address>, <hp1>, <hp2>…, <dl>, <dt>, <dd>, <ul>, <li>,<menu> и <dir>.

Архивная версия: https://www.w3.org/History/19921103-hypertext/hypertext/WWW/MarkUp/Tags.html

С Днём рождения, HTML! Ну и я :)

#html #бородач
50👍349🤩2
#инструмент дня

Ты тоже верстать умеешь лучше, чем рисовать? Say no more!

Библиотека Satori от небезызвестной компании Vercel умеет конвертировать почти любой HTML-макет в SVG: https://github.com/vercel/satori

Зачем это надо?

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

Короче, крутая штука же.

#svg #html #бородач
9👍5
#новость дня

Если нужно превратить HTML в картинку, приходится пользоваться утилитами разной степени кривизны — ведь нужно имитировать DOM. Cтабильного решения не было вообще (наверное, только Playwright и скриншот).

Теперь начинает появляться что-то вменяемое.

WICG выкатили идею под названием HTML-in-Canvas: холст учат рисовать обычные HTML-элементы: https://github.com/WICG/html-in-canvas

Прямо так, как браузер их и так рисует в DOM — со стилями, размерами, текстом, вложенностями. Только вместо того, чтобы показывать их на странице, он превращает элемент в картинку внутри <canvas>.

На самом деле, выглядит весьма проклято, вот пример с иллюстрации:


<canvas id="canvas" width="638" height="318" layoutsubtree="true">
<div id="drawElement" style="width: 550px;">
Hello from <a href="https://github.com/WICG/html-in-canvas">html-in-canvas</a>!
<br>I'm multi-line, <b>formatted</b>,
rotated text with emoji (&#128512;), RTL text
<span dir=rtl>من فارسی صحبت میکنم</span>,
vertical text,
<p style="writing-mode: vertical-rl;">
这是垂直文本
</p>
an inline image (<img width="150" src="wolf.jpg">), and
<svg width="50" height="50">
<circle cx="25" cy="25" r="20" fill="green" />
<text x="25" y="30" font-size="15" text-anchor="middle" fill="#fff">
SVG
</text>
</svg>!
</div>
</canvas>


Почему нельзя просто API для DOM? Потому что там целая плеяда сесурити-специалистов выступает против.

Работает это пока только в Chrome Canary от 138 и выше, и включать надо отдельный флаг. Плюс есть ограничения: рендерятся только те элементы, которые лежат внутри самого канваса, и некоторые штуки браузер сознательно блокирует — типа чужих iframe или странных SVG. Но в целом — оно работает.

Флаг, кстати, такой: --enable-blink-features=CanvasDrawElement.

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

#html #canvas
8👍4
#статья дня

Ну что же, пора просыпаться от зимней спячки, котаны! Салаты съедены, сериалы отсмотрены. Плавно готовимся к неизбежному.

В моей предыдущей компании были очень популярны турниры по настольному футболу, aka foosball. Не до драк, конечно, но со своим лором, правилами и даже традициями. Например, проигравший увековечивал своё имя под столом.

Так вот, к чему это я.

Помню, мы использовали какой-то сервис для составления турнирных таблиц. Я какое-то время даже планировал его склонировать, но руки не дошли. А тут наткнулся на интересную реализацию деревьев диаграмм. Ну или блок-схем, если хотите. Как раз похожих на турнирные таблицы.

Как вам такое: отрисовка дерева с помощью... списков!

Вот, глядите: https://codepen.io/alinaki/pen/ZYOOWOL

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

Начало тут: https://fractaledmind.com/2018/03/05/css-tree/

Ну что, будем таки писать такой сервис? Или максимально гибкая отрисовка на холсте наше всё?

#css #html #tree #list
6