Функция getDimensions в экосистеме Floating UI отвечает
за получение геометрических характеристик элемента: его ширины и высоты.
Это базовый слой вычислений, на котором строятся более сложные механизмы
позиционирования, такие как определение координат, выравнивание и работа
middleware.
В отличие от прямого использования DOM API (offsetWidth,
clientWidth, getBoundingClientRect),
getDimensions предоставляет унифицированный и предсказуемый
способ извлечения размеров независимо от типа платформы (DOM, React
Native, кастомные адаптеры).
getDimensions применяется внутри платформенного адаптера
(platform), который передаётся в
computePosition. Floating UI устроен так, что вся работа с
окружением (DOM или любая другая среда) абстрагирована через интерфейс
платформы.
Пример контекста:
computePosition(reference, floating, {
platform: {
getDimensions(element) {
// реализация
}
}
});
В браузерной версии библиотека уже содержит реализацию по умолчанию, однако понимание её устройства важно для:
type Dimensions = {
width: number;
height: number;
};
function getDimensions(element: Element | VirtualElement): Dimensions;
Функция принимает:
Возвращает:
width и
heightСтандартная реализация в браузере выглядит предельно просто:
function getDimensions(element) {
return {
width: element.offsetWidth,
height: element.offsetHeight
};
}
Однако в реальности используются более точные методы, учитывающие особенности рендеринга.
offsetWidth / offsetHeightclientWidth / clientHeightgetBoundingClientRect()transform)getBoundingClientRectНесмотря на точность, getBoundingClientRect имеет
особенности:
В задачах позиционирования иногда требуется именно “layout size”, а не визуально трансформированный размер.
getBoundingClientRectБолее точная версия:
function getDimensions(element) {
const { width, height } = element.getBoundingClientRect();
return { width, height };
}
Такой подход используется, если:
Inline-элементы (span, a) могут давать
неожиданные результаты:
offsetWidth может быть равен 0Floating UI предполагает, что:
Floating UI поддерживает виртуальные элементы — объекты, имитирующие DOM API.
Пример:
const virtualElement = {
getBoundingClientRect() {
return {
width: 100,
height: 50,
x: 0,
y: 0,
top: 0,
left: 0,
right: 100,
bottom: 50
};
}
};
В этом случае getDimensions реализуется так:
function getDimensions(element) {
const rect = element.getBoundingClientRect();
return {
width: rect.width,
height: rect.height
};
}
getDimensions используется совместно с:
getElementRects — получение прямоугольников reference и
floatinggetClippingRect — определение области отсеченияgetOffsetParent — вычисление контекста
позиционированияРазмеры элемента напрямую влияют на:
offset)shift и fliparrow)Свойство CSS box-sizing влияет на интерпретацию
размеров:
content-box — ширина не включает padding и borderborder-box — ширина включает всёgetDimensions должен учитывать, что:
offsetWidth всегда возвращает border-boxgetBoundingClientRect тоже соответствует
border-boxCSS-свойства:
transform: scale(1.5);
transform: rotate(45deg);
влияют на результат getBoundingClientRect, но не
влияют на offsetWidth.
Это означает:
Частые вызовы getDimensions могут вызывать:
Оптимизации:
Пример кэширования:
let cached;
function getDimensions(element) {
if (!cached) {
cached = {
width: element.offsetWidth,
height: element.offsetHeight
};
}
return cached;
}
Если элемент:
display: none;
то:
offsetWidth = 0getBoundingClientRect() возвращает нулиFloating UI не может корректно позиционировать такие элементы.
Решение:
visibility: hiddenSVG-элементы:
offsetWidthgetBBox() или
getBoundingClientRect()Пример:
function getDimensions(element) {
if (element instanceof SVGElement) {
const rect = element.getBoundingClientRect();
return { width: rect.width, height: rect.height };
}
return {
width: element.offsetWidth,
height: element.offsetHeight
};
}
При использовании:
zoom: 2;
или системного масштабирования:
getBoundingClientRect учитывает масштабoffsetWidth — нетЭто важно при:
offsetWidth округляет значенияgetBoundingClientRect возвращает floatFloating UI предпочитает точность, особенно при:
Комбинированная реализация:
function getDimensions(element) {
const rect = element.getBoundingClientRect();
return {
width: rect.width || element.offsetWidth,
height: rect.height || element.offsetHeight
};
}
Преимущества:
В нестандартных окружениях (Canvas, WebGL, Native):
function getDimensions(element) {
return {
width: element.width,
height: element.height
};
}
Главное требование:
Элемент не в DOM
Анимации
Flex и Grid
Scrollbars
getDimensions напрямую влияет на:
placement: center)flipshiftОшибки в размерах приводят к:
Для корректной работы Floating UI достаточно:
function getDimensions(element) {
return {
width: Number,
height: Number
};
}
Требования:
Внутри computePosition:
getDimensions участвует на первом этапе, задавая основу
всех последующих вычислений.