CSS-live.ru

Новые и старые единицы измерения (краткий обзор)

Про единицы измерения в CSS сказано уже прилично. Статей на эту тему в интернете можно найти довольно таки много. Но, всё не стоит на месте, появляются новые элементы, свойства, но, так же, и, единицы измерения длины, которые тоже потихонечку пополняют новые стандарты.

В этой статье, я бы хотел затронуть часть, уже устоявшихся единиц измерения, обсудить их положительные и отрицательные стороны, а так же мне бы хотелось сделать краткий обзор совершенно новых единиц, которые пришли в веб совсем недавно.

Пиксели — абсолютная единица

В относительно новой статье на Хабре сказано, что px — это относительная единица длины, но, на самом деле это уже не так. С недавних пор пиксели считаются абсолютной единицей, и тому свидетельствует небольшая история.

В CSS1 px пиксель сделали относительным, потому что он считался реальным пикселем устройства. Ведь, по сути, устройства разные. В каком нибудь лазерном принтере пиксель — это один микрон, а например, на уличном экране, пиксель уже равняется пару сантиметрам. В общем px был относительно DPI устройства вывода. В CSS2.x поняли, что поторопились, и стали вводить понятие "логического пикселя" в зависимости от угла зрения. Пиксель определили как 1/96 дюйма при рассмотрении с расстояния вытянутой руки, а потом вообще плюнули и решили, что как его ни рассматривай, по сути-то он именно 1/96 дюйма и есть, и все браузеры именно так его и отображают и, не мудрствуя лукаво, зафиксировали соотношение 1px = 0.75pt = 1/16pc = 1/96in тем самым пиксель стал полноправной абсолютной единицей, как всегда и воспринимался интуитивно.

При этом физический пиксель может не соответствовать CSSному. На том же четвёртом айфоне физических пикселей 960, а CSS-ных — 480, как у предыдущих айфонов каждый CSSный пиксель картинки рисуется четырьмя физическими. Разработчики браузеров предложили такое расширение CSS media queries (пока нестандартное), как device-pixel-ratio, которая показывает соотношение реальных пикселей девайса с условными CSS-ными. В зависимости от этих показателей можно менять стили, или грузить картинки разной чёткости. Например, для старых айфонов мы можем грузить фон, скажем, 480 на 320 (грубо, но быстро), а для новых — размеров все 960 на 640 и масштабировать фон через background-size до 480 CSS-ных пикселей, по идее, на экране будут играть все пиксели картинки.

Кстати, у новых айпадов и макбуков с пикселами будет та же история, что и у айфона 4. Так же для девайсов высокого разрешения, типа принтеров, рекомендуется точно выдерживать абсолютные единицы (те же дюймы и сантиметры) и пиксели выводить из этой пропорции, так что на CSSный пиксель может приходиться даже дробное число физических. 
А для девайсов низкого разрешения типа экранов и для девайсов "рассматриваемых с нестандартного расстояния" рекомендуется привязывать CSS-ные пиксели к ближайшему подходящему целому числу пикселей девайса. На большинстве экранов – 1:1, на новых айфонах с айпадами и будущих макбуках – 2:1 (4:1 по площади)

pt

pt — это довольно таки старинная единица измерения, которая уже не один десяток лет используется для печати, в наборных машинках и во всякого рода программах для набора текста. 

Считается, что с pt можно достигнуть наилучшего, кросс-платформенного и кросс-браузерного результата при печати документа. Многие известные авторы CSS книг, да и не только, настоятельно рекомендуют использовать пункты (pt) строго для печати! Хотя на моей памяти, есть несколько, действительно опытных веб-мастеров, которые всю свою сознательную жизнь использовали в своих проектах пункты, и отнюдь не для печати. Но, сделав выбор в пользу этих единиц измерения, они руководствовались тем, что pt, по сути, считается самой универсальной длиной. Например, IE6 отлично масштабирует пункты, в отличии от пикселей, которые остаются неизменными в этом браузере.

В остальном пункты ведут себя практически так же. Единственное, что в них плохо, это неудобство, которое включает в себя коэффициент пересчёта. 1px = 0.75pt и это всегда нужно учитывать, при пересчёте шрифта, ширины и прочих вещей. В связи с последним, пожалуй самой простой и удобной единицей измерения всё же остаются пиксели (px).

%

Проценты (%) — это уникальная единица измерения. Эта относительная единица работает так же, как и слышится. Т.е, если, например, у родительского элемента установлен размер шрифта 24px, то выставив у дочернего элемента размер шрифта в 50%, последний будет меньше первого ровно в два раза, и будет составлять 12px.

По сути, ничего сложного. Следует помнить, что у процентов есть ряд особенностей. Например, в отличии от em, размеры отступов, ширины и т.д, у процентов высчитывается относительно ширины родительского элемента, а не относительно его шрифта. В связи с чем не получится указать размер шрифта и отступов в одних и тех же единицах.

font-size: .5em; margin: .5em vs. font-size: 50%; margin: 50%

Т.е, если, например, в последнем случае хочется, чтобы отступ был равен межстрочному интервалу, то из процентной величины шрифта напрямую его не взять. Всё равно придётся прибегать к (r)em-ам или абсолютным единицам.

Ещё один из важных моментах в жизни процента, это пример, когда задав вертикальные отступы у элемента в %, многие начинающие верстальщики (да, и не только), полагают, что высчитываться они будут относительно высоты родительского элемента. Но, на самом деле это не так. На этом примере видно, что при изменении высоты, отступы у параграфа остаются неизменными, что нельзя сказать про результат во время смены ширины контейнера. В этом случае вертикальные отступы начинают пропорционально изменяться, относительно ширины своего родительского элемента. Т.е, выходит, что вертикальные отступы реагируют на width предка, а не на его height. Это может показаться странным, но на самом деле всё вполне логично. Составляя эту часть спецификации, мудрые дядьки из W3C исходили из того, что, если, например, верхнее или нижние отступы задать как процент от высоты родителя, это может привести к бесконечному циклу. Ведь в таком случае высота родителя постоянно бы увеличивалась, чтобы вместить вертикальные отступы, которые затем снова должны были бы увеличиться относительно новой высоты и т.д. Этот момент очень важен и о нём нужно помнить.

Но, самое, пожалуй, известное и полезное использование процентов, это ситуация, когда мы можем назначить корневому элементу body разумный размер шрифта, а затем использовать проценты для шрифта всех остальных элементов на сайте. Это позволяет изменять размер шрифта всего сайта в одном месте, т.е. у body. Пожалуй, это очень удобно.

em

Начнём с того, что em вычисляется относительно размера шрифта родительского элемента. Один em равен значению свойства font-size заданного шрифта. 
Всё это очень важно понимать, при таких ситуациях, как, например, вложенность нескольких элементов в друг друга. 

Рассмотрим небольшую ситуацию. Предположим, у нас есть элемент <div>, в который вложен <span>, в который в свою очередь вложен элемент <i>. Допустим у <div> задан размер шрифта в 20px, а у его дочернего <span>-а — 0.5em, а у самого вложенного (<i>), ну скажем — 1.5em

<div class="wrapper">
        Размер шрифта: 20px
	<span>
		Размер шрифта: 10px
		<i>Размер шрифта: 15px </i>
	</span>
</div>
.wrapper { font-size: 20px; }
.wrapper span { font-size: 0.5em; background: #FC9; }
.wrapper span i { font-size: 1.5em; background: yellow; }

А вот собственно и результат. Но давайте разбираться. Как я уже и говорил, em пляшет от установленного шрифта. И, так как у нашего контейнера размер шрифта составляет 20px, то у вложенного <span>-а один em будет равен так же 20px, а так как его значение шрифта равно 0.5em, то, переведя это в пиксели (20/(1/0.5)), мы получим ровно половину от 20, т.е. 10px. Ну, а далее всё по накатанной. Для элемента <i> один em уже будет равняться 10px (полученный в результате пересчёта размер шрифта его родителя). Ну, а раз у <i> стоит шрифт, размером в 1.5em, значит нам просто нужно к 10 прибавить ровно половину (10 + (10/2)), что в сумме даст 15px. В принципе не очень-то и сложная арифметика, единственное, что нужно, это учитывать эти вещи и не запутаться во время вёрстки. Вот, хоть и не актуальная, но хорошая статья на эту тему.

Да, и, как вы могли заметить, em легко принимает в качестве своих значений дробные числа. Этим они отличаются от других единиц, так как в связи с этой особенностью, с дико длинными дробями em-ы получают высокую точность. Но, стоит отметить, что, по наблюдениям моих коллег, браузер IE отбрасывает третий и последующий знаки после запятой для em-ов и позволяет писать всего лишь два знака после запятой. Примерно так — 1.23.

Ну, и конечно же, следует уточнить, что em-ы работают не только со шрифтами, но и с любыми другими размерами и свойствами, например, с теми же отступами, границами, ширинами и т.д. И высчитывают эти величины, так же, отталкиваясь от размера шрифта.

Кстати, до недавнего времени em-ы считались самими "модными" единицами измерения. Модными в плане болезни под названием "em", которой болели многие разработчики, в том числе и я. Симптомы этой болезни таковы, что веб-разработчик проставляет em-ы где только можно и нельзя. Тыкая их не только в размеры шрифта, но и в ширины, высоты, отступы и другие части элементов. Причём делая это неосознанно, а ради какого понта или моды. В связи с этим сайты, напичканные этими единицами измерения, при малейшем "ветре" начинают разваливаться, разнося контейнеры и блоки в пух и прах.

Чтобы наглядно продемонстрировать, как это происходит, я подготовил пару сайтов, которые когда-то верстал. Первый из них — это следствие болезни, а второй уже сделан с умом.

Первый пример — неправильное использование em

Попробуйте увеличить размер шрифта в настройках браузера и вы увидите, что произойдёт. Хотя на такое лучше не смотреть. Сайт полностью развалился, блоки разъехались в разные стороны. Находится на таком сайте невозможно, текст не читаем, информация невосприимчива, вокруг ужас. Соответственно с такого сайта хочется поскорее убежать.

Почему такое произошло? Всё очень просто, если взглянуть в код, то в нём отчётливо можно увидеть, что повсюду царит em. Эта единица измерения там выставлена всему живому, почти что всем элементам, начиная с самого главного контейнера и заканчивая каким нибудь малонужным span-ом. Причём в em прописан не только их размер шрифта, а как я уже говорил, ширина, высота, отступы, размеры, да и вообще всё что угодно.
Это одна из причин, вторая — это то, что графическое оформление (особенно фоновые картинки) привязано к пиксельной сетке и не может масштабироваться вслед за шрифтом (по крайней мере кроссбраузерно на сегодняшний день) В целом всё сделано бездумно, без оглядки на будущее. По хорошему нужно было бы сделать картинки с запасом, ограничить ширину главного контейнера, да и многих других элементов, в пикселях, а не в em-ах. Ведь, далеко не все вещи на сайте, строго обязаны масштабироваться. Масштабирование следует применять правильно и с умом.

Второй пример — правильное использование em

Во втором примере расклад совершенно иной. При "зверском" увеличении/уменьшении размера шрифта ничего не страдает, блоки масштабируются красиво, я бы сказал — правильно. Ничего ни разваливается, текст не вылезает за края родительских элементов, картинки масштабируются как нужно, подстраиваясь под размер шрифта. В целом на сайте приятно находится.

В чём же отличие? Отличие в том, что к моменту верстки этого сайта, я уже переболел em-ами, добрые люди спустили меня на землю, дав понять, что em-ы — это не панацея, и что, перед тем, как их применять, следует 100 раз отмерить, а только потом резать. Что и было сделано в этой работе. Перед тем, как верстать тот или иной блок, я старался проверять всевозможные варианты, размеры, вид этого блока, при разных разрешениях, размерах шрифта и экранах. Проставлял нужные em-ы только в те места, где благодаря им, при масштабировании картина в целом не портилась и сайт сохранял свой первоначальный вид.

Отсюда можно сделать вывод, что em — это полезная вещь, но только там, где она действительно необходима. Плюс, последнее время эта "техника" уже менее актуальна, чем раньше. Дело в том, что современные браузеры научились вполне отлично масштабировать весь документ. Если быть точным, то это называется "Полностраничное масштабирование документов", поэтому применение для этих целей таких единиц измерения, как em, отошло на задний план.

Вертикальный ритм

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

Как я уже и говорил, в своих значениях em позволяет указывать не только целые числа, но и дроби, например так — 1.23535em, а это прибавляет им огромную точность. В связи с этим, мы легко можем настраивать межстрочный интервал с помощью этих единиц. Есть разные сервисы по созданию таких вот интервалов, основанных на em-ах. Вот один из них. Там можно выбрать название шрифта, размер и выставить нужный интервал. Единственное, о чём нужно помнить, это то, что к каждой задаче нужны свои значения, шрифты, размеры и интервалы. Т.е. от этого сервиса можно лишь только начать плясать, а дальше уже допиливать вертикальный ритм под свои нужды.

rem

rem — новыя единица измерения, введённая спецификацией. Она означает примерно "Корневой em" (root em).

Давайте уточним, что это значит. Если em — это единица, которая пляшет относительно шрифта родительского элемента, то rem — это единица измерения, которая пляшет относительно корневого элемента, т.е, как вы уже догадались — html. Это означает, что мы можем определить единый размер шрифта в <html>, и отталкиваться уже от него, причём при любой вложенности.

html { font-size: 62.5%; }
body { font-size: 1.4rem; } /* =14px */
 h1 { font-size: 2.4rem; } /* =24px */

Здесь я определил базовый размер шрифта, чтобы было удобно использовать rem, отталкиваясь от 1rem = 10px. В остальном rem, по сути, представляет из себя точно такую же единицу измерения, что и em, с тем же функционалом и поведением.

А что же с поддержкой в браузерах?

Вы может быть будете удивлены, но поддержка вполне приличная. Safari 5, Chrome, Firefox 3.6 +, и даже Internet Explorer 9 имеют поддержку этих единиц. Приятной частью является то, что IE9 поддерживает изменение размера текста, который определяется с помощью rem. (Увы, бедная Opera (до 11.10, по крайней мере) не осуществила поддержку этих единиц. Но, в последней 11.60 всё отлично.

Что делать с теми браузерами, которые не поддерживают rem? Я бы предложил указывать их размеры в обычных и надёжных пикселях. Благо для IE6-8 есть условные комментарии, которые абсолютно законны и валидны.

vh и vw

rem — это не единственная новинка спецификации. Я бы хотел представить вам ещё несколько. vw и vh — единицы, которые отталкиваются от размеров области просмотра.

Давайте представим ситуацию. У нас на сайте присутствуют элементы, которые должны поместиться в область просмотра, причём, допустим, не полностью, а составлять 95% ширины и высоты окна. С помощью JavaScript мы могли бы высчитывать размеры окна, делать перерасчёт и подставлять эти данные в наш свойства нашего элемента. Но, это, во-первых, неудобно, постоянные перерасчёты при ресайзе окна, а во-вторых, само использование JavaScript для этих целей не самая лучшая затея. С помощью vw и vh мы можем вычислить размер элемента относительно области просмотра. Один vw равен 1/100 ширины всего экрана, а один vh соответственно 1/100 высоты. Для того, чтобы элемент занимал, например, всю ширину окна браузера, его ширине следует выставить 100vw.

Где бы это могло пригодится?

Ну, например, самое первое, что приходит на ум, это всплывающие попапы, типа Lightbox. Или, например, какие нибудь изображения в виде фона сайта, у которых должны быть определённые отступы от края окна.

А что с поддержкой браузеров?

Вот тут, к сожалению всё не так гладко, как нам хотелось бы. На данный момент, как это не удивительно, vw и vh поддерживает только лишь единственный браузер — Internet Explorer 9. Но, стоит надеется, что в ближайшем будущем этот удручающий факт начнёт меркнуть и мы с можем в полной мере насладиться этими единицами в любимых браузерах.

vm

Ну, здесь всё просто. vm — это точно такая же единица измерения, что и две предыдущие (vw, vh). Отличие только в том, что она отталкивается от самой короткой по длине стороны. Например, если, ширина экрана будет равна 500px, а высота 800px, то один vm будет равен 500/100, т.е. 5px. Поддержка в браузерах идентична предыдущим. Internet Explorer 9, единственный браузер, работающий с этой величиной, на данный день.

ch

Ну, и пожалуй последняя единица, которую я хотел бы рассмотреть в этой статье — это ch. 

ch – это относительная единица, но отталкивается она не совсем от размера шрифта, а если быть точным, то по спецификации:

Equal to the advance measure of the "0" (ZERO, U+0030) glyph found in the font used to render it.

Равна авансовой ширине литеры "0" (ноль, U+0030), найденной в шрифте, используемом для его (элемента) отображения

Почему именно "0"?
На самом деле "0" — это условный символ, на его месте может быть любая другая цифра. Т.к. цифры в уважающих себя шрифтах и должны быть одинаковыми в ширину (чаще всего все цифры в шрифте одной ширины, но слепо полагаться на это нельзя, лучше перепроверить).

Где поддерживается?
А вот здесь самое интересное. Дело в том, что на данный момент единицу ch поддерживают только два браузера: Firefox 10 и Internet Explorer 9, но делают они это совершенно по разному. Но прав, на мой взгляд, именно Firefox. И вот почему…

Откройте этот тестовый пример в IE9 и Ff10. Посмотрите разницу. Обратите внимание на верхний блок (с классом ".ref") и на следующий за ним, ширина которого равна 10chFf10 отображает второй блок, по идее, правильно, потому что его ширина точно совпадает с верхним блоком (где находятся одни нули), а вот в IE9 розовый блок явно меньше, что уже само по себе противоречет спецификации. По самому нижнему блоку можно увидеть, на сколько ошибается IE9. Я выставил блоку letter-spacing в значение .079em и только после этого последние блоки сравнялись. Причём шрифты monospace тут не приделах, я выставил sans-serif (Arial) и получил такую же картину

Скорее всего такое поведение IE9  обусловлено тем, что единица ch сейчас не востребована и IE видимо не уделил ей должного внимания. И поэтому она поломана в этом браузере. Но, есть надежда, что к релизу IE10 этот недочёт всё таки исправят.

Кстати, любой символ в моноширинных шрифтах будет ширины 1ch и этим можно пользоваться для разных прикольных эффектов. Возьмите это на заметку, думаю пригодится.

Резюме

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

Внимательно изучите каждую единицу в отдельности, и пробуйте применять их на практике. Удачи!
 

P.S. Это тоже может быть интересно:

58 комментариев

  1. Ой, недалеки времена, когда введут единицу измерения, равную ширине слова в третьей строчке пятого абзаца :) Столько требующих изменений модулей, а они единицы измерения новые придумывают.

    1. Ну вреда от новых единиц я точно не вижу :). Rem — просто прелесть, все плюсы em-ов без их главного недостатка, удобны во всяческой адаптивности (и работают во всём новом!). Vh и vw полезны для веб-интерфейсов, где элементы нередко должны занимать определенную часть экрана. У ch тоже навскидку просматривается куча полезных применений — форматирование столбцов чисел, поля форм, соответствующие максимальному кол-ву вводимых символов… да хоть просто прикольные эффекты типа http://lea.verou.me/2012/02/simpler-css-typing-animation-with-the-ch-unit/ :)

      Вот бы еще всё это великолепие поддерживалось повсеместно и единообразно (а не как та же ch в IE9)… Но это общая беда любых CSS-новинок, по-моему.

  2. Не мог понять, почему в первом примере, показывающем недостатки em ничего не плывет, сколько бы не нажимал ctrl+. Все-таки браузер по умолчанию масштабирует всю страницу целиком, а не только шрифт. А для масштабирования только шрифта нужно лезть в настройки (а есть ли у некоторых такая возможность, например в Opera?). Предупреждать надо ;)

  3. Часть про новые единицы измерений очень интересна!
    И вообще, в целом, хороший блог.
    Например статья про абсолютное позиционирование в таблицах тоже очень понравилась.

  4. Изврат, конечно. Пиксель — не пиксель, а пункт — не пункт. Хотя отношусь с пониманием, так как иначе всё выглядело бы нечитабельно мелким на высоких DPI из-за того, что разработчики не научились использовать пункты.

    Ну а какого было мое удивление, когда обнаружилось, что пункт привязан к пикселю! И это было совсем не так давно. Кстати, пиксель всё-таки не совсем абсолютная величина, так как если размер реального пикселя на экране не слишком разительно отличается от 1/96 дюйма, то логический пиксель будет равен физическому. Оно и понятно, так как в противном случае в появилась бы адовая интерполяция, которую на повышенных DPI еще можно понять-простить, но при плотности близкой к 1/96 — ни за что. И в этом как раз и состоит неадекватность пункта. Ведь на одном экране ширина элемента, назначенная в пункта, будет выглядеть другой на другом экране (из-за привязки к пикселю и различия в их размере). Однако пункт всё-таки не всегда привязан к пикселю. Например если использовать пункты в условиях Media Qeries, то там пункт уже совсем другой (вероятно, настоящий, типографский).

    1. Да, CSS-пиксель нельзя назвать «совсем абсолютным» в бытовом понимании (как точную копию некоего платинового эталона из парижской палаты), тут смысл в том, что на любом конкретном устройстве пиксели, пункты, миллиметры и дюймы связаны однозначно (и если искажаются — то все разом, одинаково). Насчет этой взаимопривязки в спеке есть отдельная ремарка (http://www.w3.org/TR/CSS21/syndata.html#x39):
      «Для поддерживающего CSS устройства эти меры связаны 1) посредством соотнесения физических единиц с их физическими размерами, либо 2) посредством соотнесения пикселя с «референсным пикселем». Для печати и подобных устройств с высоким разрешением, единицей привязки должна быть одна из стандартных физических единиц (дюймы, сантиметры и т.п.). Для устройств низкого разрешения и устройств с нетипичными расстояниями просмотра вместо этого рекомендуется привязка через пиксель. Для таких устройств рекомендуется, чтобы единичный пиксель относился к целому числу пикселей устройства, которое наболее приближено к «референсному пикселю» (т.е. 1/96 дюйма).»
      Так что с точки зрения спеки это не баг, а фича. Да и как быть иначе, если ОС просто не сообщает браузеру честного разрешения монитора?

      А вот насчет пунктов в Media Qeries, сорри, я не понял, нельзя ли пояснить (желательно примером)? Читал только про специфику мобильных браузеров (http://www.quirksmode.org/mobile/viewports2.html), но там вроде как раз пиксели «особенные»…

  5. Ну а теперь по статье.

    > Пиксель определили как 1/96 дюйма при рассмотрении с расстояния вытянутой руки

    Это как? Реальная величина 1 дюйма разве меняется в зависимости от расстояния, с которого на него смотришь? ;)

    Em-ы ты обругал вообще несправедливо (надеюсь, можно на «ты»?). Особенно в начальной редакции (статью прочитал 1—2 дня назад, но прокомментировать всё никак времени не было). Em — великолепная единица. Конечно, ее надо использовать с умом. Но это касается не только em. CSS вообще не терпит небрежности. По поводу первого примера — он вообще сверстан недальновидно, это касается далеко не только em. Вся раскладка «деревянная». Особенно удручает фиксированно заданные высоты.

    Кстати, я совсем не понял прелести того, что em такой сверхточный. Это попахивает попыткой подогнать строки к размеру чего-либо, что в корне неверно. Никогда нельзя верить тому, как отрисовались шрифты. Вдруг у пользователя не окажется нужной гарнитуры? Тогда она поменяется на другую, а у другой гарнитуры будет совсем другая ширина букв и высота строки (одинаковый кегль и интерлиньяж вовсе не гарантирует одинаковую высоту строки). Более того, у пользователя может оказаться другое количество строк текста, даже если ширина блока нерезиновая. Так что фиксированная высота элемента не оправдана никогда! Исключение будет, если разработчик задумал там скроллбар.

    1. > Реальная величина 1 дюйма разве меняется в зависимости от расстояния, с которого на него смотришь?
      Насколько я понял, CSS1 (и CSS2.x поначалу) пытались привязываться именно к угловому размеру, а не к линейному. И только потом, представив реальное кол-во граблей на этом пути, плюнули и сделали как проще (т.е. как сейчас) :)

      > Em-ы ты обругал вообще несправедливо
      А мне кажется — наоборот перехвалил :). Помню, как я по молодости пытался сверстать пиксель-в-перфект дизайн с базовым размером шрифта, кажется, 13 (в общем, простое число) пикселей, используя em-ы. Коэффициенты для пересчета оказывались совершенно неудобными, а IE7 не желал принимать третью и последующие цифры после запятой, тупо обрубая до двух. В итоге как раз вертикальный ритм мне выровнять так и не удалось — при самом удачном раскладе каждая десятая-одиннадцатая строчка оказывалась на пиксель выше, отчего строки в соседних колонках сползали друг относительно друга. Причем в разных браузерах слегка по-разному. Возможно, я тогда тупо не умел их готовить, но возился долго и безуспешно…

      1. А вот мне как раз наоборот, в итоге удалось заставить вертикальный ритм подчиняться, и получилось это благодаря именно ЕМ-ам. :)

    2. Em-ы ты обругал вообще несправедливо (надеюсь, можно на «ты»?). Особенно в начальной редакции (статью прочитал 1—2 дня назад, но прокомментировать всё никак времени не было). Em — великолепная единица. Конечно, ее надо использовать с умом. Но это касается не только em. CSS вообще не терпит небрежности. По поводу первого примера — он вообще сверстан недальновидно, это касается далеко не только em. Вся раскладка «деревянная». Особенно удручает фиксированно заданные высоты.

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

      Кстати, я совсем не понял прелести того, что em такой сверхточный. Это попахивает попыткой подогнать строки к размеру чего-либо, что в корне неверно. Никогда нельзя верить тому, как отрисовались шрифты. Вдруг у пользователя не окажется нужной гарнитуры? Тогда она поменяется на другую, а у другой гарнитуры будет совсем другая ширина букв и высота строки (одинаковый кегль и интерлиньяж вовсе не гарантирует одинаковую высоту строки). Более того, у пользователя может оказаться другое количество строк текста, даже если ширина блока нерезиновая. Так что фиксированная высота элемента не оправдана никогда! Исключение будет, если разработчик задумал там скроллбар.

      Я не спорю, всякое может быть, но, по крайней мере, как показывает практика, ЕМ-ы более точны при том-же вертикальном ритме, нежели другие единицы. Конечно же говоря про сегодняшний день.

      Ну может быть где-то перехвалил конечно, но совсем чуть-чуть :)

  6. Кстати, могу подсказать хорошую тему для будущей статьи — различие рендеринга элементов форм(инпутов и тд.) различными браузерами и методы борьбы с этим.
    Очень уж больная тема.

  7. Кстати вот, тоже был удивлён когда выяснилось что пиксель != физическому пикселю экрана. Но, вообще, удивлён не слишком, поскольку мне казалось что то, что я вижу на разных экранах как один пиксель — не так уж мало, и во-вторых, зная что у мобильного устройства разрешение full hd, меня удивляло, каким же образом, сайты открываются в явно адаптированном для маленьких разрешений варианте (и шрифты, при этом, не слишком маленькие, читаемые).
    И вот, теперь, всё более-менее встало на свои места. Большое Вам спасибо!

  8. Да, кстати, % и em, по видимому, не всегда совпадают и для vertical-align:

    https://jsfiddle.net/Launder/n817tfLv/1/

    в случае em, у шрифта берётся его численное значение, а в случае %, у шрифта берётся толи размер его кегельной площадки, толи «литерной» площадки, то ли некий line-height шрифта по-умолчанию, в общем как назвать не знаю, но зависит это от конкретного шрифта.

    1. Верно! Для vertical-align за 100% берется фактическое значение line-height. Если оно не задано, то берется значение по умолчанию из метрик шрифта — т.е., да, высота того, что браузер по умолчанию заливает фоном текста (сам не знаю, как грамотно это назвать: однозначно не «кегельная» площадка, потому что не равна кеглю, «литерная» — похоже, моя отсебятина и у нее мало смысла в цифровом наборе… наверное, лучше, чем просто «дефолтный line-height шрифта» не придумать:).

  9. Да, и ещё:

    «мудрые дядьки из W3C исходили из того, что, если, например, верхнее или нижние отступы задать как процент от высоты родителя, это может привести к бесконечному циклу» — мне кажется исходили они не обязательно из этого, а может быть из того, что в этом случае появляется возможность «за один проход» (мне кажется, CSS специально проектировалося так, чтоб рендеринг был, по возможности, «однопроходным»: прочитал — разрисовал, пошёл дальше), то есть, без использования скриптов, строить геометрические фигуры нужных пропорций. По-умолчанию, понятное дело, прямоугольники:

    https://jsfiddle.net/Launder/ycx2mo51/

    но их, как известно, можно по разному трансформировать.

    Что же касается бесконечного цикла, то тут есть пару моментов:
    Во-первых цикл будет сворачивающимся, то есть, каждую итерацию изменения будут меньше и меньше, и, при достижении определённого порога можно и остановится.
    Вот, смотрите сами:
    В Вашей же терминологии отступ это паддинг?
    Ну, если box-sizing: content-box, то вообще проблем, насколько я понимаю, не будет, скажем высота у нас 100 пикселей, а паддинг 40% от этой высоты, в этом случае при изменении паддинга высота не меняется, поскольку она паддинг не включает. Поэтому просто считаем паддинг и всё. Между прочим, это значение по-умолчанию, а значит по умолчанию, цикла не будет.
    Если же у нас значение box-sizing отличается от контент-бокс, то оно включает в себя и паддинги и сложности будут. Но, давайте посмотрим какие:

    Вот у нас высота 100 и паддинг 40%. По сути получается 100px + 40% = 100%. Получается, 100px в переводе на проценты это 60%. Один процент это 5/3, а
    100% это 500/3 = 100 + 200/3 = 100 + 198/3 + 2/3= 100 + 66 + 1.98/3 + 0.02/3,
    ну то есть, с 2/3 ситуация аналогичная 200/3, а поскольку у последнего целая часть равна 66, то далее следует 6 в периоде. Итого 100% это 166.(6), соответственно паддинг получается 166.(6) — 100 = 66.7 округляется до 67 пикселей.
    Итого для машины
    1. считаем скольким процентам равна известная нам высота.
    2. находим один процент.
    3. прибавляем нужное количество процентов.

    Если же считать итерациями, то получится тоже самое:
    К 100 прибавляем 40 (140) умножаем на 0.4 (получаем «текущие» 40% — 56)
    Получившийся результат снова прибавляем к 100 (156) и снова умножаем на 0.4 (62.4)
    Если посмотреть внимательно, то мы увидим, что, по сути, мы к 100 сначала прибавили 40 (0.4 от 100), затем прибавили 0.4 от 40 (16), потом 0.4 от 16 (6.4), потом 0.4 от 6.4 (2.56), то есть, мы от всё меньших частей находим 40% и прибавляем их к общему результату, и видя значение очередного члена, мы начинаем понимать к чему движется общая сумма.
    Буквально 6-8 итераций в нашем примере, выявят результат, а уж с точностью до пиксела, и того меньше.

    Поэтому, сомневаюсь, что стояла задача именно не допустить чтоб компьютер встал в тупик, вероятнее, разработчикам нужен был инструмент, позволивший им отдельно работать с размерами, а отдельно — с пропорциями, что даёт большую гибкость при вёрстке.

    1. А если у дочерних элементов проставлен марджинв % (который считается от высоты родителя), то получается следующая ситуация:
      1. Считается высота контента с учётом всех фиксированных составляющих, если они есть (высота/поля/отступы/границы).
      2. А дальше от получившейся величины, отстёгивается % нужным дочерним элементам
      3. от этого увеличивается высота

      Но и тут ситуация аналогичная предыдущей. Скажем у нас есть два марлжина один 4%, другой 3% значит оставшийся контент занимает 100% — (4% + 3%) = 93%. И с итерациями, последовательно умножаем каждый кусочек на 0.04 и 0.03 соответственно, получившийся марджин снова умножаем на тоже самое складываем и так далее, получаются сходящиеся ряды.
      Но в любом случае это, конечно, это лишние операции. Да и для верстальщика, наверное, не слишком удобно, поскольку нужно в голове держать сколько % расходуется, сколько осталось, если скажем у нас 5 марджинов по 5%, и три по 10%, получается контент считается как 100% — (5х5% + 3х10%) = 100% — 25% — 30% получается 45% считать высоту контента + все фиксированные составляющие. Можно так и в минус уйти ненароком, если, скажем у нас не 5 блоков будет, а 15 с 5% марджином.
      В общем, такая раскладка, возможно, даёт лишнюю работу и машине и верстальщику.

    2. мне кажется, CSS специально проектировалося так, чтоб рендеринг был, по возможности, «однопроходным»

      Не кажется, так и есть:) Именно из этой тонкости и «растут» многие раздражающие проблемы «на ровном месте» в CSS, типа вертикального центрирования при динамической высоте (если неизвестно, где блок кончится, то непонятно, где его начинать, чтобы сверху и снизу осталось поровну места) и неопределенности поведения таблиц.

      Вариант с «последовательным приближением», пока разница не станет невидимой, для веба не годится: физические пиксели всё мельчают, физические разрешения растут, а сложные раскладки бывают еще и глубоко вложенными, так что шагов понадобится не так уж мало. Если на каждом шаге перерисовывать интерфейс, он будет «дерганным», если отрисовывать только после финального шага — будут заметные лаги (особенно на мобильных устройствах, у которых разрешение ого-го, а видеокарты еле-еле:). Алгоритмы новых схем раскладки стараются строить так, чтоб можно было за один-два прохода всё отмерить и один раз отрисовать.

  10. Если на каждом шаге перерисовывать интерфейс, он будет «дерганным», если отрисовывать только после финального шага — будут заметные лаги

    Согласен с этим. Да и вероятность ошибок больше.

    Именно из этой тонкости и «растут» многие раздражающие проблемы «на ровном месте» в CSS, типа вертикального центрирования при динамической высоте

    Вот как раз сегодня почти весь день промедитировал над известной Вам темой:

    https://htmlforum.ru/topic/55893-margin-v/?sortby=date

    После того, как Вы объяснили как браузер строит раскладку в этом случае, возникло два основных вопроса:
    1. А можно ли в принципе сделать так, чтоб у резинового блока, отступы/поля были пропорциональны блоку.
    И, второй, возможно, возможно, чуть более компромиссный:
    2. Возможен ли двухколоночный макет где один блок (в нашем случае правый) широкий по содержимому, а другой блок (левый) занимает всё оставшееся пространство.

    Сначала думал над первым вопросом и вчера ночью, мне почему-то показалось что я был близок к решению, но сегодня что-то ничего толком не получилось, перешёл на второй вопрос и тоже сходу что-то ничего не идёт. Флексы я пока не рассматриваю, они где-то, конечно, помогают, но интересно что вообще возможно в классическом CSS 2.1… У меня пока получается, что если родительский блок резиновый, то либо дочерний блок (псевдоблок) пропорциональных размеров, но тогда, чтоб он вышел за пределы родительского блока, его нужно так или иначе вывести из потока, либо если мы создаём что-то, что «чувствуют» окружающие (например отступ) — то это уже от размеров общего родителя. Интересно, есть ли какой-то принцип, за который можно зацепиться, и увидеть, насколько резиновой может быть раскладка… Может исхитриться и что-нибудь в label обернуть, чтоб создать обратную зависимость…
    А второй вопрос тоже относится к резиновости, может ли блок занимать ровно столько место, сколько ему дали, не перепрыгивая на другую строчку…
    Вот такие мысли, по-поводу динамической отрисовки.

  11. У меня на мобильном устройстве физический пиксель равен примерно 0.069 (1080/75 и 1920/133), тогда как px равен 0.26458(3) (дюйм/96).
    Если px разделить на физический пиксель получится 3.8345. Я так понимаю округляется до 4?
    То есть разрешение 1920 x 1080 трансформируется в 480 x 270?

    1. Нет, к сожалению, производители телефонов выбирают коэффициент пересчета из собственных соображений. Например, у айфонов ниже 6-го ширина экрана считается равной 320 CSS-пикселей (т.е. >3 CSS-дюймов, при всего 2 физических). У айфона 6 — 375 CSS-пикселей, а у 6+ — внезапно 414 (т.е. коэффициент пересчета 2.6 с копейками, вообще не целый — там картинка тройного разрешения искусственно чуть ужимается, чтоб вписаться в стандартную FullHD-матрицу). А у некоторых моделей Android-устройств встречается коэффициент 2.25. Универсального правила, увы, нет:(. Но чаще всего для FullHD-устройств встречается коэффициент 3, т.е. экран считается 360х640 CSS-пикселей.

        1. Как при масштабировании растровой картинки. Фактически тот же Айфон 6+ отрисовывает интерфейс как картинку 2208×1242, а потом ужимает ее целиком до 1920×1080. Некоторые тонкие линии, конечно, при этой процедуре могут «мылиться», но поскольку физические пиксели очень малы, обычно это практически незаметно.

          1. Ну то есть принцип такой: у нас есть CSS пикселя белого цвета и четвёртый пиксель чёрного. Допустим коэффициент 2.25.
            Получается 3 х 2.25 = 6.75
            А дальше возможны варианты: либо округляем до 7, либо и, что более вероятно, 7ой цвет 7го пикселя будет считаться, как переходный между чёрным и белым, но поскольку «чёрных долей» в ней в три раза больше (0.75 против 0.25), то и цвет его будет ближе к чёрному.
            Вообще, судя по всему, не такая простая проблема, поскольку приведённый мною пример, скорее, предельно упрощённая схема.
            Но, возникает вопрос, в целесообразности дробных единиц — зачем они, когда веб-графика, по большей части, растровая?
            Не проще либо, в приведённых Вами примерах, 2.25 округлить до двойки, а интерфейс рисовать сразу для FullHD, что, вероятно, было бы и «дешевле» с точки зрения вычислительных ресурсов… Или очень важно соблюсти px = 1/96 дюйма? Но для этого можно сделать просто чуть поменьше/побольше разрешение. Какой смысл в большем разрешение, если оно будет «мылить» наиболее часто выводимый на нём контент?

            1. Насколько я понимаю, оптимизируют не столько под графику, сколько под текст — чтобы он был не слишком мелкий, но и не плющился в узкую колонку в одно-два слова на строку. Растровая графика (без запаса по разрешению) с той самой бикубической интерполяцией будет «мылиться» при любом коэффициенте больше единицы, так что таким образом пытаются выбрать наименьшее зло.

              1. Для растровой графики, насколько я понимаю, чем больше разрешение, тем лучше, поскольку при масштабировании, врят ли возможно избежать дробных значений, да и они не так важны, поскольку изображаются не объекты, а пиксели определённого разрешения, а значит при любом увеличении разрешения, нужно считать переходы (кстати, при уменьшении, тоже вопрос, вот было у нас три пикселя, белый-черный-белый, а теперь эти три пикселя нужно уместить в два. как это сделать без замыливания? :) )
                А для векторной графики, насколько я понимаю, дробный коэффициент, как раз плох, поскольку, чем на большее количество физических пикселей, попадают опорные точки, тем больше мыла (или придётся вносить не заметные искажения, которые, вероятно, в некоторых случаях, могут стать заметными, и/или существенными, например при необходимости точного чертежа).
                Скажем, линия 1px (или другая CSS-ед.) solid black это вектор, потому что можно точно вычислить её границы. С другой стороны, лично я, не знаю способов, нагнуть этот вектор таким образом, чтоб совсем избежать ступенчатости.
                Шрифты, я почему-то думал, что в основном растровые, и только точно векторный SVG. Но поискав в интернете информацию, поэкспериментировав с масштабированием на мобильном устройстве (в том числе посмотрев на поведение шрифтов с засечками), вспомнив и сопоставив всю имеющеюся информацию, я пришёл к выводу, что шрифты, всё же, в основе своей, векторные. Впрочем это, по видимому, большая тема…
                Получается для сайтов с вёрсткой и текстом, лучше кратные разрешения, для изображений и видео экстремального разрешения (и, наверное, для игр) — чем выше разрешение, тем лучше (может ли кратность как-то облегчить жизнь — не знаю, нужно лучше в этом разбираться, чтоб дать точный ответ).
                С учётом легкости масштабирования, мне представляется, что разрешения действительно лучше делать побольше, при этом CSS-пиксели всё-таки делать кратными обычным пикселям, а в жертву принести точность 1px = 1/96 inch, тем более, в мобильном устройстве широко используется масштабирование контента.
                В этом смысле, не очень понятно, то, что Вы пишите:

                текст — чтобы он был не слишком мелкий, но и не плющился в узкую колонку в одно-два слова на строку

                вот скажем у нас физическое разрешение FullHD, а CSS 360х640 (коэфф 3). При размере шрифта в 16px, в моём устройстве, где коэфф соответствия px = 1/96 inch, должен равняться 3.83, поскольку 3 меньше 3.83, текст будет чуть меньше, чем предполагалось при вёрстке (впрочем, мобильники мы обычно держим ближе к себе, чем расположен экран монитора, поэтому разглядеть буквы нам будет проще, да и легко можно масштабировать). Если бы коэфф. был, скажем, 2.83 (например, размер устройства был бы больше, при том же FullHD, соотв. плотность пикселей была бы меньше) и этот коэфф. округлили бы до 3, и буквы (по-умолчанию) стали бы чуть больше. В любом случае колебания размера текста было бы не значительным, врят ли больше настолько, чтоб это как-то сказалось на восприятии строки. Скажем на строке было 15 слов стало 13 или даже 11. Думаю, разница не так уж существенна…
                Впрочем, использование на мобильниках разрешения больше FullHD вообще, по-моему, вопрос немного спорный… Не то что я сильно против, просто задач, где это реально могло бы сказаться, пожалуй, чуть больше чем нисколько…

                1. Для растровой графики, насколько я понимаю, чем больше разрешение, тем лучше

                  Не всегда, если исходную картинку приходится увеличивать. Когда картинку увеличивают вдвое с бикубической интерполяцией, исходные значения остаются лишь у части пикселей, а остальные заполняются промежуточными значениями — что и дает пресловутый эффект «замыливания на ретине» (а использовать разные алгоритмы для увеличения и уменьшения браузерам, видимо, сложно).

                  шрифты, всё же, в основе своей, векторные

                  Да, и именно поэтому одно время были популярны шрифтовые иконки. Другое дело, что для отображения шрифтов, действительно, используются хитрости типа хинтинга (подгонки горизонтальных линий к целым пикселям, благодаря чему шрифты выглядят четче, но заметно искажаются, особенно в мелком размере). Чем выше плотность физических пикселей, тем меньше таких искажений.

                  разрешения действительно лучше делать побольше, при этом CSS-пиксели всё-таки делать кратными обычным пикселям, а в жертву принести точность 1px = 1/96 inch

                  В основной массе стараются так и делать. Именно поэтому у 5-дюймовых FullHD-экранов логический размер 360х640 CSS-пикселей, а не 235×418 (по соотношению 1/96), и текст действительно получается в полтора раза мельче (что компенсируется тем, что мобильники, действительно, держат ближе к глазам). Для разрешения 2560х1440 (большинство нынешних флагманов) уже берется коэффициент 4, что дает те же логические 360×640 (текст того же размера, но еще чуть четче). Дробные коэффициенты — всё-таки скорее исключение. Но они бывают:)

                  1. Извиняюсь, если вопрос банален, но уверен, Вы много раз с ним сталкивались, а потому, вероятно, Вам не составит труда на него ответить :)
                    Мы говорили о максимальных разрешениях, а на какое минимальное разрешение экрана стоит ориентироваться?
                    Спасибо!

                    1. Мне кажется, «практический потолок», на который сегодня стоит ориентироваться — это 4k (3840×2160). Как минимум под Windows оно может учитываться как 1dppx. По физическому разрешению рекорд, пожалуй, у iMac Retina 5k с 5120х2880, но оно актуально только для растровых картинок, в CSS-ных пикселях там скорее всего будет 2560×1440 (2dppx).

                    1. Ой, прошу прощения за невнимательность(. Думаю, стоит ориентироваться на минимальную ширину 320px.

                  2. Почему-то у последнего уровня дерева ответов, нет кнопки ответить, поэтому отвечаю тут…
                    Задал Вам вопрос, а сам подумал: мы говорили про большие разрешения смартфонов, а чего я не спросил про вообще большие разрешения? Так что, Вы, своим ответом, предвосхитили мой следующий вопрос :) Вот теперь, про диапазон разрешений ясно.
                    Спасибо! :)

    1. Да, в теории и em, и rem в медиазапросах должны брать начальный размер шрифта из настроек браузера (16px, если эти настройки не менялись). На практике был один нюанс в Safari (возможно, уже исправили).

      1. Статья отличная, автор проделал эксперименты, с помощью которых, можно понять, как ведёт себя браузер, во всех основных сценариях применения (гифки у него, только, черезчур медленные, засыпаю, когда смотрю, а когда просыпаюсь, мою остановку уже проехали). Тем не менее, насчёт его выводов у меня есть сомнения.
        Ок, давайте назначать медиазапросы в em. Но, тогда, позвольте, у меня все элементы должны зависеть от размера шрифта. А, на мой взгляд, это не вполне правильно — пользователю, в плане масштабирования даны две степени свободы: менять масштаб, и менять размер шрифтов. Не могу сказать что для меня очевидно, зачем менять только шрифты, но, интуитивно, полагаю, что это, в некоторых случаях, может быть уместно.
        При этом, как мне кажется, что в rem-ах, имеет смысл ставить размеры только у тех элементов интерфейса, которые, так или иначе, связаны с оформлением текстового содержимого.
        А раз так, то давайте прикинем, что будет, если мы будем менять размер шрифта.
        Рассмотрим гипотетический пример:

        padding: 10%
        @media only all and (min-width: 1600px) {padding: 8%}


        @media only all and (min-width: 100em) {padding: 8%}

        Мы взяли, да увеличили размер исходного шрифта, с 16 до 22px.
        В первом случае (px), у нас в правилах ничего не изменилось, но, зато мог изменится размер блока, за счёт того, что контент стал чуть побольше.
        В результате, при страничке шириной 1600px у нас уменьшился отступ, но из-за того, что шрифт стал больше, возможно уменьшился он «слишком рано» и оформление могло немного съехать.
        Во-втором случае (em), правила изменили размер странички, при которой будет применено новое правило (от 2200px). Но, в случае, если у нас есть большие куски оформления, не зависящие от шрифтов, то правило может быть применено «слишком поздно», актуальность изменения отступа возникнет раньше, чем окошко «дойдёт» до нужного размера.
        Как же быть?
        Можно написать что-то вроде:

        @media only all and (min-width: 1600px) and (min-width: 100em) {padding: 8%}

        В случае двух min-width берётся большее значение (во всех ли браузерах?) и в нашем случае, при увеличении шрифта с 16 до 22px ситуация будет развиваться по второму варианту.
        Вопрос: когда это критично?
        Если у нас есть дизайн, который работает на 300px (значение от фонаря), то, предполагается, что «тоже самое» будет работать и на 500px. Поэтому, если при увеличении окна «старое оформление» будет оставаться чуть дольше, по-идее, это, конечно плохо, но не смертельно. Поэтому, в этом случае em предпочтительнее.
        Но что будет, если мы уменьшим шрифт? Может получится с точностью до наоборот. Вёрстка предназначенная от 300px переключится в новый режим от 250px и что-нибудь может съехать.
        Но в случае, когда мы используем в медиа-запросе оба правила с em и px, то последний случай исключается.
        Получается дублирование единиц измерения некий костыль, не дающий вёрстке съехать, в крайнем случае.
        Вообще говоря, не совсем понятно, из каких соображений нельзя переопределять размер шрифта браузера для медиа-запросов. Как минимум, для прозрачности кода, мне представляется, лучше писать в примечании, что em зависит от браузера и по-умолчанию равно 16px (поскольку если в документе, по-умолчанию, оно везде равно 10px, то не мудрено, запамятовать).
        Второе, а какое решение, предложили бы Вы?
        Третье, какое, с Вашей точки зрения, решение, могло бы быть стремящимся к идеалу? (с учётом специфики CSS, то есть «однопроходной» логики, без циклов). Мне представляется, возможность использоваться функцию calc в самом запросе. С учётом возможности добавления дополнительных условий через оператор or, наверное, это было бы достаточно для большинства ситуаций, хотя, если честно, не до конца уверен, что достаточно представляю весь спектр возможных ситуаций…
        ЗЫ: код вида:

        .pixel {
        background: red;
        @media (min-width: 400px) {
        opacity: 0.5
        }
        }

        написан на каком-то препроцессоре?

  12. Можно ли в вёрстке использовать линии, меньше чем 1px, рискуем ли мы получить «невидимые нити», в каких единицах измерения это лучше делать, скажем 0.3px или 0.03rem?
    Всегда ли браузеры округляют до px или в некоторых случаях до физических пикселей, или даже до субпикселей?

    1. Использовать можно, но желательно всё-таки тестировать:). Насколько я в курсе, до целых физических пикселей округляются значения тех свойств, которые так или иначе отображаются целыми пикселями, типа border-width или padding (но есть нюансы — например, как минимум в почти всех десктопных браузерах на Windows padding: .1px остается невидимым, но считается ненулевым и не дает схлопываться margin-ам!), а не округляются значения свойств, задействующих субпиксельный рендеринг (тени, letter-spacing и т.п.). А на невидимую линию можно наткнуться и с целыми пикселями, но при нестандартном масштабе в браузере (напр. 90%). Принципиальных различий между поведением разных единиц в этом плане лично я не замечал, но не исключаю, что они могут быть, буду благодарен за примеры.

      1. Ну вот в смартфоне, с коэффициентом 1 к трём, в каком-то месте ширина width: 33.3% и, для простоты, предположим что 1% = 1px. Будет ли смарт задействовать свой «свободный» реальный пиксель для отрисовки 0.3% или округлит нафик? :) И, вне зависимости от, как Вы считаете, насколько оправдана подобная отрисовка?

        1. Думаю, зависит от конкретного алгоритма отрисовки. По логике, должен задействовать. Но вообще надо тестировать (и, скажу по секрету, у нас в черновиках лежит заготовка небольшой отдельной статьи на эту тему:).

      2. И ещё, что-то я не нашёл информации, какое количество знаков после запятой браузеры воспринимают процентную запись. Точнее в интернетах пишут что три, но подтверждений этому найти не удалось. (смотрел из справочника ссылки на спецификации, ну и попробовал в canIuse найти упоминание, может где ещё порекомендуете искать подобную информацию?)

        1. ну и в поисковике: всякие там % css precision, но, если честно, жаль много времени тратить на поиск тривиальной информации, наверняка она лежит в широко известных в узких кругах местах :-)

          1. Про проценты не знаю, а про дробные пиксели для расчетов есть такая информация: в Edge минимальный «квант» длины — 0.01px, в Сафари и Хроме — 0.015625px (1/64), а в Firefox — 0.01666259765625px (1/60 с 32-битной точностью).

  13. Так какую точность для em, на сегодня, актуально использовать/указывать?

    1. Вот ведь мимо носа бегемота не замечу, увлёкшись бабочками… Этот контекст разговора подзабыл, и решил что раз не помню, то и не спрашивал… А ответ же выше! Семён Семёныч… (с) Сорри

    2. Впрочем из полученного выше ответа, не вполне понятно, как будет браузер действовать при, скажем 0.00001em, округлит, до своего «кванта»? (который равен, грубо говоря, от 0.01px до 0.02px)

    3. Ну то есть проблема вот в чём:

      поскольку CSS level3 в медиа-запросах нет отдельных правил, таких как «строго-больше» и «больше или равно» (грубо говоря, есть только второе), то в устройствах с высокой плотностью пикселей, возможна ситуация, когда в одном медиазапросе максимальная ширина окна, допустим 800px, а в другом — минимальная ширина окна начинается от 801px и возникает, некая «нестильная дыра», в которую пользователю, конечно, нужно ещё умудриться попасть, но такой вариант не исключён (если второй запрос начинаем с минимальных 800px, то на «ровно» 800px применяются оба стиля, и получится трэш, ну или очень красиво :-) ). Да, конечно, подобных наложений можно избежать, использая принцип mobile first (прогрессивно улучшая дизайн, добавляя от какого-то разрешения, какие-то новые параметры). Этот принцип хорош, но, не думаю, что он универсален, то есть применим всегда и везде. Поэтому поискать каким образом, можно уменьшить «зазор» между стилями, и задуматься над тем, чтоб в реальной жизни такая ситуация не случилась, думаю, будет не лишним…

      Поэтому первый вопрос: браузер применяет те стили, которые соответствуют разрешению окна, в его внутреннем представлении или которые получаются после округления? (ну или как?)

      Второй момент: нам нужно, чтоб применились ТОЛЬКО ОДНИ стили к любому из возможных разрешений, то есть, по медиа-запросам, для любого, из возможных разрешений браузера, должен быть только один блок правил. Но при этом, чтоб не было дырок, то есть, если ни одно, то другое. Поэтому и возникает вопрос минимального «кванта», который нужно учитывать в медиазапросах, с понимаем того, что этот «квант» для разных браузеров разный.

      Так вот если у нас ширина окна отталкивается от em, то сотая часть пикселя будет равна 0.000625em, а две сотые — 0.00125em, ну вот допустим мы округлим до 0.001em не возникнет ли ситуация, что браузеров с меньшей «виртуальной точкой» может возникнуть «пустое окно» (в данном случае в него можно попасть лишь случайно, но тем не менее), а браузеров с большей виртуальной точкой, разрешения «сольются», и будут применены стили из обоих медиа-запросов… Более того, если мы будем менять браузерные шрифты, то это может увеличить/уменьшить эту минимальную точку (если медиа-запросы писать в em), что ещё более усугубит эту, уже не вполне простую ситуацию…

      Когда уже медиазапросы четвёртого уровня станут рекомендациями, и будут внедрены в браузеры? Чтоб можно было спокойно, и любыми сравнениями пользоваться (и строгими, и не строгими, поскольку одни, дополняют другие), и скобками, для группировки условий, и назначением именно того, что нужно, а не  умудряться всё нужное вместить в линейный запрос…

      И второе, как быть сейчас, какой минимальный квант, для указанной проблемы (стыковки максимального разрешения одного медиа-запроса, и минимального разрешения другого запроса) стоит использовать, чтоб не допустить возможных артефактов(«пустых точек» и наложения обоих стилей) во всех современных браузерах,

      при назначении медиа-запросов в пикселях?

      в em?

      Благодарю за внимание :)

          1. Да нет, в приниципе, если указать

            @media (max-width: 800px) {

            // Styles

            }

            @media (min-width: 801px) {

            // Styles

            }

            В итоге у нас получится, что одни стили заканчиваются на 800px включительно,

            а вторые начинаются на 801px включительно.

            Если же мы, и min-width, и max-width зададим на 800px, то у нас применятся стили, которые выиграют в каскаде. В моём примере это будут стили, которые в min-width, так как они в коде позже, так что 2 значения мы никогда не получим.

            Все проблемы решаются тем, что мы немного следим за медиазапросами, конечно, лучше использовать 800 — 801 px, так в таком случае какое-нибудь непереопределённое свойство из max-width не залезет в наш промежуточный экран с шириной в 800px.

            Лично я всегда начинаю от Mobile First, а в случаях с элементом picture, а именно с его атрибутом media, я ограничиваю картинки с обоих сторон.

            1. Ну то, что проблема носит, скорее архитектурный недостаток, я понимаю. Но всё-таки адекватного решения, которая «склеит всё без стыков» я пока не наблюдаю…

Добавить комментарий для Алексей Отменить ответ

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Получать новые комментарии по электронной почте. Вы можете подписаться без комментирования.