Свежие статьи

Popover API или Dialog API: что выбрать?

После продолжительного изучения темы выяснилось, что Popover API и Dialog API кардинально отличаются с точки зрения доступности. Если вы стоите перед выбором, придерживайтесь такого правила:

  • Используйте Popover API для большинства поповеров.
  • Используйте Dialog API только для модальных диалогов.
Читать дальше
JS
  • 14 марта 2026

Прощай, innerHTML — привет, setHTML: усиленная защита от XSS в Firefox 148

Firefox 148 стал первым браузером, реализовавшим стандартизированный Sanitizer API — новый инструмент, который встраивает санитизацию HTML непосредственно в процесс вставки содержимого в DOM и делает защиту от XSS доступной по умолчанию.

Межсайтовый скриптинг (XSS) по-прежнему остаётся одной из наиболее распространённых уязвимостей в интернете. Новый стандартизированный Sanitizer API даёт веб-разработчикам простой способ очищать ненадёжный HTML перед его вставкой в DOM. Firefox 148 стал первым браузером, поставившим этот API в стабильную версию, — ожидается, что остальные браузеры последуют примеру в ближайшее время.

XSS-уязвимость возникает, когда сайт непреднамеренно позволяет злоумышленникам внедрять произвольный HTML или JavaScript через пользовательский контент. С её помощью атакующий может отслеживать и подменять действия пользователей и систематически похищать их данные — до тех пор, пока уязвимость не будет устранена. XSS исторически крайне сложен в предотвращении и на протяжении почти десяти лет стабильно входит в тройку самых опасных веб-уязвимостей (CWE-79).

Mozilla участвовала в борьбе с XSS с самого начала: ещё в 2009 году Firefox инициировал разработку стандарта Content-Security-Policy (CSP). CSP позволяет сайтам ограничивать, какие ресурсы (скрипты, стили, изображения и т. д.) браузер вправе загружать и исполнять, формируя надёжный рубеж обороны. Тем не менее, несмотря на постоянные улучшения, CSP так и не получил широкого распространения: его внедрение требует существенных архитектурных изменений и регулярного внимания специалистов по безопасности.

Sanitizer API призван заполнить этот пробел, предоставляя стандартизированный механизм преобразования вредоносного HTML в безопасный. Метод setHTML() встраивает санитизацию непосредственно в процесс вставки HTML, обеспечивая защиту на уровне умолчаний. Пример очистки небезопасного HTML:

document.body.setHTML(`<h1>Hello my name is <img src="x" 
onclick="alert('XSS')">`);

При такой санитизации элемент <h1> будет сохранён, а элемент <img> вместе с атрибутом onclick — удалён, что устраняет XSS-атаку. В результате останется следующий безопасный HTML:

<h1>Hello my name is</h1>

Разработчики могут усилить защиту от XSS с минимальными изменениями в коде, заменив подверженные ошибкам присваивания innerHTML на вызовы setHTML(). Если настройки по умолчанию окажутся слишком строгими или, напротив, недостаточно строгими для конкретного случая, можно передать пользовательскую конфигурацию, определяющую, какие элементы и атрибуты следует сохранить или удалить. Для экспериментов до внедрения API на продакшн-сайте рекомендуется воспользоваться песочницей Sanitizer API.

Для ещё более надёжной защиты Sanitizer API можно сочетать с Trusted Types, которые централизуют контроль над разбором и вставкой HTML. После перехода на setHTML() включить принудительное применение Trusted Types становится проще — зачастую без необходимости создавать сложные пользовательские политики. Строгая политика может разрешать setHTML(), блокируя остальные небезопасные способы вставки HTML, что помогает предотвращать регрессии в безопасности.

Sanitizer API упрощает замену присваиваний innerHTML на вызовы setHTML() в существующем коде, устанавливая новый безопасный стандарт и защищая пользователей от XSS-атак. Firefox 148 поддерживает как Sanitizer API, так и Trusted Types. Принятие этих стандартов позволит любому разработчику предотвращать XSS без выделенной команды безопасности и масштабных архитектурных изменений.

JS
  • 13 марта 2026

Что нового появилось в браузерах в феврале 2026

Февраль принёс несколько полезных обновлений: атрибут для передачи направления текста в формах получил поддержку во всех браузерах, появились удобные методы для работы с Map, а CSS обзавёлся новой функцией для сложных фигур. Разбираем, что уже можно использовать и что стоит взять на заметку.

Читать дальше
Как сверстать
  • 12 марта 2026

Разбитое сердце

Или: как одна нелепая строка кода дала ускорение в 100 раз.

Всегда знаешь, что попался хороший баг, когда первая реакция — «как такое вообще возможно?»

Я дорабатывал панель управления одного веб-приложения и заметил, что она стала загружаться вечность. Раньше страница открывалась за секунду — теперь за десять. Что-то явно шло не так.

Естественно, я обвинил React.

Ну, конечно, в современном веб-приложении источников проблем с производительностью хватает: сторонний JavaScript, перегруженные серверы, раздутые ресурсы, отсутствующие индексы в базе данных — длиннющий список. Но десятилетия разработки для веба подсказывали: это проблема фронтенда. Я просто чувствовал это. Страница выглядела дёргающейся при загрузке. А экосистема React, при всей своей относительной приемлемости сегодня, полна способов превратить кодовую базу в запутанный тормозящий клубок.

Чтобы подтвердить теорию, я объяснил Claude, что панель загружается медленно, что наверняка виноват React, и попросил проанализировать проблемы и отсортировать их по серьёзности. И действительно, Claude нашёл кучу подозрительного в React: лишние перерисовки, пропущенные мемоизации. Выяснилось, что мы ещё не перешли на React Compiler. Я попросил Claude сделать первый проход по самым простым и серьёзным проблемам, и…

Это почти ничего не дало. Может, дело не в React?

Засучил рукава и начал разбираться по-настоящему.

  1. Может, сервер медленный? Немного — но фронтенд он не блокирует.
  2. Проблема во всех браузерах? Нет. Почему-то только в Safari.
  3. Значит, виноват сторонний JavaScript? Intercom? Нет. PostHog? Нет.
  4. Ладно, роем глубже — смотрим временную шкалу производительности.

Инспектор производительности Safari за последние годы заметно разошёлся с инструментами на основе Chromium и на этой странице работал капризно. Но картину он нарисовал вполне отчётливую: 7+ секунд тратились не на разбор JavaScript, не на вычисление стилей и не на загрузку сети. 94% процессора на M1 Max уходило на… компоновку вёрстки?

В подробностях было видно несколько проходов компоновки длительностью более 1600 мс каждый. Для сравнения: это примерно в 100 раз медленнее нормы. Что-то было серьёзно не так с тем, как браузер выстраивал страницу. Flexbox может чуть замедляться, но не настолько же.

Читать дальше
Нейронки
  • 11 марта 2026

Самый быстрый старт с Qwen Code

Если вы читаете эту статью, вам зачем-то понадобилось сгенерировать код с помощью ИИ-агента. И, скорее всего, вы поискали в интернете и нашли, что есть какой-то там бесплатный ИИ-агент Qwen-Code. Вот что пишут о Qwen Code его создатели:

«Qwen Code — это агентский инструмент для программирования, который работает в вашем терминале и помогает превращать идеи в код быстрее, чем раньше»

Не слишком-то развёрнуто, верно? В этом руководстве мы за несколько минут научимся пользоваться Qwen Code и сделаем собственный небольшой проект с домашней страничкой. Важно: мы используем этот ИИ-агент для быстрой разработки сайтов, но в целом с qwen-code вы можете генерировать код на Python, C++ или любом другом языке. Или даже просто работать с файловой системой и выполнять команды в терминале!

Что понадобится для старта:

Приступим!

Читать дальше
Нейронки
  • 2 февраля 2026

Обзор новых возможностей фронтенда в январе 2026

Январь начался с мощного обновления веб-стандартов: появились новые CSS-единицы для точной типографики, заработала поддержка модулей в Service Worker’ах, а API навигации получил статус «готов к использованию». В этом обзоре — то, что уже можно применять в продакшене или начинать тестировать сегодня.

Читать дальше
Софт
  • 23 января 2026

Новинки веб-платформы: что заработало во всех браузерах в декабре

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

Читать дальше
Софт
  • 14 января 2026

Итоги 2-го чемпионата по вёрстке

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

Ключевые особенности соревнования:

  • сложные и объёмные макеты от профессиональных дизайн-студий;
  • двухнедельный формат, ориентированный на качество, а не скорость;
  • строгая многоуровневая оценка;
  • жюри из опытных разработчиков из бигтеха и компаний заказной разработки.

Второй чемпионат по вёрстке завершился 19 декабря 2025 года. Ниже — его итоги и разбор уровня работ участников.

Читать дальше
Айти
  • 23 декабря 2025

Новые ключевые слова в calc(): e, pi, infinity и NaN

Совсем недавно в CSS появилась небольшая, но любопытная возможность — использовать внутри математических функций вроде calc() готовые константы. Это не новые свойства или сложные функции, а удобные сокращения: e, pi, infinity, -infinity и NaN. Они доступны в браузерах с конца 2022 года, но по-прежнему нечасто встречаются в реальном коде. Разберём, зачем они нужны и когда могут пригодиться.

Константы работают только внутри calc() и её «родственников» — min(), max(), clamp(), sin(), cos() и прочих математических функций. Просто написать font-size: e нельзя, а font-size: calc(e * 1rem) — вполне корректно.

.element {
  font-size: calc(e * 0.5rem); /* ≈ 1.359rem */
}

Константа e — основание натурального логарифма, примерно 2.718. Её можно использовать для плавных, экспоненциальных изменений, например, при анимациях или масштабировании.

@keyframes grow {
  to {
    transform: scale(calc(pow(e, 0.5)));
  }
}

Это эквивалентно scale(1.64872…), но запись через e и pow() читается как «растём в e в степени 0.5» — точнее и выразительнее, чем просто магическое число.

Константа pi (≈ 3.14159…) особенно полезна при работе с углами, особенно в радианах. Например, поворот на 180° — это pi радиан:

.element {
  rotate: calc(pi * 1rad);
}

Можно комбинировать с тригонометрическими функциями:

.element {
  --t: 0.3;
  transform: translateX(calc(100px * sin(calc(pi * var(--t)))));
}

Здесь элемент колеблется по синусоиде, и один полный цикл приходится ровно на изменение --t от 0 до 2.

Более экзотичные константы — infinity, -infinity и NaN. Они не числа в привычном смысле, но ведут себя как числовые значения, и браузер «зажимает» их до максимально или минимально допустимых величин. Например, z-index: calc(infinity) даст самый высокий возможный z-index без необходимости подбирать гигантское число вручную.

.overlay {
  z-index: calc(infinity);
}

Это не «бесконечность» в философском смысле, а гарантированное значение, которое всегда будет больше любого другого z-index, заданного числом.

Константа NaN (Not a Number) почти никогда не нужна в повседневной разработке, но она помогает избежать неопределённого поведения при делении на ноль или других недопустимых операциях. Например:

.test {
  width: calc(0 / 0); /* вычисляется как NaN */
}

Согласно стандарту IEEE-754, любая операция с NaN возвращает NaN, и браузер в итоге проигнорирует такое свойство или заменит на значение по умолчанию. Это предсказуемо — лучше молчать, чем рисковать.

Наконец, напомним: константы чувствительны к регистру только частично. e, pi, infinity можно писать в любом регистре: E, Pi, InFiNiTy — всё сработает. А вот NaN допускает только такой вариант написания. nan, NAN или NaN() — синтаксическая ошибка.

На практике e и pi пригодятся тем, кто строит анимации, диаграммы, визуализации или работает с тригонометрией в CSS. infinity — когда нужно «перебить любой z-index». NaN — скорее для полноты реализации, чем для практического использования.

Иногда простая константа экономит время, избавляет от калькулятора и делает стиль чуть понятнее — особенно если вы любите точность и математику.

CSS
  • 21 декабря 2025
Плохая анимация в CSS. Топ примеров

Плохая анимация в CSS. Топ примеров

Вообще-то, анимация на сайте — это хорошо. Даже в 2002 году на сайте башкирской федерации настольного тенниса уже была анимированная бегущая строка — смотрите сами:

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

Но иногда анимация делает только хуже. Смотрите, когда это происходит.

Дисклеймер: ради этой статьи нам пришлось отключить адблок. Не повторяйте этого дома.

Читать дальше
CSS
  • 20 декабря 2025
Подборка кнопок с CodePen для ваших проектов

Подборка кнопок с CodePen для ваших проектов

Правильно говорят, что лучший способ чему-то научиться — подсмотреть у тех, кто умеет. Поэтому принесли вам подборку с CodePen, в которой хорошие разработчики делают интересные штуки и делятся ими со всеми. В этом выпуске — интерфейсы на CSS и React.

Читать дальше
Как сверстать
  • 19 декабря 2025
Как создать плавные анимации в CSS с cubic-bezier() — руководство с примерами

Как создать плавные анимации в CSS с cubic-bezier() — руководство с примерами

Когда вы задаёте анимацию или переход в CSS, свойства изменяются нелинейно: сначала медленно, потом быстрее, в конце снова замедляются. Это поведение называется интерполяцией и определяется так называемой функцией ускорения (или «easing function»). По умолчанию браузеры используют значения вроде ease, ease-in, ease-out и linear. Но если вам нужен более тонкий контроль над тем, как именно свойство изменяется во времени, пригодится функция cubic-bezier().

Эта функция позволяет задать собственную кривую ускорения с помощью четырёх чисел — координат двух управляющих точек кубической кривой Безье. Эти значения описывают, как «разгоняется» и «тормозит» анимация. cubic-bezier() поддерживается всеми современными браузерами и считается стабильной функцией (Baseline: Widely Available), так что её можно использовать в продакшене.

Вот пример, где переход на элементе происходит по заданной кривой:

.element {
  transition: all 0.5s cubic-bezier(0.25, 0.1, 0.25, 1);
}

В этом примере четыре числа — это координаты управляющих точек, задающих форму кривой. Именно они определяют, как быстро будет происходить переход: насколько он будет «вялым» в начале, насколько резко ускорится и как будет вести себя в конце.

Читать дальше
CSS
  • 17 декабря 2025
Как найти элемент в массиве с конца в JavaScript

Как найти элемент в массиве с конца в JavaScript

Метод findLast() появился в JavaScript как часть стандарта ECMAScript 2023 и уже широко поддерживается всеми актуальными браузерами. Он работает как зеркальное отражение метода find(), но ищет элементы не с начала массива, а с конца — и возвращает первый найденный в таком обратном порядке элемент, удовлетворяющий условию. Если ничего не найдено, возвращается undefined [[1]].

Читать дальше
CSS
  • 16 декабря 2025

Как сделать кнопку «Скопировать» на странице

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

Читать дальше
JS
  • 21 ноября 2025

UUID в JavaScript: Полное руководство

Генерация UUID — одна из тех фундаментальных задач, с которой сталкивается каждый разработчик. Universally Unique Identifier, или универсальный уникальный идентификатор, решает простую, но критически важную задачу: создание гарантированно уникального идентификатора.

Читать дальше
JS
  • 20 ноября 2025

Как спарсить JSON (100% рабочий способ)

JSON (JavaScript Object Notation) — это текстовый формат для представления структурированных данных. Он повсеместно используется для обмена информацией между клиентом и сервером, хранения конфигураций и сериализации состояний. В JavaScript его преобразование в рабочие объекты выполняется стандартным методом JSON.parse(). Ниже описаны корректные и надёжные способы его применения — от базового использования до промышленных практик.

Читать дальше
JS
  • 18 ноября 2025

lab() и lch() стали широкодоступными в браузерах

В ноябре 2025 года появилось два новых способа задавать цвет в CSS. lab() и lch() стали полностью доступны во всех основных браузерах и больше не нужно включать никакие экспериментальные настройки.

  • Chrome и Edge — с версии 111 (уже почти 3 года как есть)
  • Safari — с версии 16.4 (весна 2023)
  • Firefox — с версии 125 (2024 год)

Обычные цвета rgb() и hex часто дают неожиданные результаты, когда хочется просто сделать цвет чуть светлее или чуть темнее. С lab() и особенно с lch() всё стало намного проще и предсказуемее:

  • Меняешь только яркость — цвет остаётся тем же самым по оттенку
  • Меняешь насыщенность — не уходишь случайно в серый или в слишком ядовитый
  • Поворачиваешь оттенок на 30–60 градусов — получаешь красивую гармоничную палитру
Читать дальше
CSS
  • 16 ноября 2025

Новинки веб-платформы: что стало доступно во всех браузерах в ноябре

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

Читать дальше
Как сверстать
  • 16 ноября 2025

CSS-функция color() теперь доступна во всех браузерах

По данным MDN Web Docs и Web Platform Features Explorer, по состоянию на ноябрь 2025 года функциональная нотация color() достигла статуса widely available во всех основных браузерах без необходимости включения экспериментальных флагов.

Читать дальше
CSS
  • 14 ноября 2025