Маркдаун-версия страницы для ИИ-агентов может утечь в браузер живого пользователя
По вашим страницам уже ходят ИИ-агенты, и каждая обходится им в токены. Медиана по 300 сайтам: 2592 токена на страницу по извлечённому тексту, без скриптов и стилей. Около половины из них не тело статьи: пятая часть это навигация, шапка и подвал, остальное повторы.
Семь сайтов из 300 отдают машинному читателю маркдаун-версию, и та же страница стоит уже 962 токена. Но у шести из семи нет заголовка
Досталось и документации Cloudflare про эту самую фичу: там обе проблемы сразу. Я забрал этот замер себе как чеклист: раздаёте контент по
По вашим страницам уже ходят ИИ-агенты, и каждая обходится им в токены. Медиана по 300 сайтам: 2592 токена на страницу по извлечённому тексту, без скриптов и стилей. Около половины из них не тело статьи: пятая часть это навигация, шапка и подвал, остальное повторы.
Семь сайтов из 300 отдают машинному читателю маркдаун-версию, и та же страница стоит уже 962 токена. Но у шести из семи нет заголовка
Vary: Accept: кэш перед сайтом не знает, что ответ зависит от запрошенного формата, и может отдать маркдаун браузеру или HTML агенту. Ломается тихо, в логах не видно.Досталось и документации Cloudflare про эту самую фичу: там обе проблемы сразу. Я забрал этот замер себе как чеклист: раздаёте контент по
Accept — сверьте Vary и проверьте, не выпал ли из маркдаун-версии текст страницы. У трёх сайтов из семи выпал.❤2🔥1
Ваш блок отцентрован идеально, но у читателя с боковой панелью он съедет вправо
Привычный body { display: grid; place-items: center } центрирует колонку внутри вебвью. А вебвью это не окно: боковая панель Arc или Vivaldi забирает ширину слева, и колонка встаёт заметно правее реального центра экрана.
Автор блога seg6.space считал поправку как window.outerWidth - window.innerWidth: разница даёт ширину интерфейса браузера, а блок сдвигается на её половину через translate. Схема сломалась на открытых справа DevTools: сумма та же, а как она поделена между левой и правой панелью, из двух чисел не вытащить. Недостающую координату он добыл из событий указателя.
#css #фронтенд
Привычный body { display: grid; place-items: center } центрирует колонку внутри вебвью. А вебвью это не окно: боковая панель Arc или Vivaldi забирает ширину слева, и колонка встаёт заметно правее реального центра экрана.
Автор блога seg6.space считал поправку как window.outerWidth - window.innerWidth: разница даёт ширину интерфейса браузера, а блок сдвигается на её половину через translate. Схема сломалась на открытых справа DevTools: сумма та же, а как она поделена между левой и правой панелью, из двух чисел не вытащить. Недостающую координату он добыл из событий указателя.
#css #фронтенд
❤3👍3
Ноль ошибок в автопроверке доступности ещё не значит, что сайтом можно пользоваться
Проверку доступности обычно вешают в CI и смотрят на цвет прогона: зелёный значит порядок. WebAIM восьмой год подряд гоняет по этой же логике главные страницы миллиона сайтов из рейтинга Tranco и выложил срез за февраль 2026 года: движок WAVE смотрит отрендеренный DOM, уже после скриптов и стилей, на провалы по WCAG 2.2 уровней A и AA.
При этом авторы сами очерчивают границу метода: автоматика находит не все нарушения, и пустой отчёт не означает, что страницей можно пользоваться. Так что зелёный прогон закрывает часть, остальное ловится руками и скринридером.
Попробуйте с формы Site Lookup на странице отчёта: вбиваете свой домен и видите, что WAVE нашёл именно у вас. Этот список удобно брать, как отправную точку для ручной проверки.
#фронтенд
Проверку доступности обычно вешают в CI и смотрят на цвет прогона: зелёный значит порядок. WebAIM восьмой год подряд гоняет по этой же логике главные страницы миллиона сайтов из рейтинга Tranco и выложил срез за февраль 2026 года: движок WAVE смотрит отрендеренный DOM, уже после скриптов и стилей, на провалы по WCAG 2.2 уровней A и AA.
При этом авторы сами очерчивают границу метода: автоматика находит не все нарушения, и пустой отчёт не означает, что страницей можно пользоваться. Так что зелёный прогон закрывает часть, остальное ловится руками и скринридером.
Попробуйте с формы Site Lookup на странице отчёта: вбиваете свой домен и видите, что WAVE нашёл именно у вас. Этот список удобно брать, как отправную точку для ручной проверки.
#фронтенд
❤3👍2
От аськи до биткоина, от Nokia 3310 до QR-кодов — пройди анкету и узнай, какой ты носитель информации!
❤4💩3
Ошибки в WebGPU-пайплайне теперь всплывают в редакторе, ещё до первого кадра
Рендер-пайплайн на WebGPU молчит до первого кадра: формат цели рендеринга не совпал с тем, что ждёт фрагментный шейдер, и на канвасе пусто, без единого сообщения.
Уго Даниэл 2,5 года делает pngine: обвязка WebGPU описывается S-выражениями, которые один в один повторяют спецификацию, а не собирается вызовами JS. Шейдеры и инициализация cpu/wasm лежат там же, и это не только про браузер: формат играется поверх rust wgpu, есть плееры под Android и iOS.
Конфигурацию pngine проверяет рефлексией WGSL и правилами спецификации, без живого WebGPU-контекста. Ошибки и предупреждения приходят во время набора текста, потому что у формата есть LSP.
Ещё демку можно выгрузить в один .png: картинка хранит байткод и сама ничего не запускает, но открывается крошечным плеером. Прототип рендера можно отдать коллеге картинкой.
Рендер-пайплайн на WebGPU молчит до первого кадра: формат цели рендеринга не совпал с тем, что ждёт фрагментный шейдер, и на канвасе пусто, без единого сообщения.
Уго Даниэл 2,5 года делает pngine: обвязка WebGPU описывается S-выражениями, которые один в один повторяют спецификацию, а не собирается вызовами JS. Шейдеры и инициализация cpu/wasm лежат там же, и это не только про браузер: формат играется поверх rust wgpu, есть плееры под Android и iOS.
Конфигурацию pngine проверяет рефлексией WGSL и правилами спецификации, без живого WebGPU-контекста. Ошибки и предупреждения приходят во время набора текста, потому что у формата есть LSP.
Ещё демку можно выгрузить в один .png: картинка хранит байткод и сама ничего не запускает, но открывается крошечным плеером. Прототип рендера можно отдать коллеге картинкой.
❤2
Forwarded from GameDev: разработка игр
Пружинящую деформацию модели в Three.js собирают на костях, а не на симуляции мягкого тела
Гнущийся объект в вебе обычно делают либо запечённой анимацией, которая не отвечает на ввод, либо симуляцией мягкого тела, которая съедает кадр.
В демке Codrops Эйфелева башня работает катапультой: тянешь её мышью, она гнётся и копит энергию, отпускаешь — и шар летит через Париж. Гибкость держит библиотека Wiggle: в модель встраивают цепочку костей, каждая догоняет родительскую по пружинному закону, поэтому объект качается в ответ на действие игрока, а не проигрывает готовый клип.
Париж вокруг собран не руками: город стримится из Cesium ion, это фотореалистичные 3D-тайлы Google. На стороне Three.js остаются анимация, столкновения и приземление.
Приём переносится на любую модель с костями: антенна, хвост, ветка. В статье остались расчёт траектории и стыковка геоданных с физикой.
Гнущийся объект в вебе обычно делают либо запечённой анимацией, которая не отвечает на ввод, либо симуляцией мягкого тела, которая съедает кадр.
В демке Codrops Эйфелева башня работает катапультой: тянешь её мышью, она гнётся и копит энергию, отпускаешь — и шар летит через Париж. Гибкость держит библиотека Wiggle: в модель встраивают цепочку костей, каждая догоняет родительскую по пружинному закону, поэтому объект качается в ответ на действие игрока, а не проигрывает готовый клип.
Париж вокруг собран не руками: город стримится из Cesium ion, это фотореалистичные 3D-тайлы Google. На стороне Three.js остаются анимация, столкновения и приземление.
Приём переносится на любую модель с костями: антенна, хвост, ветка. В статье остались расчёт траектории и стыковка геоданных с физикой.
❤2🔥2
Chrome прощает битую разметку, а скринридер на ней спотыкается, и проверить это можно за минуту
Страница открывается во всех браузерах, и на этом проверка разметки обычно заканчивается. Тео Дюкрё прогнал через открытые валидаторы 2656 живых главных страниц из топ-5000 доменов Tranco: полностью валидный HTML оказался у 12,8% сайтов, а без единого предупреждения свёрстаны 2,6%.
Сильнее всего это бьёт по доступности: 41,6% страниц не размечают регионы ARIA-метками, 20,4% сайтов оставляют картинки без alt. Chrome достроит структуру сам, а скринридер читает именно эту разметку и объявляет «iframe» там, где вы имели в виду навигацию.
Откройте вкладку Accessibility в devtools на своём главном шаблоне: если дерево регионов пустое, начните с
#html
Страница открывается во всех браузерах, и на этом проверка разметки обычно заканчивается. Тео Дюкрё прогнал через открытые валидаторы 2656 живых главных страниц из топ-5000 доменов Tranco: полностью валидный HTML оказался у 12,8% сайтов, а без единого предупреждения свёрстаны 2,6%.
Сильнее всего это бьёт по доступности: 41,6% страниц не размечают регионы ARIA-метками, 20,4% сайтов оставляют картинки без alt. Chrome достроит структуру сам, а скринридер читает именно эту разметку и объявляет «iframe» там, где вы имели в виду навигацию.
Откройте вкладку Accessibility в devtools на своём главном шаблоне: если дерево регионов пустое, начните с
header, nav и main, а картинки без alt поймает html-validate в CI. Цифры и методика в разборе DevClass.#html
❤2
Tailwind меняют на StyleX ради типизированных токенов, а спотыкаются на сборке
Вы прикидываете, стоит ли тащить StyleX в проект, и упираетесь в спор на уровне вкусов: типизация против скорости вёрстки. В LogRocket Blog этот спор закрыли практикой — собрали 20 компонентов на Tailwind, переписали на StyleX и замерили строки кода, вес CSS-бандла и время сборки.
Но полезнее цифр то, что вылезло по дороге:
• barrel-экспорты, когда всё отдаётся наружу через один
•
• динамические ключи стилей приходится расписывать явной таблицей соответствий;
• falsy-значения в массиве
Победителя автор не назначает: в разборе есть и настройки Webpack с Babel, и список мест, где Tailwind остаётся быстрее.
#css
Вы прикидываете, стоит ли тащить StyleX в проект, и упираетесь в спор на уровне вкусов: типизация против скорости вёрстки. В LogRocket Blog этот спор закрыли практикой — собрали 20 компонентов на Tailwind, переписали на StyleX и замерили строки кода, вес CSS-бандла и время сборки.
Но полезнее цифр то, что вылезло по дороге:
• barrel-экспорты, когда всё отдаётся наружу через один
index.ts, ломают разрешение токенов;•
@keyframes прямо внутри stylex.create() туда не принимаются;• динамические ключи стилей приходится расписывать явной таблицей соответствий;
• falsy-значения в массиве
sx не работают, так что привычное условие через && придётся переписать.Победителя автор не назначает: в разборе есть и настройки Webpack с Babel, и список мест, где Tailwind остаётся быстрее.
#css
❤2
Forwarded from Инструменты программиста
Neovim: терминальный редактор, который настраивается на Lua
Neovim — форк Vim для тех, кто правит код прямо в терминале и не хочет ставить туда полноценную IDE. От Vim отличается вменяемыми настройками по умолчанию и встроенной поддержкой Language Server Protocol: редактор сам получает от языкового сервера автодополнение, переход к определению и подсветку ошибок, и собирать это из плагинов не нужно.
Конфиг пишется на Lua и разбивается на модули, поэтому сложная настройка не превращается в один нечитаемый файл. Внутри есть свой эмулятор терминала, а большинство плагинов Vim продолжают работать.
Ставится на Linux, macOS (brew install neovim) и Windows. Пригодится, если вы часто редактируете файлы по ssh: подсветка ошибок и автодополнение будут и там, где графического редактора нет.
Установку и сборку первого конфига по шагам разбирают в The New Stack.
#инструменты
Neovim — форк Vim для тех, кто правит код прямо в терминале и не хочет ставить туда полноценную IDE. От Vim отличается вменяемыми настройками по умолчанию и встроенной поддержкой Language Server Protocol: редактор сам получает от языкового сервера автодополнение, переход к определению и подсветку ошибок, и собирать это из плагинов не нужно.
Конфиг пишется на Lua и разбивается на модули, поэтому сложная настройка не превращается в один нечитаемый файл. Внутри есть свой эмулятор терминала, а большинство плагинов Vim продолжают работать.
Ставится на Linux, macOS (brew install neovim) и Windows. Пригодится, если вы часто редактируете файлы по ssh: подсветка ошибок и автодополнение будут и там, где графического редактора нет.
Установку и сборку первого конфига по шагам разбирают в The New Stack.
#инструменты
🔥8
Как читать ввод геймпада в JavaScript и находить дрейф стиков
Gamepad API прост, но первая проверка может объявить неисправный контроллер здоровым. Chromium держит значение оси на нуле, пока хотя бы раз не увидит её около центра: по модулю меньше 0,1. Поэтому сильный дрейф может оставаться скрытым сколько угодно.
Есть и вторая ловушка:
Я сохранил практический разбор freeCodeCamp как чеклист для браузерного тестера. После подключения попросите пользователя провести стики через центр, дождитесь ненулевого значения каждой оси и только затем ищите дрейф. Без контроллера опрашивайте API редко, после подключения переходите к каждому кадру.
Gamepad API прост, но первая проверка может объявить неисправный контроллер здоровым. Chromium держит значение оси на нуле, пока хотя бы раз не увидит её около центра: по модулю меньше 0,1. Поэтому сильный дрейф может оставаться скрытым сколько угодно.
Есть и вторая ловушка:
navigator.getGamepads() возвращает снимок состояния. Его нужно вызывать заново в каждом кадре requestAnimationFrame, а пустые ячейки массива пропускать.Я сохранил практический разбор freeCodeCamp как чеклист для браузерного тестера. После подключения попросите пользователя провести стики через центр, дождитесь ненулевого значения каждой оси и только затем ищите дрейф. Без контроллера опрашивайте API редко, после подключения переходите к каждому кадру.
❤3
Как измерять отрисовку компонентов через Container Timing
Метрика LCP отмечает крупнейший элемент в области просмотра. Но карточка товара состоит из изображения, цены, наличия и кнопки, поэтому одна картинка не описывает её отрисовку.
Container Timing помечает атрибутом
API не сообщает, что компонент готов: позже могут появиться новые данные. Границу выбирает приложение, например последнюю запись перед первым действием пользователя. В разборе Гарри Робертса на CSS Wizardry есть код настройки, варианты границ и ограничения, а также подключение к origin trial Chrome.
Метрика LCP отмечает крупнейший элемент в области просмотра. Но карточка товара состоит из изображения, цены, наличия и кнопки, поэтому одна картинка не описывает её отрисовку.
Container Timing помечает атрибутом
containertiming область DOM. Через PerformanceObserver браузер сообщает, когда текст или изображение впервые занимают ещё не учтённую её часть. Так видны первое содержимое и этапы отрисовки.API не сообщает, что компонент готов: позже могут появиться новые данные. Границу выбирает приложение, например последнюю запись перед первым действием пользователя. В разборе Гарри Робертса на CSS Wizardry есть код настройки, варианты границ и ограничения, а также подключение к origin trial Chrome.
❤2
Как сделать потоковый интерфейс стабильным
Чат с ИИ, лента логов и расшифровка речи меняются, пока пользователь их читает. Безусловная автопрокрутка выдёргивает его к новому тексту, а пересборка дерева элементов на каждый символ создаёт обновления, которые браузер не успеет показать.
Разбор Smashing Magazine предлагает три правки. Автопрокрутку оставляют, только пока до низа контейнера не больше 60 пикселей. Новый текст дописывают в существующий текстовый узел, а не пересоздают элементы через innerHTML. Символы собирают в буфер, а requestAnimationFrame переносит их в дерево элементов не чаще раза за кадр.
Пригодится перед реализацией чата, логов или живых метрик: сначала проверьте, можно ли спокойно прокрутить поток вверх, затем посмотрите, не прыгают ли соседние кнопки и не обновляется ли дерево элементов чаще отрисовки экрана.
Чат с ИИ, лента логов и расшифровка речи меняются, пока пользователь их читает. Безусловная автопрокрутка выдёргивает его к новому тексту, а пересборка дерева элементов на каждый символ создаёт обновления, которые браузер не успеет показать.
Разбор Smashing Magazine предлагает три правки. Автопрокрутку оставляют, только пока до низа контейнера не больше 60 пикселей. Новый текст дописывают в существующий текстовый узел, а не пересоздают элементы через innerHTML. Символы собирают в буфер, а requestAnimationFrame переносит их в дерево элементов не чаще раза за кадр.
Пригодится перед реализацией чата, логов или живых метрик: сначала проверьте, можно ли спокойно прокрутить поток вверх, затем посмотрите, не прыгают ли соседние кнопки и не обновляется ли дерево элементов чаще отрисовки экрана.
❤2👍1
Все дела подождут, потому что сегодня ваш день!
Поздравляем с Днем программиста и желаем меньше багов и больше фич, меньше созвонов и больше фокуса, меньше тасок с пометкой «срочно» и больше времени на отдых.
Забирайте подарок из нашей IT-коробки. Мы уверены, этот презент точно пригодится вам в работе: https://tprg.ru/2TAs
Поздравляем с Днем программиста и желаем меньше багов и больше фич, меньше созвонов и больше фокуса, меньше тасок с пометкой «срочно» и больше времени на отдых.
Забирайте подарок из нашей IT-коробки. Мы уверены, этот презент точно пригодится вам в работе: https://tprg.ru/2TAs
❤4
Как собрать плавное раскрытие галереи на GSAP MotionPath
Стопка миниатюр превращается в вертикальную ленту рядом с крупным изображением. Для каждой задаются две точки пути: промежуточная создаёт изгиб с небольшим перелётом, конечная ставит изображение на место. Высота конечной точки зависит от индекса, поэтому карточки движутся по разным дугам.
Перед анимацией код измеряет миниатюру, учитывает уменьшение масштаба и рассчитывает положение ленты. В одном сценарии GSAP кнопка скрывается, миниатюры стартуют с короткой задержкой, появляются номера и увеличивается крупное изображение.
Разбор Codrops пригодится, когда перемещение по координатам выглядит слишком прямолинейно: там есть HTML-структура, расчёты и варианты MotionPath для экспериментов.
Стопка миниатюр превращается в вертикальную ленту рядом с крупным изображением. Для каждой задаются две точки пути: промежуточная создаёт изгиб с небольшим перелётом, конечная ставит изображение на место. Высота конечной точки зависит от индекса, поэтому карточки движутся по разным дугам.
Перед анимацией код измеряет миниатюру, учитывает уменьшение масштаба и рассчитывает положение ленты. В одном сценарии GSAP кнопка скрывается, миниатюры стартуют с короткой задержкой, появляются номера и увеличивается крупное изображение.
Разбор Codrops пригодится, когда перемещение по координатам выглядит слишком прямолинейно: там есть HTML-структура, расчёты и варианты MotionPath для экспериментов.
❤1
Как настроить разную динамику открытия и закрытия меню в GSAP
При
Codrops показывает это на игровом меню: обложки разлетаются от центра, а меню раскрывается через
Если меню можно закрыть до конца открытия,
При
reverse() GSAP разворачивает кривую ускорения: плавное замедление становится плавным разгоном. Поэтому мягко появившийся элемент может закрываться вяло. easeReverse задаёт обратному ходу отдельную кривую без второй анимации.Codrops показывает это на игровом меню: обложки разлетаются от центра, а меню раскрывается через
clip-path. При закрытии elastic.out(0.3) придаёт возврату другую динамику. Переключатель позволяет сравнить варианты.Если меню можно закрыть до конца открытия,
timeScale() отдельно меняет скорость обратного хода. В разборе Codrops есть код таймлайна, пересборка после смены настройки и демо.❤2
Как воссоздать пиксельную анимацию маскота Claude на SVG и GSAP
Автор замедлил ролики до 30% скорости, сделал скриншоты каждого кадра и примерно за четыре дня собрал четыре анимации. Персонаж состоит только из SVG-прямоугольников, без видео, GIF и контуров. React связывает компоненты с элементами, а GSAP задаёт движение и смену кадров.
Для ходьбы автор синхронизировал глаза, корпус и ноги в одной временной шкале, а
Откройте разбор Codrops с кодом и примерами перед анимацией пиксельного персонажа: сначала определите, какие части анимировать плавно, а какие рисовать кадр за кадром.
Автор замедлил ролики до 30% скорости, сделал скриншоты каждого кадра и примерно за четыре дня собрал четыре анимации. Персонаж состоит только из SVG-прямоугольников, без видео, GIF и контуров. React связывает компоненты с элементами, а GSAP задаёт движение и смену кадров.
Для ходьбы автор синхронизировал глаза, корпус и ноги в одной временной шкале, а
clipPath обрезал ноги по линии пола при наклоне. Флаг пришлось нарисовать в 12 вариантах и переключать покадрово: между пиксельными формами нет плавного перехода.Откройте разбор Codrops с кодом и примерами перед анимацией пиксельного персонажа: сначала определите, какие части анимировать плавно, а какие рисовать кадр за кадром.
❤2
Как связать GSAP с WebGL и не нагружать React покадровыми обновлениями
В переходе между видео всю анимацию можно свести к числу от 0 до 1. GSAP меняет его по временной шкале, OGL передаёт значение в числовой параметр шейдера, а видеокарта по нему раскрывает блоки, искажает кадр и раздвигает цветовые каналы. Кривую движения можно заменить, не переписывая код шейдера.
Для перехода обновляются только две видеотекстуры: исходная и следующая. В эффекте под курсором автор оставил один контекст WebGL вместо нового для каждого заголовка и останавливает цикл отрисовки после 90 кадров без движения мыши.
Откройте разбор Тибо Гиньяна на Codrops, когда собираете сложную анимацию и хотите отделить её сценарий от шейдера, а покадровые изменения от состояния React.
В переходе между видео всю анимацию можно свести к числу от 0 до 1. GSAP меняет его по временной шкале, OGL передаёт значение в числовой параметр шейдера, а видеокарта по нему раскрывает блоки, искажает кадр и раздвигает цветовые каналы. Кривую движения можно заменить, не переписывая код шейдера.
Для перехода обновляются только две видеотекстуры: исходная и следующая. В эффекте под курсором автор оставил один контекст WebGL вместо нового для каждого заголовка и останавливает цикл отрисовки после 90 кадров без движения мыши.
Откройте разбор Тибо Гиньяна на Codrops, когда собираете сложную анимацию и хотите отделить её сценарий от шейдера, а покадровые изменения от состояния React.
❤1
Чем заменить палитру Tailwind в проекте на обычном CSS
После отказа от Tailwind не обязательно подбирать каждый оттенок с нуля. В подборке CSS-палитр есть готовые варианты с CSS-файлами: uchū, Flexoki и Reasonable Colors. Последняя, по впечатлению автора, сфокусирована на доступности.
Если готовая палитра не подходит, там же собраны генераторы Harmonizer, tints.dev, Coolors и colorpalette.pro. Ещё один материал показывает, как функция CSS
Практический сценарий: откройте подборку в начале работы над интерфейсом, сравните готовые палитры и переходите к генератору, только если нужен собственный набор оттенков.
После отказа от Tailwind не обязательно подбирать каждый оттенок с нуля. В подборке CSS-палитр есть готовые варианты с CSS-файлами: uchū, Flexoki и Reasonable Colors. Последняя, по впечатлению автора, сфокусирована на доступности.
Если готовая палитра не подходит, там же собраны генераторы Harmonizer, tints.dev, Coolors и colorpalette.pro. Ещё один материал показывает, как функция CSS
oklch() динамически создаёт цвета.Практический сценарий: откройте подборку в начале работы над интерфейсом, сравните готовые палитры и переходите к генератору, только если нужен собственный набор оттенков.
Julia Evans
Links to CSS colour palettes
A while back I decided to stop using Tailwind for new projects and to just write vanilla CSS instead.
❤1