Подсветка фрагментов текста без единого лишнего span в разметке
Люди страницу не читают, а сканируют, поэтому подсветка нужных кусков работает. В CSS для этого целое семейство псевдоэлементов:
Подкупает то, что оборачивать текст в разметку не надо: диапазон задаётся в JavaScript, а стили живут в CSS. В DOM не появляется ни одного лишнего узла, а значит, ничего не ломается ни в вёрстке, ни в доступности.
Поддержка пока не везде, поэтому Сюнками Фафовора показывает, как включать это через progressive enhancement: браузер без поддержки просто не покрасит, и страница останется рабочей.
#css
Люди страницу не читают, а сканируют, поэтому подсветка нужных кусков работает. В CSS для этого целое семейство псевдоэлементов:
::selection для выделенного мышью текста, ::target-text для перехода из поиска и самый гибкий из них, ::highlight(), который красит произвольный фрагмент по вашему выбору.Подкупает то, что оборачивать текст в разметку не надо: диапазон задаётся в JavaScript, а стили живут в CSS. В DOM не появляется ни одного лишнего узла, а значит, ничего не ломается ни в вёрстке, ни в доступности.
Поддержка пока не везде, поэтому Сюнками Фафовора показывает, как включать это через progressive enhancement: браузер без поддержки просто не покрасит, и страница останется рабочей.
#css
Piccalilli
Working with ::highlight() using progressive enhancement
Using a baseline of <mark> elements, Sunkanmi Fafowora helps you to understand how the new highlight API works with some progressive enhancement for good measure.
🔥5
Forwarded from Точка входа в программирование
Достаньте точный цвет пикселя из картинки прямо в браузере
Задача звучит просто: есть скриншот или логотип, нужен точный HEX конкретного пикселя. Обычно за этим идут в графический редактор, хотя браузер умеет сам, и загружать картинку никуда не надо.
Работает это через Canvas — элемент HTML, на котором можно рисовать и, что важнее, читать нарисованное по пикселям. Порядок такой: загрузить изображение, нарисовать его на canvas, забрать массив пикселей и достать нужный. В массиве каждый пиксель занимает четыре числа: красный, зелёный, синий и прозрачность.
Упражнение хорошо тем, что за один маленький проект вы трогаете объект
#javascript
Задача звучит просто: есть скриншот или логотип, нужен точный HEX конкретного пикселя. Обычно за этим идут в графический редактор, хотя браузер умеет сам, и загружать картинку никуда не надо.
Работает это через Canvas — элемент HTML, на котором можно рисовать и, что важнее, читать нарисованное по пикселям. Порядок такой: загрузить изображение, нарисовать его на canvas, забрать массив пикселей и достать нужный. В массиве каждый пиксель занимает четыре числа: красный, зелёный, синий и прозрачность.
Упражнение хорошо тем, что за один маленький проект вы трогаете объект
Image, события загрузки и типизированные массивы. Возьмите код примера и соберите пипетку, которая показывает цвет под курсором.#javascript
DEV Community
How to Extract Colors From an Image Using JavaScript and Canvas?
How to Extract Colors From an Image Using JavaScript and Canvas Have you ever looked at an...
❤2
Forwarded from Точка входа в программирование
У вас есть широта и долгота: что с ними делать, кроме метки на карте
Пара чисел вроде 40.7128 и −74.0060 обычно заканчивается маркером на карте, и на этом всё. А достать из неё можно заметно больше: найти заведения рядом, определить город и район, посчитать расстояние до другой точки.
Для новичка это удобная тренировка работы с внешним API: отправить запрос с координатами, получить JSON, разобрать его и показать результат. Заодно всплывают вещи, о которых туториалы обычно молчат: что делать, если сервис ничего не нашёл, и почему расстояние по прямой не равно расстоянию пешком.
Разбор на JavaScript годится как основа для маленького проекта «что рядом со мной»: одна форма, один запрос, один список результатов.
#javascript
Пара чисел вроде 40.7128 и −74.0060 обычно заканчивается маркером на карте, и на этом всё. А достать из неё можно заметно больше: найти заведения рядом, определить город и район, посчитать расстояние до другой точки.
Для новичка это удобная тренировка работы с внешним API: отправить запрос с координатами, получить JSON, разобрать его и показать результат. Заодно всплывают вещи, о которых туториалы обычно молчат: что делать, если сервис ничего не нашёл, и почему расстояние по прямой не равно расстоянию пешком.
Разбор на JavaScript годится как основа для маленького проекта «что рядом со мной»: одна форма, один запрос, один список результатов.
#javascript
DEV Community
How to Find Nearby Places from Latitude and Longitude with JavaScript
When you already have a latitude and longitude pair, you can do much more than simply place a marker...
👍2❤1
Вынесли логику в кастомный хук и получили лишние перерисовки
Инстинкт понятный: компонент оброс полусотней строк состояния и запросов, вы вытаскиваете это в аккуратный
Ловушка в том, что кастомный хук это обычная функция. Компонент, который его вызывает, выполняет код хука как часть собственного рендера. Состояние вы не спрятали, а перенесли: любой
Я бы прошёлся по своим «чистым» хукам с этим текстом рядом, особенно там, где один хук зовут сразу несколько компонентов. Разбор показывает, как это выглядит в профайлере.
#перформанс
Инстинкт понятный: компонент оброс полусотней строк состояния и запросов, вы вытаскиваете это в аккуратный
useDashboardFilters(), родитель худеет до десяти строк JSX. Выглядит как чистая победа.Ловушка в том, что кастомный хук это обычная функция. Компонент, который его вызывает, выполняет код хука как часть собственного рендера. Состояние вы не спрятали, а перенесли: любой
useState внутри хука по-прежнему перерисовывает того, кто хук позвал.Я бы прошёлся по своим «чистым» хукам с этим текстом рядом, особенно там, где один хук зовут сразу несколько компонентов. Разбор показывает, как это выглядит в профайлере.
#перформанс
DEV Community
Are Custom Hooks Ruining Your React App Performance?
The Hidden Cost of "Clean" Code As React developers, we are taught to value clean, DRY...
❤2👍2
ИИ-краулер видит вместо вашего сайта пустой div
Откройте клиентски отрисованный сайт в браузере: всё на месте, герой отрисован, навигация работает. Теперь заберите тот же URL так, как это делает автомат, обычным GET без браузера и движка JavaScript. В ответе почти пусто:
Раньше с этим мирились. Теперь заметная доля клиентов на ваших URL это краулеры за ответами ИИ: GPTBot, ClaudeBot, PerplexityBot, Google-Extended и фетчеры, которые обслуживают режимы поиска в вебе и живые цитаты. Многие читают начальный HTML и на этом останавливаются. Если контент появляется только после бандла, для них его не существует.
Разбор раскладывает начальный HTML на три состояния и помогает понять, в каком из них ваш сайт. Проверить себя можно одной командой curl прямо сейчас.
#spa
Откройте клиентски отрисованный сайт в браузере: всё на месте, герой отрисован, навигация работает. Теперь заберите тот же URL так, как это делает автомат, обычным GET без браузера и движка JavaScript. В ответе почти пусто:
<div id="root"></div>, пара тегов <script> и никакого человеческого текста.Раньше с этим мирились. Теперь заметная доля клиентов на ваших URL это краулеры за ответами ИИ: GPTBot, ClaudeBot, PerplexityBot, Google-Extended и фетчеры, которые обслуживают режимы поиска в вебе и живые цитаты. Многие читают начальный HTML и на этом останавливаются. Если контент появляется только после бандла, для них его не существует.
Разбор раскладывает начальный HTML на три состояния и помогает понять, в каком из них ваш сайт. Проверить себя можно одной командой curl прямо сейчас.
#spa
DEV Community
Your Single-Page App Serves an Empty Page to an AI Crawler
A browser runs your JS bundle and paints the content; an AI crawler that does not execute JavaScript reads the raw HTML and sees an empty shell. How to see what the crawler sees, the three states of your initial HTML, and the fix.
❤4
Браузер дорос до того, чтобы конвертировать файлы без сервера
Для растущего набора форматов конвертация целиком помещается во вкладку: браузер читает файл, преобразует его и отдаёт обратно, ни разу не обратившись к серверу. Ещё пару лет назад это было уделом десктопных программ.
Отсюда исчезает не только загрузка. Пропадают очередь на обработку, требование завести аккаунт и серверный шаг целиком, а вместе с ними и вопрос, что стало с копией вашего файла.
Автор разбирает механику и честно очерчивает границы: где локальная конвертация выигрывает, а где браузеру не хватает сил и сервер всё-таки нужен. Прочесть стоит до того, как закладывать такой инструмент в план.
Для растущего набора форматов конвертация целиком помещается во вкладку: браузер читает файл, преобразует его и отдаёт обратно, ни разу не обратившись к серверу. Ещё пару лет назад это было уделом десктопных программ.
Отсюда исчезает не только загрузка. Пропадают очередь на обработку, требование завести аккаунт и серверный шаг целиком, а вместе с ними и вопрос, что стало с копией вашего файла.
Автор разбирает механику и честно очерчивает границы: где локальная конвертация выигрывает, а где браузеру не хватает сил и сервер всё-таки нужен. Прочесть стоит до того, как закладывать такой инструмент в план.
DEV Community
How to Convert Files in the Browser Without Uploading Them
Most file-conversion workflows start with a trade-off that is easy to miss: Choose a file from your...
❤3👍1
Чем заменить привычные npm-пакеты, когда сервис уезжает на Rust
Тяжёлые сервисы на Node переписывают на Rust обычно ради двух вещей: предсказуемо низких задержек и счёта за инфраструктуру. Порт API с Express или Fastify на Axum, фоновый воркер, утилита для командной строки — механика везде одна.
Спотыкаются не на языке, а сразу после
Материал и есть та самая таблица соответствий для расхожих пакетов, плюс способ держать её под рукой прямо в VS Code.
Тяжёлые сервисы на Node переписывают на Rust обычно ради двух вещей: предсказуемо низких задержек и счёта за инфраструктуру. Порт API с Express или Fastify на Axum, фоновый воркер, утилита для командной строки — механика везде одна.
Спотыкаются не на языке, а сразу после
Cargo.toml. В npm больше двух миллионов пакетов, в crates.io набор заметно меньше и устроен иначе, с упором на типобезопасность и контроль памяти. Прямого аналога часто нет, а искать замену каждому пакету по одному долго.Материал и есть та самая таблица соответствий для расхожих пакетов, плюс способ держать её под рукой прямо в VS Code.
DEV Community
Migrating from TypeScript/Node.js to Rust? Here's how to map your npm packages
Rewriting heavy TypeScript/Node.js services in Rust is one of the most effective ways to lower your...
❤5
Ноль зависимостей и ноль сборки: что вышло из 59 утилит на голом JavaScript
Автор Antigravity Tools поставил себе ограничение и выдержал его 59 раз подряд: без бэкенда на Node, без пакетов npm, без webpack, vite и parcel, без аналитики и куки. Только нативные браузерные API.
Ограничение оказалось не эстетическим. Когда вы вставляете JWT в онлайновый декодер, токен уходит на чужой сервер, а когда прогоняете строку через онлайновый тестер регулярок, строку логируют. Здесь каждая операция выполняется во вкладке, потому что уходить ей просто некуда.
Автор рассказывает, что из этого получилось и чего это стоило. Отдельно любопытно как аргумент в вечном споре, нужен ли тут фреймворк.
#javascript
Автор Antigravity Tools поставил себе ограничение и выдержал его 59 раз подряд: без бэкенда на Node, без пакетов npm, без webpack, vite и parcel, без аналитики и куки. Только нативные браузерные API.
Ограничение оказалось не эстетическим. Когда вы вставляете JWT в онлайновый декодер, токен уходит на чужой сервер, а когда прогоняете строку через онлайновый тестер регулярок, строку логируют. Здесь каждая операция выполняется во вкладке, потому что уходить ей просто некуда.
Автор рассказывает, что из этого получилось и чего это стоило. Отдельно любопытно как аргумент в вечном споре, нужен ли тут фреймворк.
#javascript
DEV Community
I built 59 free browser-based dev tools in vanilla JS — here's what I learned
I've been quietly building Antigravity Tools — a collection of 59 free, browser-based developer...
👍3❤1
Модель считает прямо в браузере, а где не может, уходит в облако сама
У браузерных моделей всегда была одна и та же беда: в Chrome Gemini Nano есть, в остальных браузерах нет, и приложение приходится либо писать в двух вариантах, либо отказываться от локального счёта вовсе.
Hybrid and On-device Web SDK от Firebase AI Logic эту развилку снимает: он сам решает, где считать. В Chrome скачивает и запускает Gemini Nano прямо на устройстве, в остальных браузерах уходит к облачной Gemini 3.5 Flash. Какой бэкенд отработал, пользователь не знает и знать не должен.
Показано это на приложении для анализа картинок: пользователь загружает изображение и получает теги, альтернативный текст и рекомендации. Туториал собран на Angular 22, Tailwind и Node 24, с локальным эмулятором Firebase.
#фронтенд
У браузерных моделей всегда была одна и та же беда: в Chrome Gemini Nano есть, в остальных браузерах нет, и приложение приходится либо писать в двух вариантах, либо отказываться от локального счёта вовсе.
Hybrid and On-device Web SDK от Firebase AI Logic эту развилку снимает: он сам решает, где считать. В Chrome скачивает и запускает Gemini Nano прямо на устройстве, в остальных браузерах уходит к облачной Gemini 3.5 Flash. Какой бэкенд отработал, пользователь не знает и знать не должен.
Показано это на приложении для анализа картинок: пользователь загружает изображение и получает теги, альтернативный текст и рекомендации. Туториал собран на Angular 22, Tailwind и Node 24, с локальным эмулятором Firebase.
#фронтенд
DEV Community
Build Hybrid Image Analysis Application with Angular, Firebase AI Logic, and Gemini Nano [GDE]
This tutorial demonstrates how to build a hybrid image analysis application using Angular, Firebase...
❤5👍1
Forwarded from GameDev: разработка игр
Физика, стеклянные деформации и процедурный звук в одном эксперименте на WebGPU
Франк Райтбергер с появлением
В сцене сходятся три вещи: физика, деформации стекла и процедурно генерируемый звук. Последнее в браузерных демках встречается редко, и именно связка звука с симуляцией отличает эксперимент от обычного шейдерного этюда.
Компактный образец того, на что уже сегодня годится WebGPU в связке с TSL, без разрастания в полноценный проект.
Франк Райтбергер с появлением
WebGPURenderer и TSL сознательно перевёл свои эксперименты на новый стек, чтобы публиковать их уже на современной технологии. «Садовая аномалия» один из них.В сцене сходятся три вещи: физика, деформации стекла и процедурно генерируемый звук. Последнее в браузерных демках встречается редко, и именно связка звука с симуляцией отличает эксперимент от обычного шейдерного этюда.
Компактный образец того, на что уже сегодня годится WebGPU в связке с TSL, без разрастания в полноценный проект.
Codrops
Garden Anomaly: A Tiny WebGPU and TSL Experiment | Codrops
A tiny WebGPU and TSL experiment, tinkering with physics, deformations, and procedural audio, all tied together inside a sphere to play with.
❤1
Разработчик натянул настоящий рельеф Альп на сайт в Webflow и собрал всё за неделю
Вопрос, с которого начался проект: может ли сайт на Webflow нести реальные данные высот, натянутые сеткой горизонталей и отрисованные живьём в Three.js, а не видеопетлю и не запечённый спрайтшит.
Может. Вышли три сцены по настоящим маршрутам: Тре-Чиме в грозу, Монблан на переходе синего часа в розовый и Аннапурна ночью со снегом. Геометрия везде честная. Свой трек автор записал в Strava, выгрузил GPX, почистил типичные выбросы GPS и натянул на реальный склон SRTM, а наружу уезжает только нормализованная версия без точных координат.
Сайт при этом остался обычным редактируемым проектом Webflow, и весь он собран примерно за неделю через Webflow MCP.
Разбор сделан из журнала сборки, который автор вёл с первого дня, поэтому в нём есть и неверные повороты, а не только причёсанный итог.
Вопрос, с которого начался проект: может ли сайт на Webflow нести реальные данные высот, натянутые сеткой горизонталей и отрисованные живьём в Three.js, а не видеопетлю и не запечённый спрайтшит.
Может. Вышли три сцены по настоящим маршрутам: Тре-Чиме в грозу, Монблан на переходе синего часа в розовый и Аннапурна ночью со снегом. Геометрия везде честная. Свой трек автор записал в Strava, выгрузил GPX, почистил типичные выбросы GPS и натянул на реальный склон SRTM, а наружу уезжает только нормализованная версия без точных координат.
Сайт при этом остался обычным редактируемым проектом Webflow, и весь он собран примерно за неделю через Webflow MCP.
Разбор сделан из журнала сборки, который автор вёл с первого дня, поэтому в нём есть и неверные повороты, а не только причёсанный итог.
👍1🔥1
Типичный Программист снова откладывает отпуск. В этот раз аргумент новый, но узнаваемый: релиз вот-вот стабилизируется. Спойлер: не стабилизируется.
В новой мини-игре вам придётся взять дело в свои руки: найти его билет, собрать чемодан и проследить, чтобы туда попали не только рабочий ноутбук и запасные зарядки. По пути можно поймать промокоды от партнёров!
Поехали → https://tprg.ru/SEVh
В новой мини-игре вам придётся взять дело в свои руки: найти его билет, собрать чемодан и проследить, чтобы туда попали не только рабочий ноутбук и запасные зарядки. По пути можно поймать промокоды от партнёров!
Поехали → https://tprg.ru/SEVh
❤2
Один блок с живыми данными больше не заставит делать динамической всю страницу
Ситуация знакомая: сайт статический, а в футере нужны свежие цифры. Дальше выбор так себе — либо пометить маршрут динамическим и потерять скорость отдачи, либо писать загрузчик на весь маршрут ради одного компонента, теряя по дороге типы.
В SvelteKit 3 RC для этого есть remote functions: серверную функцию-запрос компонент импортирует и вызывает прямо у себя, а компилятор подставляет клиентскую обёртку, которая сама делает fetch. Отдельный роут и обвязка не нужны, типы с сервера доезжают до компонента.
Фича экспериментальная ещё с 2.27, третья версия пока в статусе кандидата: равноправными с load-функциями remote functions станут после того, как дочистят оставшиеся баги. Я бы попробовал их на одном компоненте со свежими данными, вроде футера, а load-функции пока не выкидывал.
#фронтенд
Ситуация знакомая: сайт статический, а в футере нужны свежие цифры. Дальше выбор так себе — либо пометить маршрут динамическим и потерять скорость отдачи, либо писать загрузчик на весь маршрут ради одного компонента, теряя по дороге типы.
В SvelteKit 3 RC для этого есть remote functions: серверную функцию-запрос компонент импортирует и вызывает прямо у себя, а компилятор подставляет клиентскую обёртку, которая сама делает fetch. Отдельный роут и обвязка не нужны, типы с сервера доезжают до компонента.
Фича экспериментальная ещё с 2.27, третья версия пока в статусе кандидата: равноправными с load-функциями remote functions станут после того, как дочистят оставшиеся баги. Я бы попробовал их на одном компоненте со свежими данными, вроде футера, а load-функции пока не выкидывал.
#фронтенд
❤2🔥1
Воркер тормозит интерфейс мимо ваших метрик, но Chrome 153 его показывает
Вы вынесли в dedicated Worker декодирование данных, фильтрацию большого каталога или клиентскую модель. INP, метрика отклика на клики и ввод, при этом приличный, а продукт кажется медленным: ответ, которого ждёт интерфейс, стоит в очереди воркера, и увидеть это было нечем.
Chrome 153 распространяет на такие воркеры Long Animation Frames, механизм учёта длинных блокирующих задач: задача, надолго занявшая event loop воркера, отдаёт запись long-animation-frame с атрибуцией по скриптам, и её видно изнутри через PerformanceObserver.
Пока это только dedicated Worker, и версия дошла до части пользователей Windows и Mac, полный релиз сегодня, 8 сентября.
#перформанс
Вы вынесли в dedicated Worker декодирование данных, фильтрацию большого каталога или клиентскую модель. INP, метрика отклика на клики и ввод, при этом приличный, а продукт кажется медленным: ответ, которого ждёт интерфейс, стоит в очереди воркера, и увидеть это было нечем.
Chrome 153 распространяет на такие воркеры Long Animation Frames, механизм учёта длинных блокирующих задач: задача, надолго занявшая event loop воркера, отдаёт запись long-animation-frame с атрибуцией по скриптам, и её видно изнутри через PerformanceObserver.
Пока это только dedicated Worker, и версия дошла до части пользователей Windows и Mac, полный релиз сегодня, 8 сентября.
#перформанс
Csswizardry
Web-Perf Wednesday 007 – Chrome Makes Busy Workers Measurable – CSS Wizardry
Chrome 153 starts exposing dedicated-worker congestion to RUM, while browser releases tighten privacy, module recovery, and image preloading.
❤2
Bun на 2000 параллельных сборках стал есть 609 МБ вместо 6,7 ГБ
Если вы упирались в память, когда Bun собирает много всего разом, в версии 1.4.0 потолок сдвинулся: на том же бенчмарке расход упал с 6,7 ГБ до 609 МБ. Заодно порт закрыл 128 старых багов и примерно на 20% ужал бинарник на Linux и Windows.
Ядро рантайма переписали с Zig на Rust, чтобы обращения к освобождённой памяти ловил компилятор. Переписывала не команда: 64 агента в параллельных git-worktree за 11 дней перевели 535 496 строк Zig и разгребли 16 000 ошибок компиляции. API обошёлся примерно в $165 000, а Turborepo с Go на Rust переводили 3–5 инженеров 14 месяцев.
Цифры порта собраны на dev.to.
#javascript #ии
Если вы упирались в память, когда Bun собирает много всего разом, в версии 1.4.0 потолок сдвинулся: на том же бенчмарке расход упал с 6,7 ГБ до 609 МБ. Заодно порт закрыл 128 старых багов и примерно на 20% ужал бинарник на Linux и Windows.
Ядро рантайма переписали с Zig на Rust, чтобы обращения к освобождённой памяти ловил компилятор. Переписывала не команда: 64 агента в параллельных git-worktree за 11 дней перевели 535 496 строк Zig и разгребли 16 000 ошибок компиляции. API обошёлся примерно в $165 000, а Turborepo с Go на Rust переводили 3–5 инженеров 14 месяцев.
Цифры порта собраны на dev.to.
#javascript #ии
❤3🔥3👍1
Длинная таблица вешает вкладку, и чинится это двумя неочевидными приёмами
Админка отдаёт 50 тысяч строк, вы выводите их в разметку как есть, и скролл захлёбывается. По замерам из разбора такой список стоит браузеру около 850 МБ узлов DOM против 1,2 МБ у той же таблицы с виртуализацией.
Живыми остаются только 15–20 видимых строк, остальное лежит массивом в JS. При скролле вы не создаёте и не удаляете узлы, а переиспользуете те же: меняете текст и сдвигаете.
Дальше два шага. Первый: невидимый div высотой «число строк × высота строки», иначе скроллбар считает список коротким. Второй: строке ставится
Забрал бы этот разбор на случай, когда в списке заводится бесконечная прокрутка: весь путь показан на чистом JS. Ограничение видно из формул: они держатся на фиксированной высоте строки.
#фронтенд
Админка отдаёт 50 тысяч строк, вы выводите их в разметку как есть, и скролл захлёбывается. По замерам из разбора такой список стоит браузеру около 850 МБ узлов DOM против 1,2 МБ у той же таблицы с виртуализацией.
Живыми остаются только 15–20 видимых строк, остальное лежит массивом в JS. При скролле вы не создаёте и не удаляете узлы, а переиспользуете те же: меняете текст и сдвигаете.
Дальше два шага. Первый: невидимый div высотой «число строк × высота строки», иначе скроллбар считает список коротким. Второй: строке ставится
top: index × ITEM_HEIGHT, иначе двадцатитысячная строка нарисуется у верхней кромки.Забрал бы этот разбор на случай, когда в списке заводится бесконечная прокрутка: весь путь показан на чистом JS. Ограничение видно из формул: они держатся на фиксированной высоте строки.
#фронтенд
👍5❤1
Маркдаун-версия страницы для ИИ-агентов может утечь в браузер живого пользователя
По вашим страницам уже ходят ИИ-агенты, и каждая обходится им в токены. Медиана по 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