Как исправить несогласованный рендеринг смежных границ TD, когда они свернуты?
У меня есть HTML-таблица со свернутыми и смежными границами и стандартной границей для всех ячеек, и я хочу изменить цвет границы определенной строки на что-то другое. Проблема в том, что когда границы свернуты, а соседние ячейки имеют разные цвета (или, как я полагаю, стили), браузер не визуализирует визуально приемлемым способом.
Вот мой HTML:
<table>
<tr><td>Lorem</td><td>Ipsum</td></tr>
<tr><td>Lorem</td><td>Ipsum</td></tr>
<tr id="foo"><td>The border of these cells</td>
<td>is not uniformly red!</td></tr>
<tr><td>Lorem</td><td>Ipsum</td></tr>
</table>
CSS:
table { border-collapse: collapse; border-spacing: 0 }
td { padding: 5px; border: 3px black solid; }
#foo td { border: 3px red solid; }
Существует также JSFiddle из вышеперечисленного.
Как это делают разные браузеры:
IE 7 (стандарты):
IE 8 и 9 (стандарты):
Firefox 11 (обратите внимание на тонкий визуальный артефакт на левой красной границе и причудливый способ визуализации углов):
Chrome 18:
Вопрос: что я могу сделать, чтобы получить визуально приемлемый рендер? Может ли это быть идеалом "красные границы всегда имеют приоритет над черными"?
Разъяснение:
Я в первую очередь ищу чистое решение CSS.
Если это невозможно, я бы работал с чем-то, что требует небольших и локализованных модификаций (то есть не то, что я должен был бы делать на каждой таблице везде).
Javascript является приемлемым, поскольку на реальном веб-сайте стили, которые управляют границами, применяются динамически в зависимости от взаимодействия с пользователем. Обработчики событий устанавливаются кодом, практически идентичным этому.
2 ответа
Я пришел к этому решению без лишней разметки: http://jsfiddle.net/fcalderan/PAJzK/12/
идея состоит в том, чтобы избежать использования border-collapse
и используя границу top/right
для ячеек таблицы и границы bottom-left
для элемента таблицы.
пробовал с IE8, FX11 и CH17, вот соответствующий CSS
table {
border-spacing : 0;
border-left : 3px black solid;
border-bottom : 3px black solid;
}
td {
padding : 5px;
border-right : 3px black solid;
border-top : 3px black solid;
}
#foo td { border-color:red; }
/* border left red-coloured using :before pseudoelement */
#foo td:first-child:before {
content : "";
position : relative;
margin-left : -8px;
padding : 8px 0 8px 5px;
border-left : 3px red solid;
}
/* top border of next rows red coloured */
#foo + tr td {
border-top: 3px red solid;
}
здесь возникает проблема, если выделенная строка является последней: в этом случае #foo + tr td
не будет ничего соответствовать: в этом случае вы можете написать вместо этого правила
#foo td:after {
content : "";
position : relative;
margin : 0 0 0 -8px;
display : block;
width : 100%;
height : 3px;
padding : 0 8px;
top : 2px;
margin-bottom : -6px;
border-bottom : 3px red solid;
}
см. пример в http://jsfiddle.net/fcalderan/PAJzK/14/
Вам нужна дополнительная разметка, например настройка id=before-foo
в предыдущем ряду и id=after-foo
на следующем, с добавлением таблицы стилей, как
#before-foo td {
border-bottom-color: red; }
#after-foo td {
border-top-color: red; }
Демо: http://jsfiddle.net/8C8Rd/
Могут быть проблемы на углах ячейки (угол может быть черным).
Причина, по которой это не может быть сделано более простым способом, заключается в том, что эффект коллапса границы был неопределенно определен и непоследовательно реализован в браузерах. Черновики CSS 2.1 даже используются, чтобы оставить цвет в ситуациях, подобных этому зависящему от браузера. Несмотря на то, что окончательная спецификация CSS 2.1 имеет требования к этому в своих правилах разрешения конфликтов границ, они не реализованы повсеместно - и в этом случае они говорят, что граница ячеек верхнего ряда выигрывает (как в большинстве протестированных вами браузеров), поэтому нет прямого способа указать рендеринг, который вы описываете. То есть, вам все равно нужно будет установить некоторые стили в предыдущем ряду.