Задать вопрос
@PendalF89

Как переопределить rem для Shadow DOM?

Пишу расширение для браузера Chrome. Во Vuetify (PrimeVue, MUI, почти в любой UI-библиотеке) размер шрифтов компонентов определяется в rem. При подключении библиотеки в shadow dom элемент, rem, заданный в html внутри shadow dom игнорируется и берётся rem из корневого html элемента. Из-за этого, на разных сайтах размер шрифта тоже разный, в зависимость от font-size в корневом html элементе. Как лучше всего решить эту проблему - пытаться переопределять стили в UI-библиотеке? Или есть ещё какой-то способ заставить UI библиотеку использовать rem, определённый в shadow dom, а не в html?
  • Вопрос задан
  • 86 просмотров
Подписаться 1 Средний Комментировать
Решения вопроса 1
@PendalF89 Автор вопроса
Не знаю, насколько это решение правильное, но вдохновившись этим решением, я написал аналогичный плагин для Vite для замены rem на em во всём CSS во Vuetify.
import { type Plugin } from "vite";
import postcss, { Root } from "postcss";

/**
 * @see https://github.com/vuetifyjs/vuetify/issues/12532#issuecomment-2755171940
 */
export default function vuetifyRemToEmPlugin(): Plugin {
  return {
    name: "vite-vuetify-rem-to-em",
    transform(css: string, id: string) {

      // Обрабатываем только файлы, связанные с Vuetify
      if (!id.includes("vuetify") || !id.includes(".css")) {
        return;
      }

      return postcss([
        (root: Root) => {
          root.walkDecls((decl) => {
            if (decl.value.includes("rem")) {
              decl.value = convertRemToEm(decl.value);
            }
          });
        },
      ])
        .process(css, { from: id })
        .then((result) => {
          return {
            code: result.css,
          };
        });
    },
  };
}

function convertRemToEm(value: string): string {
  return value.replace(/(\d*\.?\d+)rem/g, (match, p1) => {
    return `${parseFloat(p1).toFixed(4)}em`;
  });
}


Подключаем плагин к Vite
...
plugins: [
      vuetify(),
      vuetifyRemToEmPlugin()
    ],
...


Теперь можно задать стили глобально в shadow DOM и em будет подхватываться:

html, body, :host, :root {
    font-family: Roboto, sans-serif;
    font-size: 16px;
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы