Насколько гранулированы CSS-модули rem?
Я занимаюсь разработкой масштабируемого сайта, удобного для мобильных устройств и компьютеров, с использованием CSS rem единиц, основанных на среднем размере области просмотра сайта.
Для некоторых отступов и полей я установил размеры rem как 0,001rem, что нормально работает в моем браузере Firefox... но будет ли оно работать во всех современных браузерах?
Я только подвергаю сомнению способность использовать 0,001rem единицы, потому что самая высокая степень детализации, которую я видел до тысячных, это сотые доли непрозрачности... как opacity:0.25
например.
Как низко могут быть бэры? Является ли 0,00000001rem приемлемым значением в современных браузерах?
3 ответа
В конечном счете, ваша гранулярность составляет 1 физический пиксель (технически это субпиксель в современных браузерах, но я буду игнорировать это для целей данного обсуждения). Вы можете иметь разные рассчитанные значения пикселей на основе em
или же rem
даже до нескольких цифр точности. Затем вы сталкиваетесь с реальной проблемой, заключающейся в том, что при рендеринге эта десятичная точность будет потеряна, когда браузер в конечном итоге округлится, чтобы соответствовать пикселям, доступным при любой плотности пикселей устройства относительно плотности эталонных пикселей (96ppi).
По сути, этот опорный пиксель составляет 1/96 дюйма. Так 1px
в терминах CSS в основном означает 1/96"при 96ppi. На экранах с более высокой плотностью пикселей (скажем, как 326 ppi на многих экранах Apple " сетчатка ") происходит масштабирование для преобразования эталонного пикселя CSS в физические пиксели. Для упомянутого дисплея сетчатки, этот коэффициент масштабирования будет ~3.4. Поэтому, если вы задали правило CSS, чтобы задать что-то, скажем, 10px, браузер дисплея Retina должен отображать на 34 физических пикселях (при условии отсутствия других изменений HTML (то есть метаэлементов), которые изменили бы поведение отображения Из-за этого масштабирующего поведения физический размер элемента по-прежнему будет 10/96", что в точности соответствует физическому размеру, как если бы элемент отображался на экране 96ppi.
Теперь давайте добавим em
а также rem
к смеси. Итак, давайте рассмотрим пример размера шрифта корневого элемента 10px с объявлением для некоторого другого элемента .001rem
, Это означало бы, что вы пытаетесь визуализировать этот элемент с 0,01 (10px * .001rem) опорными пикселями, что на дисплее сетчатки будет равно 0,034 физическим пикселям. Вы можете ясно видеть, что rem
значение 0,001 составляет, по крайней мере, один порядок величины от существенного различия в физическом отображении, так как .01rem
в этом случае будет переводиться до 0,34 физических пикселей - нет разницы при округлении для отображения, чем для "более точного" .001rem
Спецификация.
Поэтому я думаю, что вы определяете CSS-правила на основе rem с гораздо большей специфичностью, чем это может быть принято в реальных условиях при рисовании физических пикселей, если только у вас не определен очень высокий размер корневого элемента и / или у вас нет физического экран с плотностью пикселей на порядок больше, чем у вас на дисплее сетчатки. Я предполагаю, что этот последний случай не соответствует действительности.
То, что CSS может быть вычислен с точностью до 3 десятичных знаков или что-то еще, это не означает, что физический рендеринг может происходить с таким же уровнем точности.
Простой пример на JSBin показывает, что высота 1.001 rem
оказывает 18.0156 px
в то время как высота 1.0001 rem
оказывает 18 px
(что было бы так же, как использование просто 1 rem
).
Это означает, что вы можете иметь точность до 3 десятичных знаков (по крайней мере, в настольной версии Chrome и с обычным размером шрифта).
Я также пытался написать тест JavaScript для измерения точности, но element.offsetHeight
это целое число, так что это бесполезно для этого вопроса. Если нет другого способа измерения размеров элемента в пикселях (с десятичными разрядами).
РЕДАКТИРОВАТЬ 1: В соответствии со спецификацией CSS (см. Это и это), кажется, нет никаких ограничений в отношении количества десятичных знаков.
Но, в конце концов, я думаю, что вы ограничены плотностью пикселей устройства. Физические пиксели на экране являются неделимыми, и поэтому все вычисленные размеры округляются до ближайшего целого числа.
"Теоретически CSS поддерживает бесконечную точность и бесконечные диапазоны для всех типов значений; однако в реальности реализации имеют ограниченную емкость. UA должны поддерживать достаточно полезные диапазоны и точности". w3.org
На практике, однако, мой вывод таков: в Chrome вы можете достичь тысячной доли с неограниченной точностью, пока дробная часть значения пикселя не упадет ниже 0,015.
РЕДАКТИРОВАТЬ: Исходное заключение было признано ошибочным, как только размер шрифта был увеличен до большего числа.
Попробуйте сами (я использовал Element.getBoundingClientRect()
):
var l = [
"normal",
"tens",
"hundreds",
"thousands",
"ten-thousands",
"hundred-thousands"
];
var o = document.getElementById("output");
for (var i = 0; i < l.length; i++) {
o.innerHTML += l[i] + ": " + document.getElementById(l[i]).getBoundingClientRect().height + "px<br>";
}
body,
html {
font-size: 1000px;
}
#normal {
height: 1rem;
}
#tens {
height: 1.1rem;
}
#hundreds {
height: 1.01rem;
}
#thousands {
height: 1.001rem;
}
#ten-thousands {
height: 1.0001rem;
}
#hundred-thousands {
height: 1.00001rem;
}
#output {
font-size: 16px;
}
<div id="output"></div>
<br>
<div id="normal">Hello</div>
<div id="tens">Hello</div>
<div id="hundreds">Hello</div>
<div id="thousands">Hello</div>
<div id="ten-thousands">Hello</div>
<div id="hundred-thousands">Hello</div>
Мой вывод был:
normal: 1000px
tens: 1100px
hundreds: 1010px
thousands: 1001px
ten-thousands: 1000.09375px
hundred-thousands: 1000px
Указывая, что десятитысячные места ( 0.00001
) выше точности, которую поддерживает мой браузер.
После дальнейшего увеличения размера шрифта и игры с ним я не могу найти значение, которое даст значение пикселя с дробной частью < 0,015. (Попробуйте установить font-size: 1556px
а также 1557px
)