Фон История начинается с одного древнего проекта с веб-интерфейсом, написанного под IE5-6. Разумеется, этот мамонт в новых версиях IE работает только в режиме совместимости; под другими браузерами его даже сложно рендерить, а о производительности можно и не мечтать.
В один ясный день с небес послышался голос начать постепенно переписывать всё это на современные браузеры и работа закипела.
Система на 99% состояла из регистров в виде таблиц и бланков отдельной карточки из этого регистра.
Заголовок таблицы должен быть фиксированным.
В старой версии это делалось с помощью каких-то специфических позиционных костылей, которые уже не работали в IE7. jQuery уже был подключен, плагин для фиксированного заголовка таблицы легко гуглится.
Не поддерживает заголовки с несколькими строками и различными комбинациями столбцов и диапазонов строк? Ну да ладно, можно немного поработать самому, всё равно зайти в код плагина и адаптировать его под конкретную обёртку таблицы.
Казалось бы, всё было хорошо, но время от времени стали появляться артефакты в виде столбиков, сползающих на 1 пиксель, местами сдвиг пропадал или накапливался до 3-4 пикселей.
Более того, в Chrome этот глюк не наблюдался.
Тщетные попытки исправить ситуацию
Артефакт появлялся или отсутствовал случайным образом в различных таблицах, а также зависел от ширины окна браузера.Ни один столбец таблицы не имеет явно заданной ширины.
Поэтому первое, что пришло на ум, это различия в ширине исходной таблицы и новой таблицы с фиксированным заголовком.
Поигравшись с шириной, я ничего не смог настроить; если в одном месте таблица отображалась правильно, то там, где она отображалась нормально, она начинала ломаться.
Так что дело не в ширине.
Второе, что я решил попробовать, — это поиграть с правильным отступом для полосы прокрутки.
Я прибавил и убавил к ширине 1 пиксель, полностью убрав этот отступ.
В итоге результат оказался таким же, как и в первой попытке.
Далее я решил проверить ширину столбцов после рисования и форматирования таблицы заголовков.
Внезапно где-то была ошибка в разметке и ширина таблицы могла измениться после рендеринга нового элемента, но значения ширины до и после оказались одинаковыми.
Никакие хитрости со стилями типа border-box и display тоже не дали желаемого результата — таблицы все равно были разные.
Скандалы, интриги и расследования
В полном отчаянии я взял в руки калькулятор, открыл firebug и начал складывать ширину каждого столбца, пытаясь найти, куда именно таблица начала уходить.И.
поджигатель сказал, что они все имеют одинаковую ширину! Как же так? Они даже визуально разные.
Может ли быть проблема с Firebug на вкладке разметки объекта? Смотрю в DOM — в clientWidth такое же значение, встроенный инспектор в FF выдаёт аналогичные значения.
Глаз обмануть можно и можно, но краска вряд ли.
Копирую скриншот окна браузера в редактор и начинаю считать ширину столбцов.
Я добираюсь до первого изогнутого столбца, и краска дает ширину на 1 пиксель меньше, чем говорит браузер! Я возвращаюсь на страницу.
Все браузерные инструменты и jQuery мамой клянутся, что ширина столбца 473 пикселя, но Paint твердо настаивает, что на самом деле она 472. Сразу вспомнился монолог Задорнова про приклеенную посередине рулетку.
Неужели тещи добрались до разработчиков? Кстати, в IE ситуация в точности повторяла то, что происходило в FF. ЗАГОВОР?
Следующий час я провожу в Google, пытаясь найти существующие ошибки при вычислении ширины столбцов или некоторых функциях clientWidth или функции .
width().
И безрезультатно.
Все, что можно найти, это либо дробные значения в CSS, либо явные ошибки авторов разметки.
Напился (с) Должен быть способ узнать правильную ширину столбца, каким-то образом таблица отрисовывается браузером и ничего никуда не пролезает. Ничего не остается, как перебирать возможные различия в свойствах ячеек.
Я извлекаю свойства столбца из DOM исходной таблицы и свойств, сгенерированных плагином.
Я сравниваю.
Кажется, все совпадает. кроме offsetLeft. Как же так? Вставляем костыль с расчетом ширины исходя из смещения; для последней ячейки мы будем использовать обычную ширину:
И теперь таблицы одинаковы во всех моих браузерах.this.nextSibling.offsetLeft - this.offsetLeft = 472
Что происходит
Макет таблицы не содержит ширины столбцов, и браузер автоматически регулирует ширину столбцов в зависимости от содержимого таблицы.Где-то рассчитанное значение ширины оказывается дробным, и здесь, видимо, начинаются проблемы с реализацией.
Поскольку дробную ширину невозможно отобразить, значение округляется, и это округленное значение подставляется в DOM. При определенных соотношениях могут накапливаться ошибки округления, а общая ширина таблицы будет увеличиваться или уменьшаться.
Согласно статье habrahabr.ru/post/31392 затем FF пытается подогнать содержимое точно под размер родителя и уменьшает значения некоторых столбцов на 1 пиксель, чтобы они не превышали ширину таблицы, offsetLeft меняется для смещенных столбцов, а clientWidth — нет! Поэтому при попытке создать копию заголовка таблицы скрипт возвращает не уменьшенную (или увеличенную) ширину не на 1 пиксель, а столбцы раздвинуты.
Я не вижу другого варианта.
В IE ситуация аналогичная, только там инспектор показывает дробное значение ширины столбца, clientWidth имеет округленное значение, но рендеринг всё равно на 1 пиксель меньше.
Тот же диагноз, только инспектор не врёт.
Чтобы исключить ситуацию, что в верстке страницы есть какая-то ошибка, попробуем воспроизвести ошибку в тепличных условиях: Скрытый текст <!DOCTYPE html>
<html>
<head>
<script src="calc/jquery.js"></script>
<script>
$(document).
ready(function(){ $(window).
resize(function() { $('#tr > *').
each(function() { var width1 = this.clientWidth; var width2; if ($(this).
next('td').
length) { width2 = $(this).
next('td')[0].
offsetLeft - this.offsetLeft;
}
console.log(width1, width2);
});
});
});
</script>
</head>
<body>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr id="tr">
<td>1234556</td>
<td>123455644</td>
<td>12345</td>
<td>12345565645</td>
<td>123455643</td>
<td>12345563453433</td>
<td>12345565645</td>
<td>123455643</td>
<td>12345563453433</td>
</tr>
</table>
</body>
</html>
И действительно, в ФФ, когда я меняю ширину окна, ширина1 и ширина2 иногда отличаются на 1 пиксель.
Причем разница может быть как больше, так и меньше, что исключает использование разных методов округления при заполнении DOM и при рендеринге страницы, но на самом деле проблема где-то на этапе «сжатия» столбцов таблицы.
Конечно, расположение элементов с дробной шириной или высотой — задача нетривиальная и решается по-разному, но несоответствие ширины, указанной в DOM, и реальной на странице я считаю непростительным.
Может быть я ошибаюсь в данной ситуации и не надо создавать баг-репорт? Такое поведение вполне ожидаемо и в моем случае мне нужно использовать такой костыль, чтобы правильно выровнять ширину столбцов? Я хотел бы услышать ваше мнение.
Теги: #Firefox #ошибки #верстка #разработка сайта
-
Народный Переезд В Юкоз Начался
19 Oct, 24 -
Субстики №139
19 Oct, 24 -
5 Демонов В Душе Сотрудницы Службы Поддержки
19 Oct, 24 -
Как Порадовать Невесту Программиста
19 Oct, 24 -
«Финам» Вложит В Ит Еще 150 Млн Руб.
19 Oct, 24