<divelopers> – Telegram
<divelopers>
1.03K subscribers
21 photos
253 links
Рандомные мысли про HTML, CSS, доступность, пользовательские интерфейсы, производительность, браузеры и веб-стандарты.

Автор: @alexnozer
Download Telegram
Вопросы с собеса

Человек в твиттере опубликовал некоторые вопросы про HTML, которые ему задавали на собеседовании. Я постарался на них ответить без использования каких-либо источников.

как сказать пользователю, что js выключен?


Чтобы сообщить пользователю о неработающем js можно использовать элемент <nonoscript>. Его содержимое отображается только тогда, когда js отключён или недоступен по каким-либо причинам.

что будет если убрать тег DOCTYPE?


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

какие теги могут быть в head и зачем?


В <head> могут быть:
<noscript> - заголовок окна браузера
<base> - базовый адрес
<meta> - метаданные
<link> - гиперссылка на ресурс
<style> - инлайн-стили
<noscript> - скрипты, как инлайном, так и внешние

какие атрибуты у тега noscript?


У <noscript> есть следующие атрибуты:
src - путь к файлу
type - тип скрипта, module или importmap
nomodule - скрипт не нужно обрабатывать как модуль
async - загружать скрипт асинхронно, выполнить при загрузке
defer - загружать скрипт асинхронно, выполнить в конце
integrity - хэшсумма для проверки файла
crossorigin - управление междоменными запросами
глобальные атрибуты - все другие атрибуты, которые можно указать у любых элементов

как с помощью тега span вывести подсказку?


Не совсем понял, что имеется ввиду под подсказкой. Но допустим первый способ - добавить атрибут noscript, второй способ - добавить кнопку и использовать Popover API для отображения подсказки.
🥰4👍1🔥1🥴1
"Доступность — это определённый уровень вашего сервиса. Это не бонус, не особые потребности и не то, что можно предложить по запросу — так просто должно быть."

Полностью согласен с этим тезисом.

https://habr.com/ru/companies/rtlabs/articles/741906/
👍72
Invokers API

Новое предложение от группы OpenUI - Invokers. Это декларативный способ привязать кнопку к какому-то элементу на странице и указать действие, которое будет вызвано при взаимодействии с этой кнопкой. На самом деле это довольно частая задача, чтобы при клике на кнопку с другим элементом что-то происходило. Примеров много: бургер-меню, модальное окно, выпадающее меню, переключение вкладки, смена слайда в галерее, отображение подсказки и т.д.

OpenUI предлагает добавить кнопкам (<button>, <input type="button"> и <input type="reset">) два новых атрибута:
1) invokertarget - цель действия, принимает id элемента, с которым что-то должно произойти.
2) invokeraction - название действия, которое необходимо выполнить.

<button invokertarget="my-video" invokeraction="playpause">Play/Pause</button>
<button invokertarget="my-video" invokeraction="toggleMuted">Mute/Unmute</button>

<video id="my-video" src="video.mp4"></video>


invokeraction можно не указывать, тогда подразумевается значение auto, при котором вызываются стандартные действия в зависимости от элемента. Для <dialog> и [popover] это будет открытие или закрытие, для <audio> и <video> - пауза и воспроизведение.

<button invokertarget="my-dialog">This opens a dialog</button>

<dialog id="my-dialog">This is the dialog</dialog>


Также можно указать действие в виде ключевого слова, которое будет соответствовать (скорее всего) названию метода элемента. Например, кнопке-крестику внутри <dialog> можно указать invokeraction="close", что будет вызывать метод close() у <dialog>.

<button invokertarget="my-dialog">Open dialog</button>

<dialog id="my-dialog">This is the dialog
Hello world!

<button invokertarget="my-dialog" invokeraction="close">Close</button>
</dialog>


А что, если метода нет? Тогда ничего не произойдёт. Но можно подписаться на событие invoke, в обработчике которого можно прочитать действие из invokeraction и предпринять какие-то действия с элементом. Это также может быть хорошей альтернативой для делегирования событий.

<button invoketarget="my-custom">Invoke a div... to do something?</button>
<button invoketarget="my-custom" invokeaction="frobulate">Frobulate</button>

<div id="my-custom"></div>

<noscript>
document.getElementById("my-custom").addEventListener("invoke", (e) => {
if (e.action === "auto") {
console.log("invoked an auto action!");
} else if (e.action === "frobulate") {
alert("Successfully frobulated the div");
}
});
</noscript>


Событие вызывается при клике мышкой, нажатии клавиш Enter или Space, касании пальцем на тач-устройствах. А если хочется не по нажатию, а по наведению? Для этого предусмотрены атрибуты interesttarget и interestaction. Работают так же, как и invoker*, но только по ховеру.

<button interesttarget="my-popover">Open Popover</button>

<div id="my-popover" popover="hint">Hello world</div>


Для консистентности эти атрибуты в скором времени должны заменить атрибуты из Popover API, такие как popovertarget и popoveraction, поскольку они повторяют логику invoker* и interest*. Какое-то время будут работать оба, после чего popover* объявят deprecated.

С точки зрения accessibility, у кнопки с этими атрибутами будет неявно установлены соответствующие aria-атрибуты: aria-controls, aria-details и aria-expanded в зависимости от типа целевого элемента.

Более подробно и с примерами можно ознакомиться в черновике предложения OpenUI. Когда этого ждать? Chrome и Firefox уже взяли это в работу, со временем остальные браузеры должны подтянуться.
👍62🔥1
Alpine.js, Qwik, Lit и Stencil

Краткий обзор:

Alpine.js

Это, скорее, библиотека, нежели фреймворк. Коротко описал бы как Vue на минималках для улучшения готовой разметки и добавления в неё интерактивности за счёт атрибутов, очень похож на petite-vue. Часто используется в связке с Laravel и Livewire.

Qwik

Базируется на идеях React, имеет по сути тот же синтаксис, но иначе работает под капотом и предлагает делить приложение на маленькие чанки и динамически подгружать их только при взаимодействии с компонентами. Тем самым предлагает улучшенный load performance.

Lit

Фреймворк для веб-компонентов и приложений на их основе, предлагает удобные абстракции и DX. Вырос из Polymer. Максимально базируется на веб-стандартах. На Lit разрабатывают YouTube, Chrome DevTools и разные библиотеки компонентов.

Stencil

Компилятор веб-компонентов от команды Ionic. По своей идее похож на Lit, но фокусируется именно на создании отдельных веб-компонентов, а не на разработке веб-приложений. Активно использует ts и декораторы. Может быть интегрирован в React, Angular и Vue.
👍61
Semantics for newbies

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

https://zavsievich.github.io/semantics-for-newbies/
🔥6👍21
Веб-компоненты

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

Google вкладывается в веб-компоненты с самого их появления. Началось все с библиотеки Polymer, из которой вырос Lit. При помощи Lit сейчас разрабатывается YouTube, DevTools и интерфейс Chrome в целом, а недавно веб-компоненты добавили в Maps API. Кроме того, Angular имеет хорошую поддержку. Можно как использовать сторонние веб-компоненты, так и создавать свои при помощи Angular Elements. Также Google разрабатывает 3ю версию Material Design с использованием веб-компонентов.

Microsoft так же делает ставку на веб-компоненты. Они разработали свою библиотеку FAST и дизайн-систему Fluent UI. Сейчас они используются на таких проектах, как MSN, Bing, VS Code, Edge и некоторых других.

Adobe активно использует веб-компоненты в Photoshop Web. Кроме того, они разработали дизайн систему Spectrum на основе веб-компонентов и используют её в некоторых своих проектах.

Salesforce предлагает партнёрам разрабатывать UI для своих решений при помощи собственной разработки - библиотеки Lightning Web Components, построенной поверх веб-компонентов.

IBM добавила поддержку веб-компонентов в свою дизайн-систему Carbon. Аналогично поступили SAP в своей дизайн-системе UI5. Другие компании тоже используют веб-компоненты: Red Hat, Nord, Siemens, Clever Cloud, GitHub, Netflix и тд.

Некоторые компании строят бизнес на веб-компонентах. Так, финская компания Vaadin предлагает одноимённый фреймворк для разработки enterprise-приложений, в основе которого Java и веб-компоненты.

Стоит упомянуть также и независимые библиотеки веб-компонентов. Одна из таких - Shoelace. Она предлагает хорошо проработанные, доступные и кастомизируемые компоненты.

Веб-компоненты используются более чем активно. Поэтому утверждение, что они никому не интересны - не верно. Просто их активно не рекламируют, как фреймворки. Это браузерный стандарт, который просто берут и используют.
👍61🔥1
CSS4 быть!

Как и CSS5. Идея добавить "версию" к CSS была выдвинута ещё в 2020 году. С тех пор периодически обсуждалась. Но не так давно прошло собрание рабочей группы CSS, на котором было принято решение об утверждении CSS4, CSS5 и CSS Next.

Немного истории

На данный момент у HTML и CSS нет версий. Стандарты являются "живыми" и развиваются постоянно, вместо того, чтобы накапливать фичи и раз в некоторое время делать релиз новой версии. Например, стандарт HTML обновлялся сегодня (14 января 2024). Отсутствие версий позволяет постоянно развивать фичи и делать это параллельно. Так, CSS разделён на модули (Grid Module, Display Module, Font Module и т.д.), которые развиваются независимо и имеют свой уровень. Уровень отражает доработки предыдущего и новые фичи.

Возвращаясь к версиям

Последними стандартами с версиями были HTML5 и CSS3. После сосредоточились на развитии живых стандартов. Но релиз новых версий оказал огромное влияние на веб. Если гуглить HTML и CSS, то увидите знакомый оранжевый логотип с цифрой 5 и синий с цифрой 3. W3C даже сделали целый сайт и рекламную кампанию для HTML5. В это время появилось старое и новое, многие задумались о том, чтобы переписать свои сайты на свежие версии. HTML5 и CSS3 появились в вакансиях и резюме и стали уже нарицательными.

С тех пор в HTML и CSS появилось много нового, но нововведения растянуты по времени и внедрены в рамках живых стандартов. То есть у нас всё ещё HTML5 и CSS3. И вот разработчики стандартов решили заняться техномаркетингом и добавить "новые версии" для привлечения внимания. И так:
- CSS3 - последняя версия (~2009-2012)
- CSS4 - фичи, которые мы уже используем: custom properties, flexbox, grid, calc и т.д. (~2013-2018)
- CSS5 - новые фичи: container queries, цветовые пространства, has, view transition, nesting, и т.д. (~2019-2024)
- CSS Next - будущее.

Это ни коим образом не влияет на то, как разрабатываются сами стандарты. Они по-прежнему будут живыми, без версий. CSS4 и CSS5 - это брендинг для новых фич, чтобы стимулировать сообщество их изучать и внедрять, обновлять сайты и учебные программы. Так что готовимся править CV.
🤔32👌2
CSS Wrapped 2023

Вышел CSS Wrapped 2023 с обзором фич, которые появились за этот год. На мой взгляд это огромный прогресс в развитии CSS. Не все фичи получили кроссбраузерную поддержку, но в Chrome и Edge последних версий все они доступны, а это большая доля рынка.
👍4
Радиокнопки на градиентах

София Валитова в своём блоге рассказывает про стилизацию <input type="radio"> при помощи градиентов, без лайфхаков с псевдо-элементами и <label>.

https://ru.ariarzer.dev/2023/tutorials/gradient-radio/
👍2🔥2
Доступность и торты

Забавная мультипликация про торты и доступность от команды Microsoft Bing 🎂

https://www.youtube.com/watch?v=HE2R86EZPMA
2👏1
Вас уже больше сотни! 💯
Всем огромное спасибо!

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

Представьте ситуацию: вы заполняете большую форму, например, оформляете заказ в интернет-магазине, покупаете билет на концерт, пишете запрос в техническую поддержку продукта или отзыв на услугу. И вот, вы хотите ввести что-то и случайно вместо цифры на клавиатуре нажимаете F5, задеваете тачпад и нажимаете на ссылку, свайпом от края экрана вызываете действие "назад" на мобильном. В результате данные потеряны. Те, кто писал курсовые и дипломные работы в Word, понимают всю боль, когда "Приложение Word не отвечает".

Если вы разрабатываете форму, особенно большую, то примите ряд мер по предотвращению потери введённых данных. Тем более, эти меры достаточно простые.

Запрос на перезагрузку страницы.

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

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

Сохранение введённых данных.

При вводе данных в форму подпишитесь на одно из событий (input, change), считывайте все текущие данные с полей и сохраняйте их в локальное хранилище (LocalStorage, IndexedDB). При использовании <form> и стандартных полей ввода, вы можете получить объект FormData, сериализовать его в JSON-строку и сохранить.

При случайном обновлении страницы сообщите пользователю, что в браузере есть сохранённые ранее данные, которые можно восстановить, и добавьте в начале формы кнопку, при клике на которую достаньте данные из хранилища и заполните ими форму.
👍101
Режим чтения

В Chrome 120.0.6099.144 появилась иконка для включения режима чтения, он же упрощённый режим. Раньше его можно было включить во всплывающем окне, но оно отображалось не на каждой странице. В других браузерах есть аналогичный режим, в том числе и на десктопных.

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

Полезная фича для контентных сайтов, которая позволяет удобно читать контент без лишних элементов и рекламы, настраивать его под себя, отключать неудобные стили и скрипты. Чтобы это хорошо работало, страница должна быть семантически свёрстана, об этом как-нибудь тоже расскажу.
👍42
Alt картинок:
1) Скриншот сайта smashing magazine в браузере Chrome на Android. Возле строки поиска расположена кнопка с иконкой телефона, на котором отображен текст. Кнопка включает режим чтения.

2) Скриншот сайта smashing magazine в браузере Chrome на Android в режиме чтения. Лишние элементы интерфейса скрыты, контент отображается в оттенках сепии, шрифтом без засечек, со 100% размером текста.

3) Скриншот сайта smashing magazine в браузере Chrome на Android в режиме чтения. Открыто меню настроек режима чтения. Доступные опции: Найти на странице, Внешний вид, Перевести...

4) Скриншот сайта smashing magazine в браузере Chrome на Android в режиме чтения. Открыто всплывающее окно настроек режима чтения. Вверху три кнопки выбор цветовой схемы: Светлая, Тёмная и Сепия (выбрана). Под кнопками выпадающий список для выбора типа шрифта, выбрана опция Без засечек. Под списком ползунок для изменения размера шрифта, установлен на 100%.
👍42
Забытый скроллбар

Последнее время я часто стал замечать на сайтах горизонтальный скроллбар буквально на десяток пикселей. Всё дело в разработчиках на MacOS. Сейчас объясню.

Дело в том, что поведение скроллбара на MacOS и Window отличается. На MacOS скроллбар отображается поверх страницы и не занимает места. А на Windows скроллбар при стандартных настройках занимает 17px.

В CSS есть замечательная единица vw — ширина текущего вьюпорта. Разработчики на MacOS используют эту единицу, чтобы растянуть блок на всю ширину экрана. И у них всё хорошо. А на Windows блок растянется на всю ширину и к нему прибавится ещё 17px для вертикального скроллбара. В итоге и появляется тот самый горизонтальный скроллбар, потому что блок превысил ширину вьюпорта на эти 17px.

Как быть? Тестировать проект не только на MacOS, но и в других системах при помощи Browserstack, LambdaTest, виртуальной машины или реальных устройств.

А для CSS есть лайфхак. Ширину скроллбара можно вычислить:

body {
--sb: calc(100vw - 100%);
}
Мы от ширины текущего вьюпорта (например, 1920px) отнимаем 100% ширины <body>, которая как раз включает всё, кроме скроллбара (1903px). Разница — и есть ширина скроллбара (17px). Чтобы это работало правильно, у <body> не должно быть горизонтальных margin и padding, и width должен быть стандартным, то есть 100%. Все эти условия соблюдаются в 99% случаев, поэтому этот хак можно использовать.

.full-width-block {
width: calc(100vw - var(--sb));
}
Это будет работать, потому что все элементы вложены в <body> и будут наследовать объявленное в нём кастомное свойство
--sb.

Другой лайфхак заключается в том, чтобы объявить свой настоящий vw, в котором будет учитываться скроллбар:

body {
  --sb: calc(100vw - 100%);
--vw: calc(100vw - var(--sb));
}

.full-width-block {
width: var(--vw);
}
На MacOS и мобильных устройствах, где скроллбар плавающий, его ширина будет равна 0, поэтому все эти формулы там тоже будут работать. Ссылка на демку codepen, которую можно открыть на разных устройствах и протестировать.
👍15❤‍🔥8🔥4
Дополнение к посту выше ⬆️

В MacOS есть настройка, которая переключает режим отображения скроллбара. Можно сделать так, чтобы он занимал место (16px), как в Windows. Делается это в настройках (Settings →Appearance). При этом подход, приведённый в предыдущем посте, тоже будет работать.
👍6
Подключение шрифтов с Google Fonts

Скорее всего, вы подключаете на сайт сторонние шрифты. Если сайт небольшой, то, скорее всего, вы найдёте шрифт на Google Fonts, скопируете сниппет и вставите его в <head>:

<head>
<!-- ... -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet">
</head>


Шрифт подключится, всё будет работать (при условии указания font-family). Но что на самом деле тут происходит и зачем нужны все эти теги? Тут стоит сделать отступление и разобраться, как работает сеть. Чтобы загрузить что-то с удалённого сервера, браузеру нужно:
1) найти URL
2) определить тип ресурса
3) разбить URL на составляющие (схема, домен, путь, параметры и т.д.)
4) определить IP-адрес сервера по имени домена (DNS Lookup)
5) "поздороваться" с сервером (TLS Handshake)
6) обменяться ключами безопасности (SSL)
7) запросить ресурс
8) подождать ответа от сервера
9) скачать ресурс
10) обработать ресурс

Вернёмся к сниппету.

<link rel="preconnect" href="https://fonts.googleapis.com"> 

Сообщает браузеру, что нужно заранее подключиться к домену fonts.googleapis.com. Выполняются этапы 1-6, чтобы при последующих обращениях к этому домену не делать лишнюю работу и не тратить время. На этом домене расположен сервер, который генерирует шрифты по указанным параметрам и CSS-файл с директивами @font-face, которые и подключают шрифт.

<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 

Делает то же самое, но уже к домену fonts.gstatic.com и в режиме CORS. Это домен CDN, на которых лежат сгенерированные файлы шрифтов.

<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet">

Обращается к серверу за итоговым CSS-файлом. Так как к этому домену мы уже заранее подключились, то запрос происходит быстрее и начинается сразу с 7 этапа. Далее браузер разбирает этот файл, находит URL и делает запрос за каждым подходящим шрифтом. И снова благодаря preconnect это происходит быстрее.

Помимо всего прочего, каждый запрос к доменам Google сопровождается передачей информации об устройстве, браузере, настройках и т.д. С одной стороны, эти данные используются, чтобы сгенерировать оптимальный шрифт (для новых браузеров woff2, для старых woff, ttf, eot). С другой стороны, Google есть Google и их основной доход - продажа данных рекламодателям.

Итого имеем: два запроса на предварительное соединение, один запрос за CSS, запросы за шрифтами и передача данных. Вместо этого сделайте следующее:
1) скачайте CSS-файл с определением @font-face по ссылке, которую сгенерировал Google
2) скачайте нужные шрифты из этого файла
3) положите CSS-файл рядом с другими стилями или скопируйте код в ваш файл стилей
4) положите шрифты рядом с проектом
5) удалите все <link> от Google Fonts

Это улучшит время загрузки шрифтов и перформанс, уменьшит количество запросов, уберёт необходимость в предварительном подключении и не будет передавать данные в Google.
12👍5🔥2