Использование CSS `zoom` для масштабирования элементов интерфейса
Сравнение CSS zoom и transform scale по влиянию на поток, поддержке браузерами и сценариям масштабирования UI для выбора подходящего инструмента.
Когда вам нужно масштабировать часть интерфейса — виджет, панель предварительного просмотра, встроенный компонент — у вас есть два основных инструмента: 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 чисто решает реальный класс задач масштабирования интерфейса.
Часто задаваемые вопросы
Является ли CSS zoom частью официальной спецификации?
Да. Свойство zoom изначально было нестандартной функцией, введённой Internet Explorer, но с тех пор было включено в спецификацию CSS Viewport Module Level 1. Все основные браузеры теперь поддерживают его, включая Firefox начиная с версии 126. Его безопасно использовать в продакшене, хотя вам всё равно следует тестировать кроссбраузерное поведение для граничных случаев.
Можно ли использовать CSS zoom и transform scale вместе на одном элементе?
Можно, но результаты могут быть запутанными. Свойство zoom сначала масштабирует элемент и его место в макете, затем transform scale применяет чисто визуальное преобразование поверх этого. Два эффекта визуально умножаются, но только zoom влияет на поток документа. Их комбинирование редко необходимо и усложняет отладку, поэтому используйте что-то одно, если у вас нет чёткой причины.
Влияет ли CSS zoom на медиа-запросы или точки останова?
Нет. Свойство zoom не изменяет ширину viewport и не запускает точки останова медиа-запросов. Оно только масштабирует элемент и его потомков в существующем контексте макета. Если вам нужно, чтобы ваш интерфейс реагировал на разные размеры viewport, используйте медиа-запросы, контейнерные запросы или техники гибкой вёрстки вместо zoom.
Как CSS zoom взаимодействует с элементами с fixed-position или sticky внутри масштабированного контейнера?
Поведение может различаться между браузерами, особенно с элементами 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.
Star on GitHub12k