Back

Использование CSS `zoom` для масштабирования элементов интерфейса

Использование CSS `zoom` для масштабирования элементов интерфейса

Когда вам нужно масштабировать часть интерфейса — виджет, панель предварительного просмотра, встроенный компонент — у вас есть два основных инструмента: zoom и transform: scale(). Они выглядят похожими, но ведут себя совершенно по-разному. Выбор неправильного инструмента может сломать вашу вёрстку способами, которые сложно отладить.

Эта статья объясняет, как работает CSS-свойство zoom, когда его использовать и чем оно отличается от transform: scale().

Ключевые моменты

  • CSS-свойство zoom масштабирует элемент и его место в макете, заставляя окружающий контент перестраиваться вокруг нового размера.
  • transform: scale() — это чисто визуальное преобразование, которое изменяет внешний вид без влияния на поток документа.
  • zoom не анимируется. Для анимированного масштабирования используйте transform: scale().
  • Следите за кроссбраузерными особенностями: в Safari были баги, когда getBoundingClientRect() мог возвращать размеры до применения zoom.

Что на самом деле делает CSS-свойство zoom

Свойство zoom масштабирует элемент и участвует в формировании макета. Когда вы масштабируете элемент через zoom, окружающий контент перестраивается вокруг его нового масштабированного размера, точно так же, как если бы вы физически изменили размеры элемента.

.preview {
  zoom: 0.75; /* отображается в 75% размере, занимает 75% исходного пространства */
}

Вы можете использовать числовые значения или проценты:

  • zoom: 1 — нормальный размер (по умолчанию)
  • zoom: 1.5 — 150% от исходного размера
  • zoom: 0.5 — 50% от исходного размера
  • zoom: 150% — то же самое, что 1.5

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

CSS zoom против transform: scale() — ключевое различие

Именно здесь возникает большая часть путаницы.

transform: scale() — это визуальное преобразование. Оно изменяет внешний вид элемента, но оставляет его место в макете полностью неизменным. Div размером 120×120px, масштабированный до 2x, всё равно занимает 120×120px пространства в потоке документа. Другие элементы не перемещаются.

zoom — это масштабирование, влияющее на макет. Div размером 120×120px с zoom: 2 занимает 240×240px в потоке. Окружающие элементы перестраиваются вокруг него.

Поведениеzoomtransform: scale()
Влияет на поток макета✅ Да❌ Нет
Окружающие элементы перестраиваются✅ Да❌ Нет
Масштабирует от верхнего левого угла (по умолчанию)✅ Да❌ (масштабирует от центра по умолчанию)
Анимируется❌ Нет✅ Да

Поскольку zoom участвует в формировании макета, его нельзя анимировать. Если вам нужно анимированное масштабирование, используйте вместо этого transform: scale().

Когда использование CSS zoom для масштабирования интерфейса имеет смысл

Масштабирование интерфейса с помощью CSS zoom наиболее полезно, когда вы хотите, чтобы масштабированный элемент действительно занимал свой новый размер в макете:

Масштабированные превью или миниатюры. Если вы отображаете UI-компонент полного размера внутри маленькой карточки предварительного просмотра, zoom позволяет уменьшить всё поддерево, сохраняя при этом внутреннюю вёрстку нетронутой.

.thumbnail-preview {
  zoom: 0.3; /* отображает полный компонент в 30% размере */
  width: 400px; /* естественная ширина компонента */
}

Встроенные виджеты. Сторонние или легаси-виджеты с фиксированными внутренними размерами можно уменьшить без изменения их внутреннего CSS.

Административные панели. Масштабирование интерфейса с помощью CSS zoom может помочь уместить плотные информационные панели в ограниченные области без переписывания логики вёрстки.

Поддержка браузерами и известные особенности

CSS-свойство zoom теперь имеет широкую поддержку в браузерах на базе Chromium, Safari и современном Firefox (поддерживается с Firefox 126). Это больше не является особенностью только IE, и поддержка браузерами отслеживается на платформах вроде Web Platform Status.

Однако есть реальные несоответствия, о которых нужно знать:

  • getBoundingClientRect() в Safari исторически возвращал размеры до применения zoom, а не масштабированные размеры. Chrome и Firefox корректно сообщают обновлённый размер. Если ваш JavaScript зависит от размеров элемента после применения zoom, тщательно тестируйте в разных браузерах.
  • zoom не является заменой адаптивного дизайна. Он не адаптируется к изменениям viewport так, как это делают медиа-запросы или гибкие макеты. Используйте его для конкретных задач масштабирования, а не как систему вёрстки.
  • Вложенный zoom работает мультипликативно. Родитель с zoom: 0.5, содержащий потомка с zoom: 0.5, отобразит потомка в 25% от его исходного размера. Избегайте применения zoom на нескольких уровнях одного поддерева, если только вы явно не учитываете это умножение.

Заключение

CSS-свойство zoom — это узкоспециализированный инструмент: используйте его, когда вам нужно, чтобы элемент и его место в макете масштабировались вместе. Обращайтесь к transform: scale(), когда вам нужно визуальное масштабирование без влияния на поток документа или когда нужна анимация. Знайте о браузерных особенностях, связанных с getBoundingClientRect(), избегайте нестандартных ключевых значений и не анимируйте его. В рамках этих ограничений zoom чисто решает реальный класс задач масштабирования интерфейса.

Часто задаваемые вопросы

Да. Свойство zoom изначально было нестандартной функцией, введённой Internet Explorer, но с тех пор было включено в спецификацию CSS Viewport Module Level 1. Все основные браузеры теперь поддерживают его, включая Firefox начиная с версии 126. Его безопасно использовать в продакшене, хотя вам всё равно следует тестировать кроссбраузерное поведение для граничных случаев.

Можно, но результаты могут быть запутанными. Свойство zoom сначала масштабирует элемент и его место в макете, затем transform scale применяет чисто визуальное преобразование поверх этого. Два эффекта визуально умножаются, но только zoom влияет на поток документа. Их комбинирование редко необходимо и усложняет отладку, поэтому используйте что-то одно, если у вас нет чёткой причины.

Нет. Свойство zoom не изменяет ширину viewport и не запускает точки останова медиа-запросов. Оно только масштабирует элемент и его потомков в существующем контексте макета. Если вам нужно, чтобы ваш интерфейс реагировал на разные размеры viewport, используйте медиа-запросы, контейнерные запросы или техники гибкой вёрстки вместо zoom.

Поведение может различаться между браузерами, особенно с элементами fixed-position. Поскольку zoom изменяет масштабирование макета, вычисления позиционирования могут работать не совсем одинаково в разных движках. Если ваше масштабированное поддерево содержит fixed или sticky элементы, тщательно тестируйте в разных браузерах.

Truly understand users experience

See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data. . Check our GitHub repo and join the thousands of developers in our community..

OpenReplay