В июле AVIF и несколько возможностей CSS и JavaScript получили статус широко доступных. Для вёрстки это повод проверить изображения и декоративные формы, а для фронтенда — поработать с асинхронными данными и календарями.

Выбрали прикладные темы из июльского выпуска Web Features Explorer. Статусы и примеры сверены на 9 октября 2026 года. Дата в обзоре отмечает изменение доступности: часть этих возможностей появилась в браузерах значительно раньше июля.

Newly Available означает, что возможность поддерживают актуальные основные браузеры. До статуса Widely Available проходит ещё 30 месяцев. Старые версии и встроенные браузеры приложений нужно проверять отдельно, ориентируясь на аудиторию своего проекта.

Что получили актуальные браузеры

Intl.Locale: с какого дня начинается неделя

У календаря записи есть маленькая, но заметная деталь: первый день недели. В русскоязычном интерфейсе обычно ждут понедельник. Для другой локали порядок может отличаться.

Метод getWeekInfo() возвращает сведения о неделе для выбранной локали. В июле группа методов Intl.Locale info стала Newly Available: недостающую поддержку добавил Firefox 153. Сам объект Intl.Locale существовал и раньше. Карточка поддержки в Explorer.

В примере подготовим подписи столбцов календаря. Значение firstDay нумерует дни от одного до семи, начиная с понедельника, поэтому для индекса массива вычитаем единицу.

function getWeekStart(tag, fallbackFirstDay) {
  const locale = new Intl.Locale(tag);

  if (typeof locale.getWeekInfo === 'function') {
    return locale.getWeekInfo().firstDay;
  }

  return fallbackFirstDay;
}

const firstDay = getWeekStart('ru-RU', 1);
const weekdays = ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс'];
const offset = firstDay - 1;
const orderedDays = weekdays.slice(offset).concat(weekdays.slice(0, offset));

console.log(orderedDays.join(' '));
// Пн Вт Ср Чт Пт Сб Вс

Подписи готовы. Запасной первый день передаём из настроек интерфейса. В этом примере выбрали понедельник; для других локалей такую настройку нужно задавать отдельно. Сам метод также сообщает выходные дни и минимальное число дней в первой неделе года — пригодится, если календарь показывает номера недель. Описание getWeekInfo на MDN.

Локаль описывает языковые и региональные соглашения. Она не сообщает, в каком часовом поясе находится конкретный человек. Форматирование дат и выбор часового пояса остаются отдельными задачами.

Что стало широко доступным

AVIF: подготовьте второй вариант фотографии

25 июля AVIF перешёл в Widely Available. Формат подходит для фотографий и поддерживает прозрачность. Начать можно с изображения в карточке товара: подготовьте AVIF и сохраните JPEG для браузеров, которым нужен запасной вариант. Карточка AVIF в Explorer.

<picture>
  <source srcset="backpack.avif" type="image/avif">
  <img
    src="backpack.jpg"
    width="800"
    height="600"
    alt="Синий походный рюкзак с наружным карманом"
  >
</picture>

Оба файла должны содержать одну фотографию с одинаковыми пропорциями. Браузер выбирает подходящий источник, а размеры и альтернативный текст получает из img. Здесь нужен настоящий экспорт в AVIF: переименование файла .jpg в .avif формат не меняет.

Получился ли файл меньше? На этапе подготовки сравните варианты при приемлемом качестве. Посмотрите на мелкие надписи и границы предметов; затем проверьте размер файла. AVIF часто помогает сжать фотографию, но выигрыш на конкретном изображении нужно измерить. Существующее изображение не стоит заменять только ради нового расширения.

Если фотография находится на первом экране и определяет LCP, не добавляйте ей loading="lazy". Для карточек ниже первого экрана отложенная загрузка может быть уместна. Формат изображения и момент его загрузки решают разные задачи. Возможности AVIF и запасные форматы на MDN.

rect() и xywh(): прямоугольное окно в декоре

23 июля функции rect() и xywh() стали широко доступными. Они описывают прямоугольную форму для clip-path; выбранная часть элемента остаётся видимой. Попробуем на цветной декоративной плашке, где обрезка не затрагивает текст или кнопки. Поддержка rect и xywh в Explorer.

<div class="decoration" aria-hidden="true"></div>
.decoration {
  width: 240px;
  height: 160px;
  background: linear-gradient(135deg, #7b61ff, #ffbf69);
  clip-path: inset(20px 40px 20px 40px round 12px);
}

@supports (clip-path: xywh(0 0 100% 100%)) {
  .decoration {
    clip-path: xywh(40px 20px 160px 120px round 12px);
  }
}

В xywh() сначала идут координаты верхнего левого угла, затем ширина и высота. Здесь окно начинается в точке 40px 20px и имеет размеры 160px на 120px. Для браузера без поддержки остаётся inset() с той же видимой областью.

Тот же прямоугольник можно описать через rect():

.decoration {
  clip-path: rect(20px 200px 140px 40px round 12px);
}

У rect() порядок значений — верхняя, правая, нижняя и левая границы. Верх и низ отсчитываются от верхнего края элемента, право и лево — от левого. Поэтому 200px означает координату правой границы. У inset() это значение обозначало бы отступ справа: переносить числа между функциями без пересчёта нельзя. rect на MDN, xywh на MDN.

Место в раскладке сохранится. Обрезка меняет видимую область, но элемент по-прежнему занимает свой прямоугольник. Для фотографии товара чаще достаточно object-fit; clip-path стоит брать, когда нужна именно фигурная видимая область.

Array.fromAsync(): собрать значения из асинхронного источника

Метод Array.fromAsync() стал Widely Available 25 июля. Он возвращает промис с новым массивом и умеет читать асинхронную последовательность. В учебном примере источник выдаёт товары по одному, а мы собираем их названия. Карточка Array.fromAsync в Explorer.

async function* getProducts() {
  yield { id: 1, title: 'Рюкзак' };
  yield { id: 2, title: 'Термос' };
}

async function showTitles() {
  try {
    const titles = await Array.fromAsync(
      getProducts(),
      (product) => product.title
    );

    console.log(titles);
    // ['Рюкзак', 'Термос']
  } catch (error) {
    console.error('Не удалось собрать названия', error);
  }
}

showTitles();

Функция со звёздочкой создаёт асинхронный генератор. yield выдаёт следующий товар, а второй аргумент Array.fromAsync() преобразует его в название. Сбор продолжается до конца последовательности.

Следующий элемент ждёт. Метод последовательно запрашивает и ожидает элементы, а также ожидает результат функции преобразования. Если поместить в эту функцию загрузку файла, следующая загрузка начнётся после завершения предыдущей. Для одновременного запуска независимых запросов по массиву адресов обычно вызывают map(), а завершения всех запросов дожидаются через Promise.all(). Менять этот подход на Array.fromAsync() ради ускорения не стоит. Подробности ожидания на MDN.

Для среды без метода можно сохранить тот же порядок с for await...of:

async function collectTitles() {
  const titles = [];

  for await (const product of getProducts()) {
    titles.push(product.title);
  }

  return titles;
}

collectTitles().then(console.log).catch(console.error);

Оба варианта создают новый генератор вызовом getProducts(). Бесконечную последовательность собирать целиком в массив нельзя: она не закончится. Накопленные значения будут занимать память.

Что попробовать в своём проекте

Начните с одной фотографии в каталоге. Такой эксперимент покажет измеримый результат: сколько весит выбранный файл и сохраняется ли нужное качество. Остальные примеры подключайте под задачу. Календарю пригодятся сведения о неделе, декоративной плашке — форма. Для асинхронного источника можно попробовать сбор значений.

  • Сверьте минимальные версии браузеров проекта с карточкой выбранной возможности.
  • Убедитесь, что запасной вариант даёт тот же смысл и результат.
  • Проверьте изображение при медленном соединении и смене ширины окна.
  • Уберите обрезку с текста и интерактивных элементов, если она мешает читать или видеть фокус.

Для самостоятельной проверки задайте два вопроса: какой файл реально загрузился вместо backpack.jpg и что покажет календарь, если getWeekInfo() недоступен? Ответы стоит получить в инструментах браузера, прежде чем переносить пример на остальные карточки.


«Доктайп» — журнал о фронтенде. Читайте, слушайте и учитесь с нами.

ТелеграмПодкастБесплатные учебники