Почему к примеру на Firefox не работает zoom, и работает moz-transform: scale - криво? Zoom масштабирует целиком, если использовать в html, body, на весь экран... transform: scale - если уменьшаем, то уменьшает и оставляет черные полосы по бокам и сверху, как-бы экран в экране получается. Есть альтернатива зуму для Лисы?
Пример: Браузер Лиса со scale:
Пример: Браузер Хром с zomm:
Видите разницу?
Приниципиальное отличие transform
от zoom
в том, что zoom
меняет реальный размер элемента, и это сказывается на положении соседних элементов и на всём размере страницы. transform
же — чисто декоративная штука, она визуально меняет элемент, но в плане расчёта геометрии размеры элемента остаются стандартными и никак не влияют на основную страницу. В примере ниже можно наглядно увидеть разницу между transform: scale
и zoom
(запускать нужно в браузере Chrome, так как Firefox на момент написания данного ответа не поддерживает zoom
):
.ramka {
display: inline-block;
vertical-align: top;
border: 1px solid black;
margin: 0 20px;
font-family: Arial, sans-serif;
font-size: 10px;
}
.demo-transform {
transform: scale(1.4);
transform-origin: left top;
}
.demo-zoom {
zoom: 1.4;
}
.img {
vertical-align: top;
}
<div class="ramka">
transform: scale(1.4)<br/>
<div class="demo-transform">
<img class="img" src="https://i.stack.imgur.com/NyEgY.png" alt="" width="100" height="100" />
</div>
</div>
<div class="ramka">
zoom: 1.4<br/>
<div class="demo-zoom">
<img class="img" src="https://i.stack.imgur.com/NyEgY.png" alt="" width="100" height="100" />
</div>
</div>
Так как transform использует исходные размеры элемента и просто масштабирует изображение, то при применении ко всей странице ширина не пересчитывается, и, как вы показали в своём скриншоте, по краям образуется пустота.
Уменьшившуюся ширину можно исправить с помощью transform-origin: left top
и width: calc(1 / 0.6)
(где 0.6
это величина scale), однако это не решит проблемы с высотой, потому что она, в отличие от ширины, заранее не известна. При scale<1 снизу будет пустота, а при scale>1 низ страницы наоборот обрежется. А всё потому что transform не меняет геометрию.
К сожалению, стандартного кроссбраузерного аналога zoom
я не знаю (есть какой-то @viewport zoom, но с его поддержкой всё ещё хуже, и заставить его работать я не смог).
Один из вариантов, как с этим жить, вы описали сами: использовать transform
для Firefox и zoom
для остальных браузеров. Судя по тому, как сильно вы «любите» Лису, этот вариант вас вполне устроит :) Но о том, что zoom
нестандартный и может быть в любой момент удалён из браузеров, я вас уже предупреждал. (Хотя было бы прекрасно, если бы его стандартизировали и реализовали в Firefox, но это дело далёкого будущего.)
Но можно в принципе пересчитывать всю геометрию самостоятельно с помощью JavaScript. Ниже я написал функцию, которая пересчитывает height
для всех элементов с классом js-zoomed
(при этом width
прописывается в CSS). Вы можете добавить класс js-zoomed
к элементу <html>
на своём сайте, чтобы пересчитывать размеры всего сайта.
Проблемное ограничение данного способа в том, что этот скрипт нужно перезапускать при КАЖДОМ изменении размеров элементов. В примере я повесил перезапуск на браузерное событие resize
(оно приводит к изменению размеров почти всегда), но если вы динамически меняете какие-то элементы какими-то скриптами, то вам надо перезапускать это вручную в коде.
Ну а ещё это просто дикий костыль с кучей ограничений. Например, у увеличеннного элемента есть торчащая вниз невидимая пустота (она образуется из-за того, height
и transform
действуют вместе), и эта пустота добавляет ненужную полосу прокрутки, так что пришлось исправить это с помощью overflow: hidden
.
function recalcZoomedElements() {
var elems = document.getElementsByClassName('js-zoomed');
// Обрабатываем элементы в обратном порядке, чтобы
// не было проблем с вложенными друг в друга элементами
for (var i = elems.length - 1; i >= 0; i--) {
var elem = elems[i];
// Убираем старый расчёт height
elem.style.height = '';
// Браузер посчитает высоту автоматически с учётом transform;
// забираем её значение себе
var rect = elem.getBoundingClientRect();
var newHeight = rect.height;
// Ставим посчитанную браузером высоту, изменяя геомертию
elem.style.height = newHeight + 'px';
}
}
// Перерасчёт при первой загрузке страницы
recalcZoomedElements();
// Перерасчёт при каждом изменении размера окна браузера
window.addEventListener('resize', function() {recalcZoomedElements()});
.ramka {
display: inline-block;
vertical-align: top;
border: 1px solid black;
margin: 0 10px;
font-family: Arial, sans-serif;
font-size: 10px;
/* Вот так имитируем окно браузера для данного примера: */
/* его ширина заране известна и за пределы окна ничего не вылезает */
width: 140px;
overflow: hidden;
}
.demo-transform {
transform: scale(1.4);
width: calc(100% / 1.4);
transform-origin: left top;
}
.demo-zoom {
zoom: 1.4;
}
.img {
vertical-align: top;
}
<div class="ramka">
transform: scale(1.4) no js<br/>
<div class="demo-transform">
<img class="img" src="https://i.stack.imgur.com/NyEgY.png" alt="" width="100" height="100" />
</div>
</div>
<div class="ramka">
transform: scale(1.4) with js<br/>
<div class="demo-transform js-zoomed">
<img class="img" src="https://i.stack.imgur.com/NyEgY.png" alt="" width="100" height="100" />
</div>
</div>
<div class="ramka">
zoom: 1.4<br/>
<div class="demo-zoom">
<img class="img" src="https://i.stack.imgur.com/NyEgY.png" alt="" width="100" height="100" />
</div>
</div>
Почему бы не использовать transform: scale()
?
.zoom {
display: block;
width: 100px;
height: 100px;
}
.zoom img {
width: 100%;
height: 100%;
}
.zoom:hover {
-webkit-transform: scale(2);
-moz-transform: scale(2);
-ms-transform: scale(2);
-o-transform: scale(2);
transform: scale(2);
}
<div class="zoom">
<img src="https://upload.wikimedia.org/wikipedia/commons/1/16/Firefox_Developer_Edition_logo.png">
</div>
Вот рабочее решение:
@media (max-width: 1680px) and (min-width: 1601px) {
html {
zoom: 87.5%;
}
@-moz-document url-prefix() {
html {
transform: scale(0.875);
transform-origin: left top;
width: calc(100% / 0.875);
height: calc(100% / 0.875);
}
}
}
На всякий случай немного объясню:
@media (max-width: 1680px) and (min-width: 1601px)
Промежуток в котором будет работать код исходя из ширины экрана.
Zoom - для современных браузеров, оставляем, ниже прописываем конкретно для Мозилы/Огненной Лисы (только они воспримут код):
@-moz-document url-prefix() {....}
У меня работает.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Что значит @ в этом контексте кода? Не могу врубитсяСкрин ниже
Как определить время конца сегодняшних сутокЕсли сейчас дата например: