Пользователь
9,6
рейтинг
25 января 2012 в 11:39

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

CSS*
В процессе создания новой версии своего грида на 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-сборки браузеров отписывайтесь в комментариях, как они себя ведут.
Тестовая страница здесь.
@zapimir
карма
99,2
рейтинг 9,6
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (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
    Opera 12.00 alpha (1213) — ipic.su/img/img3/fs/kiss_67kb.1327486737.png
  • +1
    Автору: На тестовой странице нижний правый пример подписан не верно, хотя на скриншотах всё в порядке… Вероятно должно быть «Box-Sizing: border-box»
    • 0
      Пасиб, поправил.
  • +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
        Хромиум виноват, видимо. Все-таки тестовый продукт.
      • 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 использовать.
      • НЛО прилетело и опубликовало эту надпись здесь

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