Декларативность и сотрудничество в HTML
#HTML #Лаборатория_веб_платформы
Есть некоторые клёвые API в HTML/CSS, которые прям доставляют. Чтоб решить задачу, вместо императивщины сообщаешь браузеру нужную инфу, а он делает всю остальную работу.
Хочу рассказать про
Частый кейс — указание обычной или ретиновой версии картинки. Браузер на этапе загрузки картинки ещё не знает какого она будет размера. Зато при загрузке картинки у браузера уже есть информация, что за экран у устройства: обычный или ретиновый. Поэтому разработчик подсказывает ему: вот эта картинка поменьше — для обычной плотности пикселей (1x), а вот эта картинка побольше — для большей (2x):
Браузер получает подсказку от разработчика, какая картинка для какого экрана подходит, и сам делает выбор: если экран ретиновый, грузит 2x-версию, а иначе — 1x.
Более сложная логика описания
При загрузке картинки у браузера уже есть информация, какой размер вьюпорта на устройстве. А у разработчика есть инфа, какая картинка какому размеру соответствует. То есть разработчик заранее подказывает браузеру: вот эта картинка шириной 100px, вот эта — 500px, а вот эта — 1000px.
Браузер руководствуется подсказкой разработчика и делает выбор: ага, сейчас вьюпорт десктопный >1000px, поэтому беру
Но картинки не всегда показываются на всю ширину вьюпорта! Ок, браузер выбрал картинку
Поэтому браузеру нужна ещё и инфа, которую заранее знает разработчик: какую часть вьюпорта будет занимать картинка, когда страница полностью загрузится. Например, на мобильном разрешении картинка будет на весь экран, а на более широком разрешении три картинки выстроятся в ряд и будут занимать каждая 1/3 размера вьюпорта.
Эту инфу и сообщаем браузеру в атрибуте
Таким образом у браузера есть все вводные для принятия решения: размер вьюпорта и плотность экрана (браузер знает сам), собственные размеры картинок и их размер на экране (разработчик сообщил в
И дальше браузер сам принимает решение, какую картинку выбрать. А разработчику не нужно плясать с императивными конструкциями
Вроде всё классно, если разобраться, как это работает. Только вот если не разобраться, то выходит не очень: у
Выходит так, что фича классная, но если не въехать, как она работает, то толку нет — пользователь будет получать слишком большие картинки там, где мог получить меньшие.
#HTML #Лаборатория_веб_платформы
Есть некоторые клёвые API в HTML/CSS, которые прям доставляют. Чтоб решить задачу, вместо императивщины сообщаешь браузеру нужную инфу, а он делает всю остальную работу.
Хочу рассказать про
srcset и sizes у <img>. Для чего они нужны? Прежде всего — подсказать браузеру, какую версию картинки начать загружать, когда только парсится HTML, и браузеру ещё ничего неизвестно о лейауте страницы. Браузер будет полагаться на подсказки, оставленные разработчиком, и исходя из них начинать сразу же загружать нужную картинку, не дожидаясь полного окончания парсинга страницы и применения стилей.Частый кейс — указание обычной или ретиновой версии картинки. Браузер на этапе загрузки картинки ещё не знает какого она будет размера. Зато при загрузке картинки у браузера уже есть информация, что за экран у устройства: обычный или ретиновый. Поэтому разработчик подсказывает ему: вот эта картинка поменьше — для обычной плотности пикселей (1x), а вот эта картинка побольше — для большей (2x):
src="picture1.jpg"
srcset="picture1.jpg 1x,
picture2.jpg 2x"
alt=""
>
Браузер получает подсказку от разработчика, какая картинка для какого экрана подходит, и сам делает выбор: если экран ретиновый, грузит 2x-версию, а иначе — 1x.
Более сложная логика описания
srcset нужна, если разработчик хочет предусмотреть, что на разных разрешениях экрана должны загружаться картинки разного размера.При загрузке картинки у браузера уже есть информация, какой размер вьюпорта на устройстве. А у разработчика есть инфа, какая картинка какому размеру соответствует. То есть разработчик заранее подказывает браузеру: вот эта картинка шириной 100px, вот эта — 500px, а вот эта — 1000px.
src="default.jpg"
srcset="small.jpg 100w,
medium.jpg 300w,
large.jpg 1000w"
alt=""
>
Браузер руководствуется подсказкой разработчика и делает выбор: ага, сейчас вьюпорт десктопный >1000px, поэтому беру
large.jpg и загружаю. Если бы вьюпорт был поменьше, то была бы загружена соответствующая более мелкая версия картинки.Но картинки не всегда показываются на всю ширину вьюпорта! Ок, браузер выбрал картинку
large.jpg, так как вьюпорт был >1000px. А на самом деле картинка после загрузки стилей будет показана не на всю ширину вьюпорта, а вписана в блок шириной 300px. Об этом браузер не мог знать заранее, на этапе, когда он встретил при парсинге разметки тег <img>, и поэтому сделал неверное предположение и загрузил слишком большую картинку.Поэтому браузеру нужна ещё и инфа, которую заранее знает разработчик: какую часть вьюпорта будет занимать картинка, когда страница полностью загрузится. Например, на мобильном разрешении картинка будет на весь экран, а на более широком разрешении три картинки выстроятся в ряд и будут занимать каждая 1/3 размера вьюпорта.
Эту инфу и сообщаем браузеру в атрибуте
sizes: начиная с 1000px картинка будет занимать треть размера вьюпорта 33.3vw, а в остальных случаях — весь вьюпорт 100vw:sizes="(min-width: 1000px) 33.3vw, 100vw"
Таким образом у браузера есть все вводные для принятия решения: размер вьюпорта и плотность экрана (браузер знает сам), собственные размеры картинок и их размер на экране (разработчик сообщил в
srcset и sizes).И дальше браузер сам принимает решение, какую картинку выбрать. А разработчику не нужно плясать с императивными конструкциями
<picture>, что именно и когда именно браузеру показывать.Вроде всё классно, если разобраться, как это работает. Только вот если не разобраться, то выходит не очень: у
sizes по умолчанию значение 100vw. То есть если не указать sizes, а указать только srcset, то браузер будет думать, что картинки всегда на всю ширину вьюпорта, а это часто не так.Выходит так, что фича классная, но если не въехать, как она работает, то толку нет — пользователь будет получать слишком большие картинки там, где мог получить меньшие.
❤2
#Пульс_веб_платформы 17.01.2025
Новости
🔡 вышел Chrome 132:
🔵 улучшены события и исправлены баги для элементов popover и dialog
🔵 заголовки Strict-Transport-Security (STS) теперь игнорятся для localhost
🔵 довыкатили Keyboard focusable scroll containers, которые раньше забаговали
🔵 File System Access API стало доступно на Android-девайсах и WebView
🔡 вышел Firefox 134.0:
🔵 поддержан Promise.try(), теперь он кроссбраузерный
🔵 экспериментально добавлена поддержка Intl.DurationFormat
🔵 поправлен баг с применением align-self и justify-self к абсолютно позиционированным элементам
🔡 в Node.js v22.13.0 стабилизирована фича Permission Model: это «ремень безопасности» для вашего кода, а не защита от чужого вредоносного кода; запуск файла с флагом
🔡 в Bun v1.1.43 появился экспериментальный HTML Bundler: команда
🔡 WinterCG, группа разрабочиков Deno, слилась с Ecma International, сформировала новый комитет TC55 и выпустила первый черновик их стандарта Minimum Common Web Platform API, где собраны список базовых API для конситентности между разными JS-райнтаймами
🔡 в React-е (и Next-е) появится первое API про анимацию — компонент
Проекты
🔡 emojico — cli-тула для генерации набора favicon-ок из эмодзи: под капотом буднично открывается puppeteer и снимается скриншот со страницы с иконкой
🔡 @smoores/epub — оказывается формат электронных книг epub — открытый стандарт W3C, и это либа для работы с epub-файлами
🔡 react-focus-lock — «ловушка» фокуса при показе модалок
Статьи и демки
JS
🔡 спред объекта/массива в объекте не скопирует его, а создаст ссылку на него
🔡 доля ESM-only и dual (ESM + CJS) npm-пакетов медленно, но верно растёт: в ноябре 2024 у CJS 63%, у dual + ESM 25%
🔡 напоминание для реактоводов: рефы обрабатываются до
CSS
🔡 псевдокласс
🔡 бонус использования нативного
Платформа
🔡 в современных браузерах изменился подход к кешированию ресурсов: если раньше файл мог быть единожды закеширован по урлу и потом для другого сайта браться из общего кеша
🔡 для базовой доступности достаточно использовать теги по назначению (кнопки, формы, лейблы + инпуты), не убирать стили фокуса, при открытой модалке ловить фокус и «выключать» контент под ней атрибутом
@web_platform | Поддержать канал 🤝
Новости
node --permission index.js по умолчанию обрежет все права (чтение и запись в fs, порождение процессов…), а указание явных флагов типа --allow-fs-read и --allow-fs-write уже включит только нужное bun build --experimental-html --experimental-css ./index.html --outdir=dist склеит все js-, css-файлы и ассеты в один файл и подключит их в итоговом html-файле<ViewTransition> на основе View Transitions API (не поддерживается только в FF), обещают удобство в работе с Suspence, под капотом React будет в определённый момент назначать элементу view-transition-name и вызывать startViewTransition во время мутации DOM-а:
<ViewTransition>
<Suspense fallback={<Skeleton />}>
<Content />
</Suspense>
</ViewTransition>
Проекты
Статьи и демки
JS
const state = { ...defaultState, prop: value } — это механизм Shallow Copy; если же нужно именно склонировать объект, то в современном JS для этого есть специальный метод structuredClone (поддерживается везде с 2022):
const state = structuredClone(defaultState);
state.prop = value;
useLayoutEffect и useEffectCSS
:empty помогает скрыть элементы с пустым контентом (правда пока что в браузеры не доехало обновление спеки по этому поводу, то есть блок с пробелами скрыт не будет):
.list > div:empty {
display: none;
}
<dialog> — его части легко стилизовать: подложка dialog::backdrop {}, убирание скролла body:has(dialog[open]) { overflow: hidden }Платформа
"https://cdn.example.com/jquery-3.6.0.min.js": resourceData, то теперь для защиты от отслеживания для каждого сайта кеш файла будет храниться отдельно { topLevelSite: "site-a.com", resource: "https://cdn.example.com/jquery-3.6.0.min.js" }: resourceData; как следствие — больше нет выгоды от CDN, дешевле селф-хостить на своём домене типа static.company.com/js/react.jsinert, расширять область клика на интерактивных элементах@web_platform | Поддержать канал 🤝
Please open Telegram to view this post
VIEW IN TELEGRAM
❤14👍11🔥5❤🔥1