Практический обзор CSS Houdini

Опубликовано: 2022-03-10
Краткое резюме ↬ Houdini, общий термин для набора браузерных API, направлен на внесение значительных улучшений в процесс веб-разработки и разработку стандартов CSS в целом. Разработчики внешнего интерфейса смогут расширять CSS новыми функциями с помощью JavaScript, подключаться к механизму рендеринга CSS и сообщать браузеру, как применять CSS во время процесса рендеринга. Поддержка браузеров Houdini улучшается, и некоторые API-интерфейсы уже доступны для использования, так что самое время ознакомиться с ними и поэкспериментировать. Мы рассмотрим каждую часть Houdini, его текущую поддержку браузера и посмотрим, как их можно использовать сегодня с помощью прогрессивного улучшения.

Требуется много времени, чтобы новая функция CSS или улучшение превратились из первоначального проекта в полностью поддерживаемую и стабильную функцию CSS, которую могут использовать разработчики. Полифилы на основе JavaScript можно использовать в качестве замены отсутствия поддержки браузера, чтобы использовать новые функции CSS до того, как они будут официально реализованы. Но в большинстве случаев они ошибочны. Например, scrollsnap-polyfill — один из нескольких полифилов, которые можно использовать для исправления несоответствий поддержки браузером спецификации CSS Scroll Snap. Но даже это решение имеет некоторые ограничения, ошибки и несоответствия.

Потенциальным недостатком полифиллов является то, что они могут отрицательно сказаться на производительности и их сложно реализовать должным образом. Этот недостаток связан с DOM и CSSOM браузера. Браузер создает DOM (объектную модель документа) из разметки HTML и аналогичным образом создает CSSOM (объектную модель CSS) из разметки CSS. Эти два дерева объектов независимы друг от друга. JavaScript работает с DOM и имеет очень ограниченный доступ к CSSOM.

Решения JavaScript Polyfill запускаются только после завершения начального цикла рендеринга, т. е. после создания и DOM, и CSSOM, и завершения загрузки документа. После того, как Polyfill вносит изменения в стили в DOM (путем их встраивания), он вызывает повторный запуск процесса рендеринга и повторную визуализацию всей страницы. Отрицательное влияние на производительность становится еще более очевидным, если они полагаются на метод requestAnimationFrame или зависят от действий пользователя, таких как события прокрутки.

Еще одним препятствием в веб-разработке являются различные ограничения, накладываемые стандартами CSS . Например, существует лишь ограниченное количество свойств CSS, которые можно анимировать изначально. CSS знает, как анимировать цвета, но не знает, как анимировать градиенты. Всегда была потребность в инновациях и создании впечатляющих веб-приложений, раздвигая границы, несмотря на технические ограничения. Вот почему разработчики часто стремятся использовать далеко не идеальные обходные пути или JavaScript для реализации более сложных стилей и эффектов, которые в настоящее время не поддерживаются CSS, таких как макет каменной кладки, расширенные 3D-эффекты, расширенная анимация, плавная типографика, анимированные градиенты и т. д. стилизованные элементы select и т. д.

Кажется невозможным, чтобы спецификации CSS соответствовали различным требованиям отрасли, таким как больший контроль над анимацией, улучшенное усечение текста, улучшенные параметры стиля для элементов input и select , дополнительные параметры display , дополнительные параметры filter и т. д.

Каким может быть потенциальное решение? Предоставьте разработчикам собственный способ расширения CSS с помощью различных API . В этой статье мы рассмотрим, как разработчики внешнего интерфейса могут сделать это с помощью Houdini API, JavaScript и CSS. В каждом разделе мы рассмотрим каждый API по отдельности, проверим его поддержку браузерами и текущую спецификацию, а также посмотрим, как их можно реализовать сегодня с помощью прогрессивного улучшения.

Еще после прыжка! Продолжить чтение ниже ↓

Что такое Гудини?

Houdini, общий термин для набора API-интерфейсов браузера, направлен на внесение значительных улучшений в процесс веб-разработки и разработку стандартов CSS в целом. Разработчики смогут расширять CSS новыми функциями с помощью JavaScript, подключаться к механизму рендеринга CSS и сообщать браузеру, как применять CSS во время процесса рендеринга. Это приведет к значительному повышению производительности и стабильности по сравнению с использованием обычных полифиллов.

Спецификация Houdini состоит из двух групп API — API высокого уровня и API низкого уровня .

Высокоуровневые API тесно связаны с процессом рендеринга в браузере (стиль → макет → рисование → композит). Это включает в себя:

  • API краски
    Точка расширения для шага рендеринга браузера, на котором определяются визуальные свойства (цвет, фон, граница и т. д.).
  • API макета
    Точка расширения для шага рендеринга макета в браузере, на котором определяются размеры, положение и выравнивание элементов.
  • API анимации
    Точка расширения для шага составного рендеринга браузера, когда слои отображаются на экране и анимируются.

API низкого уровня формируют основу для API высокого уровня. Это включает в себя:

  • API модели типизированных объектов
  • API пользовательских свойств и значений
  • API метрик шрифтов
  • Ворклеты

Некоторые API-интерфейсы Houdini уже доступны для использования в некоторых браузерах с другими API-интерфейсами, чтобы последовать их примеру, когда они будут готовы к выпуску.

Будущее CSS

В отличие от обычных спецификаций функций CSS, которые были представлены до сих пор, Houdini выделяется тем, что позволяет разработчикам расширять CSS более естественным образом. Означает ли это, что спецификации CSS перестанут развиваться и не будет выпускаться новых официальных реализаций функций CSS? Ну, это не так. Цель Houdini — помочь процессу разработки функций CSS, позволяя разработчикам создавать рабочие прототипы, которые можно легко стандартизировать.

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

API модели типизированных объектов

До появления Houdini единственным способом взаимодействия JavaScript с CSS был парсинг CSS, представленный в виде строковых значений, и их изменение. Разбор и переопределение стилей вручную может быть сложным и подверженным ошибкам из-за того, что тип значения необходимо менять вперед и назад, а единицу измерения необходимо добавлять вручную при назначении нового значения.

 selectedElement.style.fontSize = newFontSize + "px"; // newFontSize = 20 console.log(selectedElement.style.fontSize); // "20px"

Типизированная объектная модель (Typed OM) API добавляет больше семантического значения значениям CSS, предоставляя их как типизированные объекты JavaScript. Это значительно улучшает соответствующий код и делает его более производительным, стабильным и удобным в сопровождении. Значения CSS представлены интерфейсом CSSUnitValue , который состоит из значения и свойства модуля.

 { value: 20, unit: "px" }

Этот новый интерфейс можно использовать со следующими новыми свойствами:

  • computedStyleMap() : для разбора вычисляемых (не встроенных) стилей. Это метод выбранного элемента, который необходимо вызвать перед синтаксическим анализом или использованием других методов.
  • attributeStyleMap : для анализа и изменения встроенных стилей. Это свойство, доступное для выбранного элемента.
 // Get computed styles from stylesheet (initial value) selectedElement.computedStyleMap().get("font-size"); // { value: 20, unit: "px"} // Set inline styles selectedElement.attributeStyleMap.set("font-size", CSS.em(2)); // Sets inline style selectedElement.attributeStyleMap.set("color", "blue"); // Sets inline style // Computed style remains the same (initial value) selectedElement.computedStyleMap().get("font-size"); // { value: 20, unit: "px"} // Get new inline style selectedElement.attributeStyleMap.get("font-size"); // { value: 2, unit: "em"}

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

Методы get и set — это лишь небольшое подмножество всех доступных методов, определенных Typed OM API. Некоторые из них включают:

  • clear : удаляет все встроенные стили
  • delete : удаляет указанное свойство CSS и его значение из встроенных стилей.
  • has : возвращает логическое значение, если задано указанное свойство CSS.
  • append : добавляет дополнительное значение к свойству, которое поддерживает несколько значений
  • и т.п.

Обнаружение функций

 var selectedElement = document.getElementById("example"); if(selectedElement.attributeStyleMap) { /* ... */ } if(selectedElement.computedStyleMap) { /* ... */ }

Статус спецификации W3C

  • Рабочий проект: опубликован для рассмотрения сообществом

Поддержка браузера

Гугл Хром Microsoft Edge Опера Браузер Fire Fox Сафари
Поддерживается Поддерживается Поддерживается Не поддерживается Частичная поддержка (*)

* поддерживается с включенными флажками «Экспериментальные функции веб-платформы» или другими функциями.

Источник данных: Houdini уже готов?

API пользовательских свойств и значений

API свойств и значений CSS позволяет разработчикам расширять переменные CSS, добавляя тип, начальное значение и определяя наследование. Разработчики могут определять настраиваемые свойства CSS, регистрируя их с помощью метода registerProperty , который сообщает браузерам, как выполнить переход и обработать откат в случае ошибки.

 CSS.registerProperty({ name: "--colorPrimary", syntax: "<color>", inherits: false, initialValue: "blue", });

Этот метод принимает входной аргумент, который является объектом со следующими свойствами:

  • name : имя пользовательского свойства
  • syntax : сообщает браузеру, как анализировать пользовательское свойство. Это предопределенные значения, такие как <color> , <integer> , <number> , <length> , <percentage> и т. д.
  • inherits : сообщает браузеру, наследует ли пользовательское свойство значение своего родителя.
  • initialValue : указывает начальное значение, которое используется до тех пор, пока оно не будет переопределено, и используется как запасной вариант в случае ошибки.

В следующем примере задается пользовательское свойство типа <color> . Это пользовательское свойство будет использоваться при градиентном переходе. Вы можете подумать, что текущий CSS не поддерживает переходы для фоновых градиентов, и вы будете правы. Обратите внимание, как само пользовательское свойство используется в transition вместо свойства background , которое использовалось бы для обычных переходов background-color .

 .gradientBox { background: linear-gradient(45deg, rgba(255,255,255,1) 0%, var(--colorPrimary) 60%); transition: --colorPrimary 0.5s ease; /* ... */ } .gradientBox:hover { --colorPrimary: red /* ... */ }

Браузер не знает, как обрабатывать градиентный переход, но он знает, как обрабатывать переходы цвета, поскольку пользовательское свойство указано как тип <color> . В браузере, который поддерживает Houdini, при наведении на элемент произойдет градиентный переход. Процент положения градиента также можно заменить пользовательским свойством CSS (зарегистрированным как тип <percentage> ) и добавить к переходу так же, как в примере.

Если registerProperty удален, а обычное настраиваемое свойство CSS зарегистрировано в селекторе :root , градиентный переход не будет работать. Требуется, чтобы registerProperty использовалось, чтобы браузер знал, что он должен рассматривать его как цвет.

В будущей реализации этого API можно будет зарегистрировать пользовательское свойство непосредственно в CSS.

 @property --colorPrimary { syntax: "<color>"; inherits: false; initial-value: blue; }

Пример

Этот простой пример демонстрирует переход цвета градиента и положения при наведении курсора с использованием зарегистрированных пользовательских свойств CSS для цвета и положения соответственно. Полный исходный код доступен в репозитории примера.

Цвет и положение анимированного градиента с использованием API пользовательских свойств и значений. Задержка для каждого свойства, добавленного для эффекта в свойстве перехода CSS. (Большой превью)

Обнаружение функций

 if (CSS.registerProperty) { /* ... */ }

Статус спецификации W3C

  • Рабочий проект: опубликован для рассмотрения сообществом

Поддержка браузера

Гугл Хром Microsoft Edge Опера Браузер Fire Fox Сафари
Поддерживается Поддерживается Поддерживается Не поддерживается Не поддерживается

Источник данных: Houdini уже готов?

API метрик шрифтов

API Font Metrics все еще находится на очень ранней стадии разработки, поэтому его спецификация может измениться в будущем. В своем текущем проекте Font Metrics API будет предоставлять методы измерения размеров текстовых элементов, отображаемых на экране, чтобы позволить разработчикам влиять на то, как текстовые элементы отображаются на экране. Эти значения сложно или невозможно измерить с помощью текущих функций, поэтому этот API позволит разработчикам проще создавать функции CSS, связанные с текстом и шрифтами. Многострочное динамическое усечение текста является примером одной из таких функций.

Статус спецификации W3C

  • Сборник идей: на данный момент проект спецификации не представлен

Поддержка браузера

Гугл Хром Microsoft Edge Опера Браузер Fire Fox Сафари
Не поддерживается Не поддерживается Не поддерживается Не поддерживается Не поддерживается

Источник данных: Houdini уже готов?

Ворклеты

Прежде чем перейти к другим API, важно объяснить концепцию Worklets. Ворклеты — это сценарии, которые запускаются во время рендеринга и не зависят от основной среды JavaScript. Они являются точкой расширения для механизмов рендеринга. Они предназначены для параллелизма (с 2 или более экземплярами) и не зависят от потоков, имеют ограниченный доступ к глобальной области видимости и вызываются механизмом рендеринга при необходимости. Ворклеты можно запускать только по протоколу HTTPS (в производственной среде) или на локальном хосте (в целях разработки).

Houdini представляет следующие Worklets для расширения механизма рендеринга браузера:

  • Paint Worklet — Paint API
  • Animation Worklet — API анимации
  • Layout Worklet — API макета

API краски

Paint API позволяет разработчикам использовать функции JavaScript для рисования непосредственно на фоне, границе или содержимом элемента с помощью контекста 2D-рендеринга, который является подмножеством API Canvas HTML5. Paint API использует Paint Worklet для рисования изображения, которое динамически реагирует на изменения в CSS (например, изменения в переменных CSS). Любой, кто знаком с Canvas API, будет чувствовать себя как дома с API рисования Houdini.

Для определения Paint Worklet необходимо выполнить несколько шагов:

  1. Напишите и зарегистрируйте Paint Worklet, используя функцию registerPaint .
  2. Вызовите Worklet в файле HTML или основном файле JavaScript, используя функцию CSS.paintWorklet.addModule
  3. Используйте функцию paint() в CSS с именем Worklet и необязательными входными аргументами.

Давайте взглянем на функцию registerPaint , которая используется для регистрации ворклета Paint и определения его функциональности.

 registerPaint("paintWorketExample", class { static get inputProperties() { return ["--myVariable"]; } static get inputArguments() { return ["<color>"]; } static get contextOptions() { return {alpha: true}; } paint(ctx, size, properties, args) { /* ... */ } });

Функция registerPaint состоит из нескольких частей:

  • inputProperties :
    Массив пользовательских свойств CSS, которые Worklet будет отслеживать. Этот массив представляет зависимости ворлета рисования.
  • inputArguments :
    Массив входных аргументов, которые могут быть переданы из функции paint внутри CSS.
  • contextOptions : разрешить или запретить непрозрачность цветов. Если установлено значение false , все цвета будут отображаться с полной непрозрачностью.
  • paint : основная функция, которая предоставляет следующие аргументы:
    • ctx : контекст 2D-рисования, почти идентичный контексту 2D-рисования Canvas API.
    • size : объект, содержащий ширину и высоту элемента. Значения определяются процессом рендеринга макета. Размер холста совпадает с фактическим размером элемента.
    • properties : входные переменные, определенные в inputProperties
    • args : массив входных аргументов, переданных в функцию paint в CSS.

После регистрации Worklet его необходимо вызвать в файле HTML, просто указав путь к файлу.

 CSS.paintWorklet.addModule("path/to/worklet/file.js");

Любой ворклет также можно добавить с внешнего URL-адреса (например, из сети доставки контента), что делает его модульным и многоразовым.

 CSS.paintWorklet.addModule("https://url/to/worklet/file.js");

После вызова Worklet его можно использовать внутри CSS с помощью функции paint . Эта функция принимает зарегистрированное имя ворклета в качестве первого входного аргумента, а каждый следующий за ним входной аргумент является настраиваемым аргументом, который может быть передан в ворклет (определено внутри inputArguments inputArguments ). С этого момента браузер определяет, когда вызывать Worklet и какие действия пользователя и значения пользовательских свойств CSS изменяются в ответ.

 .exampleElement { /* paintWorkletExample - name of the worklet blue - argument passed to a Worklet */ background-image: paint(paintWorketExample, blue); }

Пример

В следующем примере демонстрируется API Paint и общая возможность повторного использования и модульность Worklet. Он использует ripple Worklet непосредственно из репозитория Google Chrome Labs и работает с другим элементом с другими стилями. Полный исходный код доступен в репозитории примера.

Пример волнового эффекта (используется Ripple Worklet от Google Chrome Labs) (большой предварительный просмотр)

Обнаружение функций

 if ("paintWorklet" in CSS) { /* ... */ } @supports(background:paint(paintWorketExample)){ /* ... */ }

Статус спецификации W3C

  • Рекомендация кандидата: стабильный рабочий проект, готовый к внедрению

Поддержка браузера

Гугл Хром Microsoft Edge Опера Браузер Fire Fox Сафари
Поддерживается Поддерживается Поддерживается Не поддерживается Не поддерживается

Источник данных: Houdini уже готов?

API анимации

Animation API расширяет возможности веб-анимации, позволяя прослушивать различные события (прокрутка, наведение курсора, щелчок и т. д.) и повышает производительность за счет запуска анимации в отдельном выделенном потоке с использованием Animation Worklet. Это позволяет пользователю управлять потоком анимации, которая работает производительно и не блокируется.

Как и любой ворклет, анимационный ворклет необходимо сначала зарегистрировать.

 registerAnimator("animationWorkletExample", class { constructor(options) { /* ... */ } animate(currentTime, effect) { /* ... */ } });

Этот класс состоит из двух функций:

  • constructor : вызывается при создании нового экземпляра. Используется для общей настройки.
  • animate : основная функция, содержащая логику анимации. Предоставляет следующие входные аргументы:
    • currentTime : текущее значение времени из определенной временной шкалы
    • effect : набор эффектов, которые использует эта анимация.

После регистрации Animation Worklet его необходимо включить в основной файл JavaScript , определить анимацию (элемент, ключевые кадры, параметры) и создать экземпляр анимации с выбранной временной шкалой. Концепции временной шкалы и основы веб-анимации будут объяснены в следующем разделе.

 /* Include Animation Worklet */ await CSS.animationWorklet.addModule("path/to/worklet/file.js");; /* Select element that's going to be animated */ const elementExample = document.getElementById("elementExample"); /* Define animation (effect) */ const effectExample = new KeyframeEffect( elementExample, /* Selected element that's going to be animated */ [ /* ... */ ], /* Animation keyframes */ { /* ... */ }, /* Animation options - duration, delay, iterations, etc. */ ); /* Create new WorkletAnimation instance and run it */ new WorkletAnimation( "animationWorkletExample" /* Worklet name */ effectExample, /* Animation (effect) timeline */ document.timeline, /* Input timeline */ {}, /* Options passed to constructor */ ).play(); /* Play animation */

Отображение временной шкалы

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

Временная шкала эффекта из примера будет выглядеть так (с длительностью 4 секунды без задержки):

Временная шкала эффекта (длительность 4 с) Ключевой кадр
0 мс Первый ключевой кадр — начинается анимация
2000 мс Средний ключевой кадр — анимация в процессе
4000 мс Последний ключевой кадр — анимация завершается или сбрасывается до первого ключевого кадра.

Чтобы лучше понять effect.localTime , установив его значение на 3000 мс (с учетом задержки 1000 мс), результирующая анимация будет привязана к среднему ключевому кадру на временной шкале эффекта (задержка 1000 мс + 2000 мс для среднего ключевого кадра). Тот же эффект произойдет, если установить значение 7000 мс и 11000 мс, потому что анимация повторяется с интервалом 4000 мс (длительность анимации).

 animate(currentTime, effect) { effect.localTime = 3000; // 1000ms delay + 2000ms middle keyframe }

Анимация не происходит при наличии постоянного значения effect.localTime , потому что анимация заблокирована в определенном ключевом кадре. Чтобы правильно анимировать элемент, его effect.localTime должен быть динамическим. Требуется, чтобы значение было функцией, зависящей от входного аргумента currentTime или какой-либо другой переменной.

В следующем коде показано функциональное представление отображения 1:1 (линейная функция) временной шкалы для воздействия на местное время.

 animate(currentTime, effect) { effect.localTime = currentTime; // y = x linear function }
Временная шкала ( document.timeline ) Сопоставленный эффект местного времени Ключевой кадр
startTime + 0 мс (прошедшее время) startTime + 0 мс Первый
startTime + 1000 мс (прошедшее время) startTime + 1000 мс (задержка) + 0 мс Первый
startTime + 3000 мс (прошедшее время) startTime + 1000 мс (задержка) + 2000 мс Середина
startTime + 5000 мс (прошедшее время) startTime + 1000 мс (задержка) + 4000 мс В прошлом первый
startTime + 7000 мс (прошедшее время) startTime + 1000 мс (задержка) + 6000 мс Середина
startTime + 9000 мс (прошедшее время) startTime + 1000 мс (задержка) + 8000 мс В прошлом первый

Временная шкала не ограничена сопоставлением 1:1 с местным временем. Animation API позволяет разработчикам манипулировать отображением временной шкалы в функции animate , используя стандартные функции JavaScript для создания сложных временных шкал. Анимация также не должна вести себя одинаково на каждой итерации (если анимация повторяется).

Анимация не должна зависеть от временной шкалы документа, которая начинает отсчитывать миллисекунды только с момента загрузки. Действия пользователя, такие как события прокрутки, можно использовать в качестве временной шкалы для анимации с помощью объекта ScrollTimeline . Например, анимация может начаться, когда пользователь прокрутит до 200 пикселей, и может закончиться, когда пользователь прокрутит экран до 800 пикселей.

 const scrollTimelineExample = new ScrollTimeline({ scrollSource: scrollElement, /* DOM element whose scrolling action is being tracked */ orientation: "vertical", /* Scroll direction */ startScrollOffset: "200px", /* Beginning of the scroll timeline */ endScrollOffset: "800px", /* Ending of the scroll timeline */ timeRange: 1200, /* Time duration to be mapped to scroll values*/ fill: "forwards" /* Animation fill mode */ }); ...

Анимация будет автоматически адаптироваться к скорости прокрутки пользователя и останется плавной и отзывчивой. Поскольку Animation Worklets запускаются вне основного потока и подключены к механизму рендеринга браузера, анимация, зависящая от пользовательской прокрутки, может работать плавно и быть очень производительной.

Пример

В следующем примере показано, как реализовать нелинейную временную шкалу. Он использует модифицированную функцию Гаусса и применяет анимацию перемещения и вращения с той же временной шкалой. Полный исходный код доступен в репозитории примера.

Анимация, созданная с помощью Animation API, в котором используется модифицированное временное отображение функции Гаусса (большой предварительный просмотр)

Обнаружение функций

 if (CSS.animationWorklet) { /* ... */ }

Статус спецификации W3C

  • Первый общедоступный рабочий проект: готов для рассмотрения сообществом, возможно изменение спецификации

Поддержка браузера

Гугл Хром Microsoft Edge Опера Браузер Fire Fox Сафари
Частичная поддержка (*) Частичная поддержка (*) Частичная поддержка (*) Не поддерживается Не поддерживается

* поддерживается при включенном флаге «Экспериментальные возможности веб-платформы».

Источник данных: Houdini уже готов?

API макета

Layout API позволяет разработчикам расширить процесс рендеринга макета в браузере, определив новые режимы макета, которые можно использовать в свойстве display CSS. Layout API представляет новые концепции, очень сложен и предлагает множество вариантов для разработки пользовательских алгоритмов компоновки.

Как и в случае с другими ворклетами, ворклет компоновки необходимо сначала зарегистрировать и определить.

 registerLayout('exampleLayout', class { static get inputProperties() { return ['--exampleVariable']; } static get childrenInputProperties() { return ['--exampleChildVariable']; } static get layoutOptions() { return { childDisplay: 'normal', sizing: 'block-like' }; } intrinsicSizes(children, edges, styleMap) { /* ... */ } layout(children, edges, constraints, styleMap, breakToken) { /* ... */ } });

Регистр ворклета содержит следующие методы:

  • inputProperties :
    Массив пользовательских свойств CSS, которые Worklet будет отслеживать и которые принадлежат элементу Parent Layout, т. е. элементу, вызывающему этот макет. Этот массив представляет зависимости верстки макета.
  • childrenInputProperties :
    Массив пользовательских свойств CSS, которые Worklet будет отслеживать и которые принадлежат дочерним элементам родительского элемента макета, т. е. дочерним элементам элементов, задающих этот макет.
  • layoutOptions : определяет следующие свойства макета:
    • childDisplay : может иметь предопределенное значение block или normal . Определяет, будут ли поля отображаться как блоки или встроенные.
    • sizing : может иметь предопределенное значение block-like или manual . Он указывает браузеру либо предварительно вычислить размер, либо не производить его (если размер не задан явно) соответственно.
  • intrinsicSizes : определяет, как блок или его содержимое вписываются в контекст макета.
    • children : дочерние элементы родительского элемента макета, т.е. дочерние элементы элемента, вызывающего этот макет.
    • edges : Макет Края окна
    • styleMap : типизированные стили OM коробки
  • layout : основная функция, выполняющая макет.
    • children : дочерние элементы родительского элемента макета, т.е. дочерние элементы элемента, вызывающего этот макет.
    • edges : Макет Края окна
    • constraints : ограничения родительского макета
    • styleMap : типизированные стили OM коробки
    • breakToken : маркер прерывания, используемый для возобновления макета в случае разбиения на страницы или печати.

Как и в случае с Paint API, механизм рендеринга браузера определяет, когда вызывается Paint Worklet. Его нужно только добавить в HTML или основной файл JavaScript.

 CSS.layoutWorklet.addModule('path/to/worklet/file.js');

И, наконец, на него нужно ссылаться в файле CSS.

 .exampleElement { display: layout(exampleLayout); }

Как Layout API выполняет Layout

В предыдущем примере exampleLayout был определен с помощью Layout API.

 .exampleElement { display: layout(exampleLayout); }

Этот элемент называется родительским макетом , который окружен краями макета , состоящими из отступов, границ и полос прокрутки. Родительский макет состоит из дочерних элементов, которые называются текущими макетами . Текущие макеты — это фактические целевые элементы, макет которых можно настроить с помощью API макетов. Например, при использовании display: flex; на элементе его дочерние элементы перемещаются для формирования гибкого макета. Это похоже на то, что делается с Layout API.

Каждый текущий макет состоит из дочернего макета , который представляет собой алгоритм макета для LayoutChild (элемент, псевдоэлементы ::before и ::after ), а LayoutChild представляет собой поле, сгенерированное CSS, которое содержит только данные стиля (без данных макета). Элементы LayoutChild автоматически создаются механизмом рендеринга браузера на этапе создания стиля. Layout Child может генерировать фрагмент , который фактически выполняет действия по рендерингу макета.

Пример

Как и в примере с Paint API, этот пример импортирует Worklet макета каменной кладки непосредственно из репозитория Google Chrome Labs, но в этом примере он используется с содержимым изображения вместо текста. Полный исходный код доступен в репозитории примера.

Пример макета Masonry (используется Masonry Worklet от Google Chrome Labs (большой предварительный просмотр)

Обнаружение функций

 if (CSS.layoutWorklet) { /* ... */ }

Статус спецификации W3C

  • Первый общедоступный рабочий проект: готов для рассмотрения сообществом, возможно изменение спецификации

Поддержка браузера

Гугл Хром Microsoft Edge Опера Браузер Fire Fox Сафари
Частичная поддержка (*) Частичная поддержка (*) Частичная поддержка (*) Не поддерживается Не поддерживается

* поддерживается при включенном флаге «Экспериментальные возможности веб-платформы».

Источник данных: Houdini уже готов?

Houdini и прогрессивное улучшение

Несмотря на то, что CSS Houdini еще не имеет оптимальной поддержки браузеров, его можно использовать сегодня с учетом прогрессивного улучшения. Если вы не знакомы с прогрессивным улучшением, вам стоит ознакомиться с этой полезной статьей, в которой это очень хорошо объясняется. Если вы решите внедрить Houdini в свой проект сегодня, вам нужно помнить о нескольких вещах:

  • Используйте обнаружение функций, чтобы предотвратить ошибки.
    Каждый Houdini API и Worklet предлагает простой способ проверить, доступен ли он в браузере. Используйте обнаружение функций, чтобы применять улучшения Houdini только к браузерам, которые его поддерживают, и избежать ошибок.
  • Используйте его только для презентации и визуального улучшения.
    Пользователи, которые просматривают веб-сайт в браузере, который еще не поддерживает Houdini, должны иметь доступ к содержимому и основным функциям веб-сайта. Пользовательский опыт и представление контента не должны зависеть от функций Houdini и должны иметь надежный запасной вариант.
  • Используйте стандартный запасной вариант CSS.
    Например, обычные пользовательские свойства CSS можно использовать в качестве запасного варианта для стилей, определенных с помощью API пользовательских свойств и значений.

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

Заключение

API-интерфейсы Houdini, наконец, позволят разработчикам хранить код JavaScript, используемый для управления стилями и оформления, ближе к конвейеру рендеринга браузера, что приведет к повышению производительности и стабильности. Позволив разработчикам подключиться к процессу рендеринга в браузере, они смогут разрабатывать различные полифиллы CSS, которыми можно легко делиться, внедрять и, возможно, добавлять в саму спецификацию CSS. Houdini также сделает разработчиков и дизайнеров менее связанными ограничениями CSS при работе со стилями, макетами и анимацией, что приведет к новым восхитительным веб-приложениям.

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

Будет интересно посмотреть, что придумает сообщество разработчиков по мере того, как Houdini набирает обороты и улучшает поддержку браузеров. Вот несколько замечательных примеров экспериментов с Houdini API от сообщества:

  • CSS-эксперименты с Гудини
  • Интерактивное введение в CSS Houdini
  • Примеры Houdini от Google Chrome Labs

использованная литература

  • Черновики спецификаций W3C Houdini
  • State of Houdini (Саммит разработчиков Chrome 2018)
  • Animation Worklet от Houdini — Google Developers
  • Интерактивное введение в CSS Houdini