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

То, что теперь работает везде

Константы внутри calc()

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

.circle {
  width: calc(2 * pi * 50px);
}

Модули JavaScript в Web Workers

Теперь можно спокойно писать воркеры с import/export — достаточно передать { type: "module" } в конструктор Worker(). Это значит, что фоновые задачи (обработка данных, сложные вычисления) можно организовывать так же чисто и модульно, как и основной код.

const worker = new Worker('worker.js', { type: 'module' });

window.print() — без сюрпризов

Метод window.print() теперь стабильно открывает диалог печати во всех браузерах. Отлично подходит для веб-приложений, где нужно распечатать чек, отчёт или документ.

document.getElementById('print-btn').addEventListener('click', () => {
  window.print();
});

Свежие фичи, которые только появились

document.caretPositionFromPoint(x, y)

Хотите узнать, куда попадёт курсор, если пользователь кликнет в определённую точку? Этот метод вернёт вам DOM-узел и смещение — идеально для текстовых редакторов, заметок или любых инструментов, где важно точно понимат, куда кликнул пользователь.

const pos = document.caretPositionFromPoint(100, 200);
console.log(pos.offsetNode, pos.offset);

Замер задержки реакции: PerformanceEventTiming

Теперь можно измерить, сколько времени проходит между кликом (или нажатием клавиши) и следующей отрисовкой. Эти данные лежат в основе метрики INP (Interaction to Next Paint) — одного из главных показателей отзывчивости сайта.

performance.getEntriesByType('first-input').forEach(entry => {
  console.log('Задержка:', entry.processingStart - entry.startTime);
});

font-family: math

Новое значение math указывает браузеру использовать шрифт, заточенный под математические формулы. Особенно актуально для образовательных платформ, научных статей и всего, где встречаются дроби, интегралы и прочая «математика».

.math-expression {
  font-family: math;
}

Декларативные команды: command и commandfor

Хватит вешать обработчики вручную! Атрибуты command и commandfor позволяют связать кнопку с действием на другом элементе прямо в HTML. Просто, читаемо, без JavaScript.

<button command="copy" commandfor="text-block">Копировать</button>
<div id="text-block">...</div>

Largest Contentful Paint (LCP)

API LargestContentfulPaint помогает точно определить, когда загрузился самый крупный элемент на странице — будь то картинка или заголовок. Это основа метрики LCP, которая показывает, насколько быстро сайт «оживает» для пользователя.

new PerformanceObserver((list) => {
  const lcp = list.getEntries().pop();
  console.log('LCP:', lcp.renderTime || lcp.loadTime);
}).observe({ type: 'largest-contentful-paint', buffered: true });

@scope — стили только там, где надо

CSS-правило @scope ограничивает применение стилей конкретной областью DOM. Это как Shadow DOM, но без лишней сложности. Отлично подходит для компонентов, где важно не «зацепить» соседние блоки.

@scope (.card) {
  p { color: blue; }
}

scrollbar-color — красивые скроллбары без хаков

Теперь можно задать цвет «ползунка» и «дорожки» прокрутки через одно свойство. Особенно удобно для тёмных тем и кастомных дизайн-систем.

body {
  scrollbar-color: #6a5acd #f0f0f0;
}

Событие scrollend

Скролл закончился — и браузер об этом сообщает. Событие scrollend срабатывает даже после анимированной прокрутки. Это позволяет корректно обновлять UI, не мешая пользователю и не вызывая «дрожания».

document.addEventListener('scrollend', () => {
  console.log('Прокрутка завершена');
});