Веб-разработка

индекс
236,88

Проблемы с округлением в CSS

Посмотрите на эту страницу. Синим цветом выделены 4 плавающих блока с шириной равной 25% у каждого, которые находятся в контейнере с шириной 50px. Теперь вопрос: Какова ширина каждого блока?

Ширина эта должна быть равна 12.5px, но т.к. мы можем использовать только целые значения, то приходится округлять значения. И тут же возникает вопрос: В какую сторону округлять? В большую, в меньшую или в обе? Результаты думаю вас удивят, как и меня.


В итоге мы имеем три абсолютно разных лагеря.

Округление в меньшую сторону — И Opera и Safari округлили значение ширины до 12px. В результате чего образовался 2-x пиксельный пробел (помечен зеленым цветом) справа от блоков. Если вы когда-либо озадачивались, почему ваша красивая навигация не заполняет все пространство контейнера, теперь вы знаете ответ.
Округление в большую сторону — 6-й и 7-й Internet Explorer увеличивают ширину до 13px, что приводит к «поломке» структуры сайта.
Округление в обе стороны — Firefox 2 и 3 сочетают оба подхода, округляя ширину одних блоков в меньшую сторону, а других в большую. Побочный эффект заключается в том, что ширина блоков теперь имеет разное значение, несмотря на то, что в CSS задано одно значение. К тому же, если получить значение ширины с помощью Javascript, то оно будет равно 12.5px, не давая понять в какую сторону было произведено округление. Есть и еще один неприятный момент. В Firefox 3 меняется порядок округления.

David Baron, один из разработчиков Mozilla, разъяснил ситуацию:

- Мы стараемся соблюдать все нижеописанные правила, которые, однако же, не могут быть удовлетворены одновременно:

1. 4 смежных объекта шириной/высотой 25% (например), начинающиеся у одного края внешнего контейнера, должны заканчиваться у другого. Не должно появляться никаких свободных или лишних пикселей.
2. Объекты, которые являются логически смежными, всегда должны визуально касаться друг друга. Не должно быть никаких пустых пробелов или наложений, возникающих из-за ошибки округления.
3. Объекты с одинаковой шириной должны занимать такое количество пикселей, которое было задано.
4. Границы объектов не должны быть размыты.

Эти правила могут быть полезными, но придется пожертвовать по меньшей мере одним из них, для того чтобы удовлетворить остальным.
+31
31 января 2008, 10:36
22

комментарии (24)

0
nekt #
Получается, что при верстке стоит рассчитывать только на 99% размера родительского блока с определенным размером?

Или есть другие методы с исправлением ситуации?
0
kost_bebix #
Или использовать кол-во процентов, достаточное для того, чтоб не приходилось пиксели "делить".
0
zolotu #
Согласен. Простые решения обычное правильные
0
wialy #
Обычно, ширина в процентах, кратная 4, показывается корректно везде. Хотя с ие попробуй угадай.
0
Maximark #
нужно стараться % - ми верстать... желательно кратной 2
Желательно "резиной"
0
xalexx #
Думаю рассчитывать надо на 100, но хотя бы изначально задавать такие размеры, чтобы получались целые числа.
0
medvoodoo #
а дальше начинается развлекуха с бордерами, которые то считаются так то эдак :) имхо лучше делать запас
0
gdX #
Встречал такие варианты с плавающими блоками, когда сайт верстается, допустим, в 2 колонки (к примеру 30% и 70% соответственно), то opera и ff при таких процентах блоки выставляют правильно - один за одним, а для ie прихзодится делать правый блок 69.9%. Тогда он не будет сваливаться под левый при изменении размеров окна.
0
andruha_derby #
Интересное исследование.

Вот только я не понимаю чем
12.5px
отличается от 12.4667px

Ведь пиксель - минимальная величина, или я что то путаю? То есть у меня в фотошопе
12px и 12.4px - это одно и тоже = 12px

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


также в теории может быть использован антиальясинг - там влияние дробных долей былобы существенным.
0
altmind #
очень просто.
просто в x86 процессорах, не все десятичные дробные числа могут быть представленны без потери точности :)
0
valodka #
С точки зрения CSS px не является абсолютной величиной.
0
spanasik #
Firefox делает всё правильно.
0
ayavryk #
FF конечно гениальный броузер, но зачем же пиксели ломать?
0
guvatara #
Я думаю что нужно вынести эту проблему на W3C и разработчикам просто взять их решение за основу. А по хорошему нужно находить решения такие, чтоб не нужно было извращаться с версткой. Я думаю дизайнер, если он понимает что делает, то вполне может предугадать такие вот казусы и находить более приемлемые варианты без ущерба всей концепции сайта.
0
lahmatiy #
На днях размышлял на эту тему, подумалось что не плохо было бы, если в CSS3 внесли такие вещи:
width: 1/4;
или, что бывает не редко
width: 1/3;
тогда как писать 33.33333% не очень
продолжая тему можно было бы ввести модификатор N означающий количество дочерних элементов, тогда получается
width: 1/N;
В зависимости от числа элементов их ширина будет пропорционально распределена по ширине родителя.
Можно так же продолжить
width: 2/N;
Блоки будут "растекаться" в две линии.
width: 1/2N;
Блоки будут делить половину ширины родителя.
width: 2N;
Не знаю насколько это разумно, но при 2 элементах элементы будут в 4 раза больше родителя, при 3 в 6 раз, при 4 в 8. Наверное данная запись лишена смысла.
Предложил бы кто нибудь данную тему w3c...
0
Chupa #
А еще в опере есть такая проблема, что она воспринимает только целые значения в процентах для ширины. Например 25,5% превратятся в 25%.
0
rat #
Да, очень не красивая штука. Если задать ширину блока 0.5%, блока вообще не будет видно, так как опера эту величину до 0% сократит. В свое время меня этот эффект очень озадачил, пришлось отказаться от использования процентов в пользу целых пикселей.
0
b2k #
вопервых там точка должна стоять а не запятая. во вторых все прекрасно работает. недавно прописывал паддинги 4.5px и в трех браузерах отображалось 9 при соединении двух блоков...
+2
Arwen #
очень интересная статья:) только, пожалуйста, добавьте хабракат, чтобы неприятностей (в виде незаслуженных минуов за это) не было.
–1
Stepanow #
Похоже, те кто минусуют Arwen не знают ни про хабракат, ни про то, зачем хабралюдям дано право минусовать и плюсовать друг друга. Не так просто нести свет людям, хотя на кострах за это уже не сжигают =)
0
Stepanow #
Ну вот, Arwen уже в плюсе, зато меня минусанули. Нет слов.
0
iuhiol #
нечего использовать дробные числа в CSS, теперь это очевидно. Результат для таких чисел был раньше непредсказуем, а теперь видно почему. Разработчикам браузеров можно порекомендовать интерпретировать такой случай как ошибку, так как претензионной точности для дизайна не получится, особенно для областей с большой контрастностью. В браузере для таких случаев можно ввести режим "кривой дизайн"
0
Freem #
да а красиво было бы делать так:

<div style="float:left; width: 50%">main</div>

<div style="float:right; width: 50%">

    <div style="float:left; width: 50%">
     sideblock-1
    </div>
    <div style="float:right; width: 50%">
     sideblock-2
    </div>

</div>

при изменении окна в IE, блок вываливается вниз, хорошо если верстка простая, бывает же еще и со "штучками дрючкапи" :-\

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.