Baseline: декабрь 2025
- пятница, 16 января 2026 г. в 00:00:13
Обзор на браузерные API, которые стали Widely available в декабре 2025. Раз в месяц я буду вам напоминать, что вы уже можете использовать в проде.
Каждый месяц выходят новые CSS-свойства, HTML-атрибуты, JavaScript-методы и WebAPI, но применять в проде мы их конечно же не будем. 2.5 года назад также каждый месяц выходили новые фичи в браузере, а вот их уже пора начинать применять.
У каждой компании, да что уж там компании, у каждой команды в компании своя методика принятия решения о внедрении той или иной фичи в проекте.
Общий же сценарий выглядит так:
- Посмотрели в пользовательские метрики. Поняли какими браузерами и их версиями в основном пользуются пользователи проекта;
- Заглянули в caniuse и поняли, какие фичи уже поддерживаются большинством браузеров;
- Приняли решение о внедрении той или иной фичи в проект.
Какие-то команды позволяют себе указывать правило "последние три версии браузеров". У других специфика проекта, что проект работает исключительно на iPad с Safari. Сами понимаете, все мы разные и требования разные, и у каждого свой подход.
Baseline - позволяет немного упростить процесс принятия решения о внедрении той или иной фичи в проект. Если фича Widely available значит фича уже как минимум есть во всех основных браузерах как минимум стабильно используются последние 2.5 года.
calc() keywords
JavaScript modules in workers
window.print()
Теперь внутри функции calc() можно использовать зарезервированные ключевые слова: e, pi, infinity и NaN. Это избавляет от необходимости копировать длинные хвосты знаков после запятой или писать огромные числа «на глаз».
Пример: Вам нужно повернуть элемент ровно на полкруга, используя радианы. Вместо 3.14159rad теперь можно написать pi * 1rad.
Пример
.circle {
/* Поворот на 180 градусов (π радиан) */
transform: rotate(calc(pi * 1rad));
}
.button {
/* хорошее скругление без знания высоты элемента */
border-radius: calc(infinity * 1px);
}pi — число Пи. Идеально для тригонометрии и расчетов, связанных с кругами.
e — число Эйлера. Основание натурального логарифма, полезно для сложных анимаций с затуханием или ростом.
infinity / -infinity — бесконечность. Позволяет задать «максимально возможное» значение.
NaN — «Not a Number». Появляется при математических ошибках (например, 0 / 0), помогает браузеру корректно обрабатывать исключения без поломки всего CSS.
Практика: гарантированный z-index
Раньше, чтобы элемент точно был поверх всех остальных, мы писали z-index: 999999. Теперь можно использовать «официальную» бесконечность:
.modal-overlay {
z-index: calc(infinity);
}Примечание: Браузер вычислит это как максимально возможное целое число. В разных браузерах и в разных операционных системах значение фактическое значение может быть разным.
Практика: работа с углами и анимациями
Если вы строите сложные интерфейсы с анимацией по траектории, константы делают формулы понятнее:
.orbit-element {
/* Смещение по синусоиде */
left: calc(50% + 100px * sin(pi / 4));
}Нюанс с регистром
Важно помнить, что e, pi и infinity можно писать в любом регистре (PI, InFiNiTy), но для NaN регистр строго зафиксирован спецификацией именно в таком виде.
Теперь веб-воркеры (Web Workers) и сервис-воркеры (Service Workers) могут напрямую импортировать и использовать JavaScript-модули — то есть файлы с синтаксисом import/export.
Пример: Вы хотите вынести вычисления (например, обработку изображений или шифрование) в отдельный воркер, но при этом использовать общие утилиты, написанные как ES-модули.
// main.js
const worker = new Worker('./worker.js', { type: 'module' });
// worker.js
import { heavyComputation } from './utils/math.js';
self.onmessage = (event) => {
const result = heavyComputation(event.data);
self.postMessage(result);
};Cинтаксис (import, export) — работает так же, как в основном потоке. Можно импортировать именованные экспорты, дефолтные экспорты, даже динамические импорты (import()).
Поддержка современных инструментов сборки — Vite, Webpack, Rollup и другие корректно обрабатывают модульные воркеры, если указан флаг { type: 'module' }.
Изоляция и производительность — модули загружаются один раз, кэшируются и не дублируются.
Практика: разделение логики между основным потоком и воркером
Вы можете писать бизнес-логику один раз и использовать её как в UI, так и в воркере:
// shared/crypto.js
export function sha256(buffer) {
return crypto.subtle.digest('SHA-256', buffer);
}
// main.js
import { sha256 } from './shared/crypto.js'; // используется в UI
// worker.js
import { sha256 } from './shared/crypto.js'; // используется в воркереПрактика: динамическая загрузка модулей в воркере
Если модуль нужен только при определённых условиях, можно использовать динамический импорт:
// worker.js
self.onmessage = async (event) => {
if (event.data.type === 'process-image') {
const { processImage } = await import('./image-processor.js');
const result = await processImage(event.data.image);
self.postMessage(result);
}
};Примечание: Чтобы создать модульный воркер, обязательно указывайте { type: 'module' } в конструкторе:
// ❌ Не сработает как модуль
new Worker('worker.js');
// ✅ Правильно
new Worker('worker.js', { type: 'module' });Если вам странно видеть window.print() в Baseline, то вы не одиноки. Так как я в начале подумал, что это шутка, но пошёл узнавать, что там с window.print произошло.
Оказалось что метод заработал в Firefox для Andorid лишь в 114 версии, выпущенной в 06.06.2023. В остальных браузерах данная функциональность работает с первых версий браузеров.
Так как формат предполгает краткое описание фичи, я всё же это сделаю.
Метод window.print() позволяет программно инициировать диалог печати прямо из JavaScript — без участия пользователя.
Пример: Пользователь оформляет заказ в интернет-магазине и хочет сразу распечатать подтверждение. Вместо того чтобы просить его вручную нажимать Ctrl+P, вы вызываете window.print() — и браузер открывает стандартное окно печати с предварительным просмотром.
<button onclick="printReceipt()">Распечатать чек</button>
<script>
function printReceipt() {
// Можно предварительно подготовить страницу (скрыть ненужные элементы)
document.body.classList.add('print-mode');
// Запускаем печать
window.print();
// После печати (или отмены) убираем класс
document.body.classList.remove('print-mode');
}
</script>
<style>
/* Скрыть кнопку и рекламу при печати */
@media print {
.no-print, button {
display: none !important;
}
body.print-mode {
/* Дополнительные стили только во время подготовки к печати */
}
}
</style>Следующий выпуск будет через месяц. До встречи!