Браузеры запутались в блочной модели для таблиц

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

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

    Похоже, производители браузеров в гонке за количеством внедренных черновиков – забыли, что стандарты нужно не только поддерживать, но и поддерживать правильно и одинаково.

    Вступление


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

    Когда начал присматриваться к деталям, обратил внимание, что в Chrome строки таблиц почему-то были больше по высоте, чем в других браузерах. Решил выяснить, в чем дело.

    Тестирование


    Сделал небольшую тестовую страничку. На которой выводятся DIV (в качестве эталона для сравнения) и таблица в которой одна ячейка (для нашего теста более чем достаточно).

    У блока DIV и ячейки таблицы TD выставляем в CSS одинаковые размеры и границу побольше, для наглядности.
    div, td{
    	width:100px;
    	height:100px;
    	border:25px solid #333;
    }

    У самой таблицы границу убираем. Все margin и padding обнуляем, cellspacing тоже (свойство border-collapse пробовал – результат аналогичный).

    На странице расположены 4 примера, со стандартной блочной моделью (content-box) и с использованием box-sizing: border-box, а также с прописанной шириной у таблицы и без неё (оказалось, тут тоже, у браузеров нет единого мнения).

    В тестировании приняли участие последние релизы основных браузеров:
    • Chrome 16
    • Firefox 9.0.1
    • Internet Explorer 9
    • Opera 11.61

    Тест проводился на Windows 7 x64.

    Результаты


    Для удобства анализа результатов свёл скриншоты браузеров в одну картинку (кликабельна).


    Как видим самый близкий результат рендеринга показан, когда включена блочная модель border–box и задана ширина у таблицы. В таком случае получаем одинаковый рендеринг в 3 браузерах из 4. Как раз всплыл тот самый баг Chrome из-за которого, я начал этот разбор полетов.

    В стандартной же для W3C блочной модели браузеры поделились на пары. Причем, что интересно рендеринг в content-box совпадает у Chrome и IE9, а в border-box уже идентичную «картинку» выдают IE9 и Opera.

    Также отметим, что IE9 и Opera уже используют свойство box-sizing без префиксов, в отличии от Chrome и FireFox.

    Заключение


    Как с этим бороться пока оптимального решения не нашел, ограничился костылем для Chrome. Для него ставится меньше высота ячеек.

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

    Подробнее
    Реклама
    Комментарии 106
    • +2
      Под Linux картинки для Firefox и Chrome имеют аналогичные ошибки, что и под Windows. Так что в данном случае операционная система не вносит искажений, только различия в реализации браузеров.
      • +5
        А какие искажения в CSS должна вносить система?
        • +21
          С одной стороны — никаких. С другой — чем черт не шутит.
          • +4
            Не так давно был баг, когда хром рендерил тени в макоси правильно, а в винде — нет. Починили где-то к девятой версии что-ли.
            • НЛО прилетело и опубликовало эту надпись здесь
              • 0
                например?
                • НЛО прилетело и опубликовало эту надпись здесь
                  • +1
                    Это 100%. В последних Хромах сломали рендеринг шрифтов — в винде рендерились без сглаживаниЯ, в то время, как в Никсах всё было прелестно, как и прежде.
          • +7
            Хром (кликабельно):

            • 0
              Это радует, значит скоро ситуация наладится.
            • +2
              chrome 18.0.1017.2 dev-m
              страничка получилась как на скрине с IE
              • +58
                И где стандартный комментарий про IE? :) Судя по всему он единственный, кто работает правильно.
                • +22
                  Да IE 9-10 почти норм. Если бы теперь 7-8 исчезли, было бы круто
                  • +3
                    делайте плавную деградацию, не пытайтесь сделать закругленные уголки, тени, и т.д. И не будете замечать проблем в IE7-8. А IE6 почти IE7, только alpha не поддерживает, заменяет на png8, и не обращайте на неровности на краях :) и у вас почти не будет головной боли.
                    Плюс через сonditional comments можете в ie6-ie8 отключить часть функционала, или сделать его по другому.
                    • +14
                      Я вам скажу по секрету, если заказчик хочет на своем ie 7 закругленные уголки, и платит за это — приходится делать
                      • –3
                        Я знаю, в последнем проекте столкнулся с этим :( как я только не называл ту девушку, которая мне показывала скриншот в ie7 и скрин макета… Ей не смог объяснить, что это не правильно :( пришлось делать. Хотя она сама мне показывала статистику браузеров, в котором ie6-ie7 в сумме меньше 4%.

                        С большинством проще, они сразу понимают, что так не надо делать, и хотят, чтобы все было хорошо в ipad/iphone )
                        • +8
                          ie6-ie7 в сумме меньше 4%.

                          Иногда это бывает критично.

                          Например у нас через проект идут заявки на покупку франшизы. В среднем около 100 заявок в день. Цена одной заявки в среднем 1,5 миллиона рублей.

                          Доля ie6/ie7 у нас на сайте порядка 2,5%. Но если мы скажем что доля 2,5% очень маленькая и ей можно пренебречь — это будет неверно, потому что если наш сайт не будет нормально работать в ie6/7 то наши партнеры будут каждый день терять в среднем 4 миллиона рублей.

                          Достаточно солидная мотивация сделать чтобы все работало :)

                          Поэтому считать в % не всегда верно, как мне кажется.
                          • +12
                            150 миллионов в день. Это 55 миллиардов в год. Кто эти люди? Мы на одной планете живем?
                            • НЛО прилетело и опубликовало эту надпись здесь
                              • НЛО прилетело и опубликовало эту надпись здесь
                              • 0
                                разделите на 320 франшиз и сумма станет уже не такой астрономической :)
                              • +13
                                И что для создания заявки необходимы именно закругленные уголки?
                                • +3
                                  Именно закругленные уголки не необходимы, но и мой комментарий был не об этом, а том что человек говорил мол в статистике 4% это же очень мало, чего она придирается.

                                  А я хотел своим комментарием сказать что мерять такие вещи процентами не очень верно, потому что за мизерным процентом могут скрываться солидные суммы денег.
                                • +2
                                  Никто не говорит отказать от работы в IE6-IE8
                                  просто можно делать так, чтобы там было менее красиво, но все также и работало. Отключение части визуальных возможностей — закругленные уголки, стилизованные формы и т.д. не должны не как повлиять на клиентов, тем более они и не узнаю, что там должно было быть что-то круглое, пока не откроют сайт в нормальном браузере.
                                  • +1
                                    Человеку который что-то покупает далеко **** на круглые уголки и тени если что! Он хочет купить быстро, дешего и качественно.
                                    • 0
                                      «быстро, дешего и качественно» — выберите любые 2 пункта
                                      • +4
                                        Дешегле некуда.
                                        • 0
                                          В большинсвте случаем надо искать гармонию между этими 3 пунктами, а не просто отбрасывать один.
                              • –1
                                Для этого нужно чтобы исчезла XP или MS выпускала для неё браузеры.
                            • +3
                              Я не понял. Вы сначала говорили о поддержке древних стандартов, а использовали box-sizing (даже заметили, что кое-кто их без префиксов использует). Как так?
                              • 0
                                www.w3.org/TR/css3-ui/#box-sizing
                                W3C Working Draft 17 January 2012
                                • +1
                                  Content-box это стандартная блочная модель для w3c, для него свойство box-sizing вообще не используется.
                                  • +1
                                    Ну, Working Draft — это даже не Candidate Recommendation. Формально именно на стадии CR браузерам рекомендуется делать реализацию, причем желательно с вендор-префиксом. Префикс убирается на стадии Proposed Recommendation. Что-то браузеры тут вперед паровоза спешат.
                                    • НЛО прилетело и опубликовало эту надпись здесь
                                      • НЛО прилетело и опубликовало эту надпись здесь
                                      • НЛО прилетело и опубликовало эту надпись здесь
                                      • +2
                                        Древние я имел ввиду сами таблицы и свойства width, height, border. Box-sizing появился уже при попытке заставить браузеры одинаково работать. Да и -webkit-box-sizing чуть ли не с первой версии Chrome реализован.
                                      • 0
                                        • +2
                                          В Mac OS поведение аналогичное. FF 9.0.1 как на Вашем скриншоте, Safari повторяет Chrome (и не удивительно, проблема в WebKit'е).
                                          • +2
                                            box-sizing — черновик (http://www.w3.org/TR/css3-ui/). Поэтому нет ничего странного в том, что при его использовании вылезают косяки в некоторых браузерах. А IE, да, молодец.
                                            • +1
                                              Наверное стоит уточнить, в случае с дефолтным content-box свойство box-sizing в примерах не используется. Так как это стандартная блочная модель W3C.
                                            • 0
                                              FF12 (Nightly) — аналогично FF9 из поста.
                                              Пруф.
                                              • НЛО прилетело и опубликовало эту надпись здесь
                                                • +1
                                                  А как гадко начинают вести себя таблицы с colspan, когда в больших ячейках сверху текст занимает места больше чем размер маленькой ячейки снизу.
                                                  • 0
                                                    я понимаю, что брюзжу, но поменяйте cellspacing=0 на стили border-collapse: collapse; а то невалидно :)
                                                    • НЛО прилетело и опубликовало эту надпись здесь
                                                      • 0
                                                        Если вам нужно убрать отступы между бордерами в таблице, то да, эквивалентно, другой причины, почему автор использует не рекомендуемый тег не вижу. И не ширины а отступов и отрисовки бордеров.

                                                        htmlbook.ru/html/table/cellspacing
                                                        htmlbook.ru/css/border-collapse
                                                        • НЛО прилетело и опубликовало эту надпись здесь
                                                          • НЛО прилетело и опубликовало эту надпись здесь
                                                      • +2
                                                        • +1
                                                          Автору: На тестовой странице нижний правый пример подписан не верно, хотя на скриншотах всё в порядке… Вероятно должно быть «Box-Sizing: border-box»
                                                        • +2
                                                          > Браузеры запутались в блочной модели для таблиц
                                                          Немудрено. Еще в прошлом веке W3C заварил дурацкую кашу с дурацкой боксовой моделью. Потом зачем-то ввел дополнительно к своей дурацкой микрософтовскую, и вот результат через 13 лет — «Браузеры запутались в блочной модели»
                                                          • НЛО прилетело и опубликовало эту надпись здесь
                                                            • +5
                                                              Та потому то W3C — мудаки, далёкие от жизни.
                                                              • 0
                                                                > я по сей день так и не понимаю…
                                                                в общепринятой модели были нестыковки. Например, непонятно как быть с картинкой. Если ей давать border то либо контент съедается, либо картинка масштабируется. В W3C решили эту проблему, зато и разработчики получили геморрой минимум на два десятилетия.
                                                                • НЛО прилетело и опубликовало эту надпись здесь
                                                                  • 0
                                                                    Ну падинги, зависимые от ширины не такое плохое решение. Если поставить padding: 1%;, то мы будем иметь одинаковый отступ со всех сторон и, главное, он не будет расти при увеличении количества контента.
                                                                    • НЛО прилетело и опубликовало эту надпись здесь
                                                            • +1
                                                              Надеюсь, табличные данные вы не собираетесь дивами переверстывать?
                                                              • +1
                                                                Я собираюсь. Во всяком случае попробовать. Дивы рисуются намного быстрее чем таблицы. В ИЕ нельзя заменять иннерХТМЛ в ТР, что для меня критично, ибо иаблица рассчитывается на хотя бы 20к строк и потому рисует только видимый кусок + запас.
                                                                • +1
                                                                  Намного быстрее? Уверен, что есть более гуманные способы решения вашей задачи.
                                                                • 0
                                                                  Я не собираюсь, для грида таблицы используются. И учитывая, что по комментариям выше уже в следующей версии Chrome будет работать как IE9, то спокойно можно использовать таблицы с border-box. Как раз в моем случае пока закончу грид, и хром обновится.
                                                                  • +8
                                                                    ничто в этом обсуждении не ласкает слух работников Microsoft как: "… в следующей версии Chrome будет работать как IE9..."
                                                                • +1
                                                                  Еще браузеры ведут себя странно и в другой ситуации с таблицами 100% высоты в ячейке(display:table-cell) таблицы(display:table)
                                                                  • НЛО прилетело и опубликовало эту надпись здесь
                                                                  • +2
                                                                    Если сделать border 1px, все приходит в более-менее норму. Я подозреваю, проблема вызвана тем, что при расчете размеров border оказыается в разных браузерах принадлежащим разным кускам таблицы: где-то он принадлежит td, а где-то — tr или колонке, соответственно, где-то он влияет на. Вот отсюда, видимо и погрешности. Спецификация CSS ведь многие моменты оставляет на откуп браузерам, верно? Ну вот и не жалуйтесь.

                                                                    Еще интересный момент, который меня всегда раздражал — во всех браузерах input:text имеет box-sizing: content-box, а button — box-sizing:padding-box + иногда еще 1-2 пиксельные неубиваемые отступы в некоторых браузерах. Как в такой ситуации сделать input и кнопку одинаковой высоты, если мы не хотим жестко задавать пиксельные размеры? Непонятно.

                                                                    • НЛО прилетело и опубликовало эту надпись здесь
                                                                      • 0
                                                                        border 1px не спасает, просто делает менее заметным, что у Chrome ячейки чуть больше.
                                                                      • +4
                                                                        Да, ни один современный браузер не поддерживает полностью HTML 4 и CSS 2.1 для таблиц, как ни странно. А ведь стандартам почти 15 лет…
                                                                        • –1
                                                                          Зачем тестовую страницу со статическим контентом делать в php? Чтобы наплыв пользователь с хабра положил сервер?
                                                                          • 0
                                                                            Ну при чём тут php, скажите, а? Не нужно людекй провоцировать на холиворы.
                                                                            • +2
                                                                              Какие холивары? Статический HTML отдаётся быстрее любой динамической страницы, на чём бы она ни была написана. Я думаю, в этом мнении все едины.
                                                                            • +1
                                                                              Там php просто для записи статистики посещения в лог, чтобы заодно проверить сервер на устойчивость к хабраэффекту.
                                                                            • 0
                                                                              Отличное исследование! И не менее полезные комментарии, в основной своей массе.
                                                                              Топик-стартеру — спасибо.
                                                                                • НЛО прилетело и опубликовало эту надпись здесь
                                                                                  • 0
                                                                                    Хромиум виноват, видимо. Все-таки тестовый продукт.
                                                                                    • 0
                                                                                      Возможно глюк одного из плагинов (AdBlock например).
                                                                                      По крайней мере после отключения и перезагрузки все нормально.
                                                                                  • 0
                                                                                    Opera 12 alpha: от 11.52 не отличается.
                                                                                    • НЛО прилетело и опубликовало эту надпись здесь
                                                                                      • +3
                                                                                        Похоже, производители браузеров в гонке за количеством внедренных черновиков – забыли, что стандарты нужно не только поддерживать, но и поддерживать правильно и одинаково.

                                                                                        Нужен очередной Acid Test для поднятия мотивации у разработчиков браузеров. Собрать 10 самых старых и грубых недочётов от каждого браузера (некоторые будут общими для нескольких браузеров) и сделать красивый и интересный тест. Если кто возглавит мероприятие, то я присоединюсь.
                                                                                        • +1
                                                                                          www.hixie.ch/tests/evil/acid/004/

                                                                                          It will likely focus on the following specifications and areas:

                                                                                          * dev.w3.org/csswg/css3-multicol/
                                                                                          * dev.w3.org/csswg/css3-background/

                                                                                          It may also include subpixel positioning; will likely be partially or
                                                                                          entirely in rtl mode and may contain non-ASCII Unicode characters with
                                                                                          special formatting requirements, e.g. U+200B; and may contain empty
                                                                                          inline boxes that are styled.


                                                                                          Как видим, Хикси не собирается ориентироваться на старые ошибки браузеров.
                                                                                          • 0
                                                                                            В принципе проверку этого бага довольно легко можно автоматизировать, так что можно собирать различные глюки, и потом сделать тестилку, и вполне возможно, что публикация его на хабре, доберется и до разработчиков.
                                                                                            • НЛО прилетело и опубликовало эту надпись здесь
                                                                                              • 0
                                                                                                Тесты — само собой. А интересные тесты — это хорошая мотивация для самих разработчиков, они сами признавались.
                                                                                                • НЛО прилетело и опубликовало эту надпись здесь
                                                                                            • 0
                                                                                              display: inline-block; по идеи должно зафиксить разницу для всех браузеров и без всяких костылей.
                                                                                              • 0
                                                                                                или display: block; :) td все таки не совсем блочный элемент
                                                                                                • 0
                                                                                                  Какая разница какой это элемент, нужно чтобы этот элемент выглядел одинаково во всех браузерах, разве не для этого стандарты придумали?
                                                                                                • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                • +1
                                                                                                  Вам не кажется, что надо начинать с себя, прежде чем писать изобличительные статьи в стиле «шок! интриги! расследования!»?
                                                                                                  1. border-collapse должен быть separate, иначе ячейки не ведут себя как отдельные блоки
                                                                                                  2. у вас неверно прописаны стили, и где ширина таблицы — проставлена ширина и таблицы и td
                                                                                                  3. при работе с размерами таблицы всегда указывают table-layout: fixed, без этого все размеры являются, как бы это сказать, пожеланиями, которые браузер может не учитывать.
                                                                                                  4. высота должна выставляться элементу, которому задана ширина: если задаем ширину table, то и высоту там, td в обратном случае

                                                                                                  Если все нормально сделать, все работает правильно(внимание, большая картинка с ie, ff, chrome): imgur.com/1EIwV
                                                                                                  Страница тут: jsfiddle.net/kXM5K/

                                                                                                  2 замечания:
                                                                                                  в одном случае пришлось выставить td display: inline-block
                                                                                                  в ие див и таблица смещены по вертикали относительно друг-друга (они display: inline-block), но размеры верны
                                                                                                  • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                    • 0
                                                                                                      Согласен, inline-block — не совсем верное решение. В хроме есть баг, где box-sizing применяется только к ширине td, т.е. выходит ширина 100px, высота 150px. Баг уже исправлен в Canary.

                                                                                                      Еще удалось найти: «However, in HTML and XHTML1, the width of the element is the distance from the left border edge to the right border edge.», т.е. ширина (и высота) таблиц считается по умолчанию вместе с бордерами. (это еще со времен HTML3: «The default table width is the space between the current left and right margins.») И далее: «In CSS3 this peculiar requirement will be defined… бла бла». Т.е. точное поведение таблиц с box-sizing еще не определено в css3. www.w3.org/TR/CSS2/tables.html#width-layout
                                                                                                      • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                        • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                          • 0
                                                                                                            Нда, обсуждение немаленькое получилось :)
                                                                                                            «Таблицы … всячески подстраиваются под контент, и применять их следует не для жёсткой разметки страницы, а для плавающих табличных данных» — именно. Даже при разном поведении в тестах, если использовать их не для разметки, а по прямому назначению, как задумывалось, проблем, как правило, никогда не возникает.
                                                                                                            • 0
                                                                                                              Я их для грида использовал, или грид не таблицами нужно делать?
                                                                                                              • 0
                                                                                                                Классический пример такой сетки, если я правильно понял слово «грид», вот: 960.gs/
                                                                                                                Ну или это: lessframework.com/
                                                                                                                Конечно же, все без таблиц.
                                                                                                                • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                  • 0
                                                                                                                    Именно Data Grid, таблица с фиксированным заголовком, и разными дополнительными фичами, типа группировки, сортировки, редактирования.
                                                                                                        • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                        • 0
                                                                                                          Это уже из разряда костылей по-моему. Зачем тогда все эти стандарты раз так нужно извращаться для создания простой таблички.

                                                                                                          1. border-collapse, как и border-spacing тут вообще ни к чему, так как это касается блочной модели, браузеры не могут определиться входит граница в размеры ячейки или нет.
                                                                                                          2. В чем ошибка? Это как бы наоборот позволило увидеть адекватное отображение в firefox.
                                                                                                          3. table-layout пробовал — без разницы, потому в конечном итоге убрал.
                                                                                                          4. Т.е. вы предлагаете в гриде, сначала посчитать высоту таблицы?

                                                                                                          И кстати в статья я не ставил задачу сделать, чтобы таблицы были одинаковыми с дивами (дивы там для наглядности, в чем отличия блочной модели). Цель была одна, чтобы таблица у которой заданы размеры ячеек и их границы, выводились одинаково во всех браузерах. Так как в гриде мы не знаем размеров таблицы, туда загружаются разные данные, и самостоятельно считать размеры таблицы как-то тоже попахивает костылями.
                                                                                                        • 0
                                                                                                          Я просто оставлю это здесь. :)

                                                                                                          usabili.ru/news/2012/01/25/silly_bug_hunting.html
                                                                                                          • 0
                                                                                                            Чел походу не особо вчитывался о чем статья. Ключевая тема в том, что один и тот же код браузеры выводят по-разному.
                                                                                                            Ему бросился в глаза баг firefox (и типа от того что это баг старый должно стать легче), а его не смутило, что хром показывает тоже неправильно, причем посвоему неправильно?
                                                                                                            А что касается атрибута cellspacing, это называется найти к чему приколупаться, наверное если бы я там тег B использовал в примере, то наверняка автор кричал бы, что нужно STRONG использовать.
                                                                                                            • НЛО прилетело и опубликовало эту надпись здесь

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