Обзор на браузерные API, которые стали Widely available в ноябре 2025. Раз в месяц я буду вам напоминать, что вы уже можете использовать в проде.
Каждый месяц выходят новые CSS-свойства, HTML-атрибуты, JavaScript-методы и WebAPI, но применять в проде мы их конечно же не будем. 2.5 года назад также каждый месяц выходили новые фичи в браузере, а вот их уже пора начинать применять.
Как мы понимаем, что уже можно использовать в проде?
У каждой компании, да что уж там компании, у каждой команды в компании своя методика принятия решения о внедрении той или иной фичи в проекте.
Общий же сценарий выглядит так:
- Посмотрели в пользовательские метрики. Поняли какими браузерами и их версиями в основном пользуются пользователи проекта;
- Заглянули в caniuse и поняли, какие фичи уже поддерживаются большинством браузеров;
- Приняли решение о внедрении той или иной фичи в проект.
Какие-то команды позволяют себе указывать правило "последние три версии браузеров". У других специфика проекта, что проект работает исключительно на iPad с Safari. Сами понимаете, все мы разные и требования разные, и у каждого свой подход.
Baseline - позволяет немного упростить процесс принятия решения о внедрении той или иной фичи в проект. Если фича Widely available значит фича уже как минимум есть во всех основных браузерах как минимум стабильно используются последние 2.5 года.
Какие фичи в вебе стали Widely available в ноябре 2025?
color()— функция для работы с цветовыми пространствами (Display P3, Rec.2020 и др.)color-mix()— смешение цветов в заданном цветовом пространствеCompression Streams API — нативное сжатие и распаковка данных (gzip, deflate)
:nth-child(… of <selector>)— улучшенный псевдокласс для точного выбора элементовOklab и OkLCh — восприятие-ориентированные цветовые пространства
WebRTC:
RTCPeerConnection.sctp— доступ к информации о SCTP-транспортеLab и LCH — научно обоснованные цветовые пространства CIE
1. color()
Функция color() позволяет задавать цвет непосредственно в нужном цветовом пространстве, а не только в привычном srgb. Это особенно важно для современных дисплеев с широким цветовым охватом (wide-gamut).
Стандартное srgb охватывает лишь часть цветов, которые способен воспринимать человек — и тем более, часть цветов, которые способны отобразить современные экраны. Цветовые пространства вроде Display P3, Rec.2020 или ProPhoto RGB позволяют отображать более насыщенные, яркие и точные оттенки.
💡 Пример: в
srgbневозможно отобразить «реальный» красный цвет, который виден на дисплее с Display P3. Сcolor(display-p3 1 0 0)— можно.
Синтаксис
color(<colorspace> <coordinates>)
Поддерживаемые цветовые пространства включают:
srgb— стандартное RGB (0–1 или 0%–100%)srgb-linear— линейное RGB (для физически корректных вычислений)display-p3— широко используемое в Apple-устройствах и HDR-контентеrec2020— для Ultra HD и HDR видеоa98-rgb— Adobe RGBprophoto-rgb— для профессиональной цветокоррекцииxyz/xyz-d50/xyz-d65— CIE XYZ, базовое цветовое пространство
Примеры
/* Яркий красный в Display P3 */ .banner { background-color: color(display-p3 1 0 0); } /* Мягкий серый в линейном sRGB */ .text { color: color(srgb-linear 0.7 0.7 0.7); } /* Насыщенный зелёный в Rec.2020 */ .video-overlay { border-color: color(rec2020 0 0.9 0); }
Координаты указываются в диапазоне 0–1 (или в процентах, где 1 = 100%). В отличие от rgb(), здесь нет альфа-канала — если нужна прозрачность, используйте color(display-p3 1 0 0 / 0.8) (поддержка / для альфы зависит от браузера, но в Baseline 2025 — уже есть).
Практика: улучшение визуального восприятия на современных устройствах
Если ваш бренд использует насыщенные фирменные цвета (например, яркий синий или зелёный), они будут выглядеть тускло в sRGB, но восхитительно — на iPhone или MacBook с P3-дисплеем.
:root { --brand-primary: color(display-p3 0 0.6 1); /* насыщенный синий */ } .hero { background-color: var(--brand-primary); }
Практика: Создание HDR-совместимых интерфейсов
Для приложений, работающих с фотографиями, видео или творческими инструментами, точная цветопередача критична. color() даёт доступ к тем оттенкам, которые раньше были «заперты» в браузере.
Практика: Плавные градиенты и анимации в wide-gamut
Смешение цветов в Display P3 через color-mix() или градиенты с color() даёт более естественные переходы без «серых провалов», характерных для sRGB.
2. color-mix()
Функция color-mix() позволяет плавно смешивать два цвета в заданном цветовом пространстве — прямо в CSS, без препроцессоров или JavaScript. Это особенно ценно, потому что результат смешения зависит от выбранного цветового пространства: в srgb переходы могут выглядеть неестественно, а в Oklab, LCH или Display P3 — гладко и предсказуемо.
Раньше, чтобы получить оттенок цвета, приходилось вручную подбирать HEX/RGB-значения или использовать Sass-функции вроде mix() или darken(). Теперь браузер сам корректно смешает цвета — с учётом того, как человек воспринимает яркость и насыщенность.
💡 Пример: если смешать синий и чёрный в
srgb, получится тусклый, «грязный» оттенок. Вoklab— насыщенный тёмно-синий, сохраняющий чистоту тона.
Синтаксис
color-mix(in <colorspace>, <color> <percentage>, <color> <percentage>?)
<colorspace>— цветовое пространство, в котором происходит смешение (srgb,oklab,lch,display-p3и др.).Первый
<color>и<percentage>— первый цвет и его доля (например,70%).Второй цвет необязательно указывать с процентом: если не указан, берётся остаток до 100%.
Если процент не задан ни для одного цвета, по умолчанию используется 50/50.
Примеры
/* Смешать красный и белый в srgb (получим розовый) */ .button { background-color: color-mix(in srgb, red, white 30%); } /* Осветлить фирменный синий на 20% в Oklch — без потери насыщенности */ .card { border-top-color: color-mix(in oklch, var(--brand-blue) 80%, white); } /* Создать тёмный вариант фона для темной темы */ :root[data-theme="dark"] { --surface: color-mix(in oklab, var(--brand-gray) 90%, black); }
💡 Проценты можно указывать только для одного цвета — второй автоматически дополняет до 100%.
Например:
color-mix(in lch, blue 70%, white)= 70% синего + 30% белого.
Практика: динамические темы и оттенки без препроцессоров
С color-mix() вы можете генерировать всю палитру прямо в CSS:
светлые и тёмные варианты основных цветов,
hover-состояния кнопок,
градиенты с живыми переходами.
:root { --primary: oklch(65% 0.25 260); --primary-light: color-mix(in oklch, var(--primary), white 85%); --primary-dark: color-mix(in oklch, var(--primary), black 90%); }
Практика: адаптивные цвета для wide-gamut-дисплеев
Смешивайте цвета в display-p3, чтобы сохранить насыщенность даже в производных оттенках:
.hero-gradient { background-image: linear-gradient( to right, color-mix(in display-p3, var(--vibrant-red) 90%, white), color-mix(in display-p3, var(--vibrant-blue) 90%, white) ); }
Практика: естественные градиенты и анимации
Поскольку color-mix() работает в восприятие-ориентированных цветовых пространствах (вроде Oklab или LCH), анимации и градиенты выглядят плавно, без «серых провалов» или неожиданного изменения яркости — чего нельзя добиться в rgb() или hsl().
Важно: цветовое пространство влияет на результат
Сравните:
/* В srgb — тусклый, «мыльный» розовый */ .pink-srgb { background-color: color-mix(in srgb, red, white 70%); } /* В oklch — чистый, насыщенный пастельный розовый */ .pink-oklch { background-color: color-mix(in oklch, red, white 70%); }

Именно поэтому color-mix() особенно мощен в связке с современными цветовыми пространствами — oklab, lch, display-p3.
3. Compression Streams API
Compression Streams API — это встроенный в браузер инструмент для сжатия и распаковки данных с использованием алгоритмов gzip и deflate. Теперь вы можете обрабатывать объёмы данных в десятки и сотни мегабайт прямо в клиенте — без библиотек, без сервера и без блокировки основного потока.
Раньше для сжатия в браузере приходилось:
подключать тяжёлые библиотеки вроде
pakoилиfflate,жертвовать производительностью (всё происходило синхронно),
или отправлять данные на сервер только ради архивации.
Теперь всё это делается нативно, асинхронно и построчно, через потоки (Streams API).
💡 Пример: вы собираете логи работы приложения — 50 МБ текста. Вместо отправки «как есть», вы сжимаете их в gzip на лету и отправляете пакет в 5 МБ. Экономия трафика — 90%.
Синтаксис
API работает через два класса:
CompressionStream(format)— сжимает данныеDecompressionStream(format)— распаковывает
Поддерживаемые форматы:
'gzip''deflate'
Оба класса принимают поток на вход и возвращают преобразованный поток на выход, что позволяет легко встраивать их в цепочки обработки.
Практика: сжатие текста в gzip
async function compressText(text) { const stream = new Blob([text]).stream(); const compressedStream = stream.pipeThrough(new CompressionStream('gzip')); const compressedBlob = await new Response(compressedStream).blob(); return compressedBlob; } // Использование const logData = 'User performed action X...'; // длинная строка const compressed = await compressText(logData); console.log('Original size:', logData.length); console.log('Compressed size:', compressed.size);
Практика: распаковка полученного файла
async function decompressBlob(blob) { const stream = blob.stream(); const decompressedStream = stream.pipeThrough(new DecompressionStream('gzip')); const text = await new Response(decompressedStream).text(); return text; }
💡 Всё работает через ReadableStream → TransformStream → ReadableStream, поэтому вы можете комбинировать сжатие с шифрованием, отправкой через
fetch, записью в IndexedDB и т.д.
Практика: отправка аналитики и логов с минимальным трафиком
Собираете события, ошибки, метрики производительности? Сжимайте их перед отправкой:
const events = JSON.stringify(collectedEvents); const blob = await compressText(events); await fetch('/api/logs', { method: 'POST', body: blob, headers: { 'Content-Encoding': 'gzip' } });
Сервер (например, Nginx или Cloudflare) может автоматически распаковать такие данные, если указан правильный заголовок.
Практика: Работа с большими файлами в веб-приложениях
Пользователь загрузил CSV или JSON-файл размером 100 МБ? Вы можете:
сжать его перед сохранением в
IndexedDB,позволить экспортировать «архив» без участия сервера,
предварительно обработать перед отправкой на бэкенд.
Практика: обработка данных в офлайне
В PWA или оффлайн-редакторе можно сжимать документы на лету и сохранять их компактно — особенно полезно на устройствах с ограниченным хранилищем.
Совместимость с существующими форматами
Файлы, сжатые через CompressionStream('gzip'), — это стандартные .gz-файлы. Их можно открыть любым архиватором или сервером. То же самое с deflate.
4. :nth-child(… of <selector>)
Псевдокласс :nth-child() получил долгожданное улучшение: теперь он может считать только те элементы, которые соответствуют заданному селектору, а не всех подряд. Это решает одну из самых раздражающих проблем CSS — невозможность точно выбрать «n-й элемент нужного типа» среди всех соседей.
Раньше :nth-child(2) означало «второй дочерний элемент вообще», даже если он не был нужного тега или класса. Чтобы выбрать, например, вторую кнопку среди множества других элементов, приходилось использовать костыли: обёртки, кастомные классы или JavaScript.
Теперь синтаксис :nth-child(An+B of S) позволяет писать точные, читаемые и семантически верные селекторы — прямо в CSS.
💡 Пример: у вас список из 10 элементов: чередуются
<div>,<button>,<span>. Вы хотите выделить вторую кнопку. Раньше — почти невозможно без классов. Теперь —button:nth-child(2 of button).
Синтаксис
:nth-child(An+B of <селектор>) :nth-last-child(An+B of <селектор>)
An+B— стандартная формула (например,2,odd,3n+1).<селектор>— любой валидный CSS-селектор (класс, тег, атрибут и т.д.).Отсчёт ведётся только среди элементов, соответствующих селектору, но позиция проверяется в контексте всех соседей.
Аналогично работает :nth-last-child(… of …) — отсчёт с конца.
Примеры
/* Второй элемент с классом .item */ .item:nth-child(2 of .item) { border-top: 2px solid red; } /* Каждая нечётная кнопка среди всех кнопок */ button:nth-child(odd of button) { background-color: #f0f0f0; } /* Последний активный пункт меню */ .menu-item:nth-last-child(1 of .menu-item.active) { margin-bottom: 0; } /* Третий <li> с атрибутом data-visible="true" */ li:nth-child(3 of [data-visible="true"]) { font-weight: 700; }
💡 Важно: элемент должен одновременно соответствовать селектору и занимать n-ю позицию среди таких же. Но сама проверка позиции учитывает всех соседей — это соответствует логике DOM.
Практика: стилизация динамических списков без JavaScript
В React, Vue или другом фреймворке часто рендерятся списки с условной логикой:
<ul> <li class="ad">Реклама</li> <li class="post">Пост 1</li> <li class="ad">Реклама</li> <li class="post">Пост 2</li> <li class="post">Пост 3</li> </ul>
Как выделить второй пост? Раньше — только через :nth-of-type() (не работает с классами) или кастомный data-index. Теперь:
.post:nth-child(2 of .post) { border-left: 4px solid #007AFF; }
Практика: гибкие таблицы и карточки
В адаптивных сетках или таблицах с условным отображением строк (например, «скрытые» или «заблокированные») можно точно стилизовать каждую n-ю видимую запись:
.row:nth-child(even of .row:not(.hidden)) { background-color: #fafafa; }
Чистые и поддерживаемые компоненты
Больше не нужно генерировать классы вроде .item--index-2 на стороне JS. Вся логика — в CSS, а структура остаётся семантичной.
5. Oklab и OkLCh
Oklab и OkLCh — это современные цветовые пространства, созданные не для машин, а для человеческого восприятия. В отличие от привычных rgb() или hsl(), они обеспечивают равномерные градиенты, предсказуемую яркость и естественное смешение цветов — без «серых провалов», неожиданной потери насыщенности или странного поведения при анимациях.
Раньше, чтобы добиться плавного перехода от тёмно-синего к светло-голубому, приходилось подбирать промежуточные цвета вручную или использовать сложные алгоритмы в JavaScript. Теперь всё это работает нативно в CSS через функции oklab() и oklch().
💡 Пример: если вы создадите градиент
linear-gradient(hsl(240, 100%, 30%), hsl(240, 100%, 80%)), в середине он станет неожиданно серым. Сoklch(50% 0.3 240)→oklch(80% 0.3 240)— переход будет гладким и насыщенным от начала до конца.
Что такое Oklab и OkLCh?
Oklab — трёхмерное цветовое пространство с координатами:
L — светлота (0% = чёрный, 100% = белый),
a — от зелёного (–) к красному (+),
b — от синего (–) к жёлтому (+).
OkLCh — та же система, но в полярных координатах (как HSL, но умный):
L — светлота,
C — хрома (насыщенность),
h — оттенок (hue) в градусах (0–360°).
Синтаксис
/* Oklab: L a b */ color: oklab(60% 0.1 -0.05); /* OkLCh: L C h */ color: oklch(70% 0.25 260);
L — от
0%до100%(или0–1).a, b — обычно от
–0.4до+0.4(но могут выходить за пределы).C — хрома, чем выше, тем насыщеннее (максимум ≈
0.4для отображаемых цветов).h — оттенок в градусах, как в
hsl().
Поддерживается альфа-канал через /:
background-color: oklch(80% 0.15 120 / 0.9);
Примеры
/* Насыщенный фиолетовый */ .card-header { background-color: oklch(65% 0.3 300); } /* Тёплый серый без цветового оттенка */ .text-muted { color: oklab(50% 0 0); } /* Плавный акцентный цвет с контролируемой насыщенностью */ :root { --accent: oklch(72% 0.22 45); /* золотисто-оранжевый */ }
Практика: создание гармоничных тем и палитр
Поскольку L (светлота) отделена от C (насыщенности), вы можете:
менять яркость темы, не трогая оттенок,
генерировать оттенки с одинаковой насыщенностью,
легко строить контрастные пары по WCAG.
:root { --primary-hue: 260; --primary-500: oklch(68% 0.25 var(--primary-hue)); --primary-300: oklch(82% 0.25 var(--primary-hue)); /* светлее, но той же насыщенности */ --primary-700: oklch(50% 0.25 var(--primary-hue)); /* темнее */ }
Практика: естественные градиенты и анимации
Градиенты в OkLCh не теряют насыщенность посередине:
.hero { background-image: linear-gradient( to right, oklch(70% 0.25 220), oklch(70% 0.25 300) ); }
Анимация яркости или насыщенности теперь выглядит физически корректно:
.button:hover { color: oklch(60% 0.28 260); transition: color 0.2s ease; }
Точные цветовые вычисления с color-mix()
Oklab и OkLCh — идеальные цветовые пространства для color-mix(), потому что смешение в них сохраняет воспринимаемую яркость:
/* Осветление без «побеления» */ .hover-bg { background-color: color-mix(in oklch, var(--brand) 90%, white); }
6. WebRTC: RTCPeerConnection.sctp
Свойство sctp в интерфейсе RTCPeerConnection наконец стало Widely available — и с ним в веб приходит прямой доступ к информации о SCTP-транспорте, лежащем в основе RTCDataChannel. Это не просто «ещё одно свойство», а важный шаг к отладке, мониторингу и управлению P2P-соединениями на уровне, который раньше был доступен только в нативных приложениях.
До появления pc.sctp разработчики WebRTC-приложений были «слепы» к состоянию канала данных: они могли отправлять и получать сообщения, но не видели, насколько велик буфер, поддерживается ли соединение, каков максимальный размер сообщения и работает ли транспорт вообще.
💡 Пример: вы отправляете 10 МБ данных через
RTCDataChannel, но соединение нестабильно. Безsctpвы не узнаете, почему — то ли сеть, то ли превышен лимит. Сpc.sctp.maxMessageSizeиpc.sctp.state— получаете точные метрики.
Что такое SCTP и зачем он нужен?
SCTP (Stream Control Transmission Protocol) — это транспортный протокол, используемый WebRTC для надёжной или частично надёжной передачи данных через RTCDataChannel. Он обеспечивает:
упорядоченную или неупорядоченную доставку,
управление потоками,
контроль перегрузки,
безопасность (через DTLS).
Хотя вы работаете с RTCDataChannel, «под капотом» всё это управляется SCTP — и теперь вы можете заглянуть «под капот».
Синтаксис и доступные данные
После установки соединения (обычно после negotiationneeded и iceconnectionstatechange) у RTCPeerConnection появляется объект sctp:
const pc = new RTCPeerConnection(); const channel = pc.createDataChannel('messaging'); // Позже, когда соединение установлено: pc.addEventListener('connectionstatechange', () => { if (pc.sctp) { console.log('SCTP ready!'); console.log('Max message size:', pc.sctp.maxMessageSize); console.log('State:', pc.sctp.state); // "connected", "closed" и т.д. } });
Основные свойства RTCSctpTransport:
maxMessageSize— максимальный размер одного сообщения в байтах (часто ~64 КБ, но зависит от реализации).state— состояние транспорта:"new","connecting","connected","closed".transport— ссылка на underlying DTLS-транспорт (для продвинутой диагностики).
💡
maxMessageSizeособенно важен: если вы попытаетесь отправить сообщение больше этого значения — оно не будет доставлено, и ошибки в консоли может не быть!
Практика: безопасная отправка больших данных
Разбивайте большие сообщения на чанки, зная точный лимит:
function sendLargeMessage(channel, pc, data) { const maxSize = pc.sctp?.maxMessageSize || 16384; // fallback const chunks = splitIntoChunks(data, maxSize); chunks.forEach(chunk => channel.send(chunk)); }
Практика: мониторинг и отладка в продакшене
Логируйте состояние соединения для анализа проблем:
if (pc.sctp) { analytics.track('webrtc-sctp', { state: pc.sctp.state, maxMessageSize: pc.sctp.maxMessageSize, browser: navigator.userAgent }); }
Практика: улучшение UX в P2P-приложениях
Если pc.sctp.state === 'closed', вы можете:
показать уведомление «Соединение с коллегой потеряно»,
предложить переподключиться,
автоматически переключиться на резервный канал.
7. Lab и LCH
Lab и LCH — это научно обоснованные цветовые пространства, разработанные ещё в 1976 году Комитетом по освещению (CIE), но до недавнего времени недоступные в CSS. Теперь, став Widely available в Baseline (ноябрь 2025), они открывают веб-разработчикам доступ к точной, восприятие-ориентированной модели цвета, где яркость, насыщенность и оттенок ведут себя предсказуемо — в отличие от rgb() или hsl().
Если rgb() описывает, как смешать свет, а hsl() — попытка упростить это для человека, то Lab/LCH описывают, как человек видит цвет. Это разница между «технической инструкцией» и «психофизиологией».
💡 Пример: в
hsl(0, 100%, 50%)(красный) иhsl(60, 100%, 50%)(жёлтый) значение «lightness» одинаково — 50%. Но на глаз жёлтый выглядит гораздо светлее. В LCH светлота (L) соответствует реальному восприятию: жёлтый будет иметьL ≈ 97%, а красный —L ≈ 54%.
Синтаксис
/* Lab: L a b */ color: lab(54% 81 69); /* красный */ color: lab(97% -21 94); /* жёлтый */ /* LCH: L C H */ color: lch(54% 106 41); /* тот же красный */ color: lch(97% 96 100); /* тот же жёлтый */
L — от
0%до100%.a, b — обычно от
–100до+100(но могут быть и больше).C — хрома, теоретически до ~
130, но на практике ограничен отображаемыми цветами.H — оттенок в градусах, как в
hsl().
Поддержка прозрачности через /:
background-color: lch(70% 50 260 / 0.85);
Примеры
/* Точный нейтральный серый — без цветового оттенка */ .text { color: lab(50% 0 0); } /* Яркий, но не «вырвиглазный» акцент */ .button { background-color: lch(65% 60 320); /* насыщенный пурпурный */ } /* Гармоничная палитра с фиксированной насыщенностью */ :root { --hue: 180; --primary-500: lch(70% 40 var(--hue)); --primary-300: lch(85% 40 var(--hue)); --primary-700: lch(50% 40 var(--hue)); }
Практика: семантические цветовые системы
Меняйте только оттенок или только яркость, не затрагивая остальное:
/* Все кнопки — разные оттенки, но одинаковой насыщенности и яркости */ .button--alarm { background: lch(68% 45 30); } .button--green { background: lch(68% 45 140); } .button--blue { background: lch(68% 45 260); }
Практика: точное смешение с color-mix()
LCH — отличное пространство для color-mix(), особенно если вы хотите сохранить воспринимаемую яркость:
.hover-bg { background-color: color-mix(in lch, var(--brand) 90%, white); }
Отличия от Oklab/Oklch
Lab/LCH и Oklab/Oklch похожи, но есть нюансы:
Lab/LCH — стандарт CIE, используется в полиграфии, фотографии, науке.
Oklab/Oklch — более новая модель, оптимизированная под отображаемые цвета и часто даёт чуть более насыщенные результаты в вебе.
Обе работают отлично, но LCH — «промышленный стандарт», а OkLCh — «оптимизирован для веба».
Выбор зависит от задачи. Для большинства UI — подойдёт Oklab/Oklch . Для точной цветопередачи (например, в дизайн-системах медицинских или печатных приложений) — предпочтителен LCH.
Следующий выпуск — в начале января 2026 года после праздников. До встречи!
