Использование 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 в потоке. Окружающие элементы перестраиваются вокруг него.
| Поведение | zoom | transform: scale() |
|---|---|---|
| Влияет на поток макета | ✅ Да | ❌ Нет |
| Окружающие элементы перестраиваются | ✅ Да | ❌ Нет |
| Масштабирует от верхнего левого угла (по умолчанию) | ✅ Да | ❌ (масштабирует от центра по умолчанию) |
| Анимируется | ❌ Нет | ✅ Да |
Поскольку zoom участвует в формировании макета, его нельзя анимировать. Если вам нужно анимированное масштабирование, используйте вместо этого transform: scale().
Discover how at OpenReplay.com.
Когда использование 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..