Соблюдаются ли десятичные разряды в ширине CSS?

225

Что-то, что меня интересовало, пока я занимался дизайном CSS.

Соблюдаются ли десятичные разряды в ширине CSS? Или они округлые?

.percentage {
  width: 49.5%;
}

или

.pixel {
  width: 122.5px;
}
Аластер Питтс
источник

Ответы:

186

Если это процентная ширина, то да, это соблюдается . Как указал Мартин, все становится хуже, когда вы получаете дробные пиксели, но если ваши процентные значения дают целочисленное значение пикселя (например, 50,5% от 200 пикселей в примере), вы получите разумное, ожидаемое поведение.

Изменить: я обновил пример, чтобы показать, что происходит с дробными пикселями (в Chrome значения обрезаются, поэтому 50, 50,5 и 50,6 все показывают одинаковую ширину).

Skilldrick
источник
7
Вы правы в том, что процентные значения не округляются сами по себе, но ширина пикселей с десятичными знаками и конечный результат расчета процента всегда будут округлены до целых пикселей :)
MartinodF
2
@MartinodF Спасибо за разъяснения. Да, пиксели округлены, но не определено, действительно ли они округляются до ближайшего, пола или потолка (что я имел в виду под «вещами, которые ломаются»).
Скиллдрик
1
@Skilldrick Ради любопытства я попробовал дробные пиксели в вашей демонстрации в некоторых браузерах: IE9p7 и FF4b7 округляют до ближайшего пикселя, а Opera 11b, Chrome 9.0.587.0 и Safari 5.0.3 усекают это значение. @andras Просто чтобы уточнить: я не говорю, что внутренние значения округлены, только окончательные значения рендеринга. Если вы масштабируете или некоторые элементы наследуют свойства и т. Д., То десятичные разряды будут учитываться.
MartinodF
10
Современное обновление: моя версия Chrome 24 фактически округляет дробные пиксели. При просмотре jsFiddle, 50,5 и 50,6 округляются до 51 пикселя, что на 1 пиксель шире, чем у делителя 50 пикселей.
Майкл Батлер
5
Что может быть наиболее важно отметить, это то, как элементы с дробными размерами в пикселях складываются рядом друг с другом. В то время как они делают круглые визуально сами по себе, они также не занимают дополнительное пространство , если положить рядом с другими дробно размерных элементов: cssdesk.com/8R2rB
Sandy Гиффорд
53

Даже когда число округляется при рисовании страницы, полное значение сохраняется в памяти и используется для последующих дочерних вычислений. Например, если ваш прямоугольник с размером 100,4999 пикселей перерисовывает в 100 пикселей, его дочерний элемент с шириной 50% будет рассчитан как 0,5 * 100,4999 вместо 0,5 * 100. И так далее до более глубоких уровней.

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

Крайний случай, конечно, но кое-что нужно иметь в виду.

natekoechley
источник
2
Принятый ответ является более полным, чем этот, но анекдот в этом дает мне лучшее представление о том, как будут ощущаться технические последствия. Спасибо за публикацию.
Том
23

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

Это лучше всего видно, когда элементы располагаются рядом (или поверх друг друга); другими словами, если бы я поместил 400 делителей по 0,5 пикселя рядом, они бы имели такую ​​же ширину, что и отдельный делитель 200 пикселей. Если бы все они на самом деле были округлены до 1 пикселя (как следует из рассмотрения отдельных элементов), мы ожидали бы, что 200px div будет вдвое длиннее.

Это можно увидеть в следующем фрагменте кода:

body {
  color:            white;
  font-family:      sans-serif;
  font-weight:      bold;
  background-color: #334;
}

.div_house div {
  height:           10px;
  background-color: orange;
  display:          inline-block;
}

div#small_divs div {
  width:            0.5px;
}

div#large_div div {
  width:            200px;
}
<div class="div_house" id="small_divs">
  <p>0.5px div x 400</p>
  <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</div>
<br>
<div class="div_house" id="large_div">
  <p>200px div x 1</p>
  <div></div>
</div>

Сэнди Гиффорд
источник
11
Что касается рендеринга: в вашем примере у вас есть два div, конкурирующих за каждый пиксель. В этих случаях ваш браузер выберет один из них для рендеринга всего пикселя - чтобы избежать размытия и других странных артефактов. Если вы установите половину пикселей в синий цвет, используя :nth-child(even)или :nth-child(odd), вы заметите, что либо все это оранжевое, либо все это голубое, а не смесь синего и оранжевого (что было бы неким смутным пурпурным оттенком).
Даан Уилмер
16

Ширина будет округлена до целого числа пикселей .

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

редактировать : я попробовал демо @ Skilldrick в некоторых браузерах для любопытства. При использовании дробных значений пикселей (не в процентах, они работают так, как это было предложено в статье, с которой я связан), IE9p7 и FF4b7, кажется, округляются до ближайшего пикселя, в то время как Opera 11b, Chrome 9.0.587.0 и Safari 5.0.3 усекают десятичные разряды. Не то чтобы я надеялся, что у них есть что-то общее в конце концов ...

MartinodF
источник
7

Кажется, они округляют значения до ближайшего целого числа; но я вижу несоответствие в Chrome, Safari и Firefox.

Например, если 33,3% конвертируется в 420,945 пикселей

chrome и firexfox показывают его как 421px. в то время как сафари показывает его как 420px.

Кажется, что chrome и firefox следуют логике пола и потолка, а сафари - нет. Эта страница, кажется, обсуждает ту же проблему

http://ejohn.org/blog/sub-pixel-problems-in-css/

agaase
источник
6

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

Важным примечанием является то, что пиксели в данном случае означают пиксели css , а не пиксели экрана, поэтому контейнер 200 пикселей с дочерним элементом 50,7499% будет округлен до пикселей CSS 101 пикселей , которые затем отображаются на 202 пикселя на экране сетчатки, а не 400 *. 507499 ~ = 203 пикс.

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

[*] Вы можете использовать некоторые методы, такие как box-shadow со смещением 0,5 и т. Д., Но фактические свойства box-модели будут отображаться до полного пикселя CSS.

Олекс Пономаренко
источник
Отлично наблюдение
август