: перед псевдоэлементом возникает разрыв на границе

У меня есть эта часть HTML, которую я хочу стилизовать. Html - таблица (и фактическая таблица), которую я хочу предоставить. Элемент также имел: перед псевдоэлементом, который я использую, чтобы поместить маленький треугольник в верхний угол.

JSFiddle здесь. Надеюсь, это имеет смысл. Я урезал разметку и CSS как можно больше, потому что это фактически небольшая часть большого сайта.

http://jsfiddle.net/GolezTrol/28yDb/2/

Теперь проблема состоит в том, что комбинация из 2 столбцов, имеющих border-collapse: collapse; в таблице и псевдо-элемент :before, приводит к тому, что верхняя граница элемента частично исчезает. Это только там для длины первого столбца.

Вы могли бы предположить, что это псевдоэлемент, расположенный поверх границы, но этот элемент очень мал, и, насколько я могу судить, это не может быть проблемой. Я добавил visibility: hidden; в псевдоэлемент, и я могу сказать, что треугольник ушел, но граница все еще неполна.

К сожалению, я не могу изменить разметку, так как это выводится MediaWiki, но у меня есть полный контроль над CSS.

HTML:

<div id="globalWrapper">
<div id="column-content">
<div class="thumb tright">
<table class="infobox vcard" style="">
    <tbody>
        <tr>
            <th colspan="2" class="fn org" style=""> Example text</th>
        </tr>
        <tr>
            <th>Row head</th>
            <td>Content</td>
        </tr>

CSS:

/* Generic table styling */
table {
  border-collapse: collapse;
  /*border-spacing: 0;*/ }

/* The box */
.thumb.tright table.infobox.vcard {
    border: 3px solid #fae104;
    position: relative;
}

/* Triangle */
  .thumb.tright table.infobox.vcard:before {
    content: "";
    position: absolute;
    width: 0;
    height: 1px;
    border-top: 5px solid transparent;
    top: -7px;
    border-left: 10px solid #555;
    visibility: hidden;
    right: -1px; }

Я уже выяснил, что он работает, когда я удаляю border-collapse: collapse;, но я не уверен, что это правильное решение, и даже если это так, мне очень хотелось бы объяснить, что происходит.

Btw. Я столкнулся с этой проблемой как в Chrome 29, так и в Internet Explorer 10. Не тестировали другие браузеры.

Update

Вместо того, чтобы использовать -или не использовать- "border-collapse", чтобы исправить проблему, я обнаружил, что это также работает:

.thumb.tright table.infobox.vcard tbody {
    display: block;
}

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

Обновлен скрипт: http://jsfiddle.net/GolezTrol/28yDb/9/

Ответ 1

Будучи новичком в StackOverflow и jsFiddle я обновил Fiddle, я думаю, это решение. Я не изменил CSS, за исключением того, что переместил псевдокласс из самой таблицы в заголовок таблицы и изменил его на: after. Работает для меня в Firefox и Chrome!

/* Triangle */ 
.thumb.tright table.infobox.vcard th:after { }

Пограничный сбой: отдельный не поддерживается в IE8, но я думаю, что это будет.

  • изменить: nevermind;)

Ответ 2

Это проблема, которая возникает только в браузерах Webkit, я думаю. Его можно считать "ошибкой браузера" imo.

th должен находиться внутри thead, а не tbody:

<thead>
        <tr>
            <th colspan="2" class="fn org" style=""> Example text</th>
        </tr>
</thead>
<tbody>
        <tr>
            <th>Row head</th>
            <td>Content</td>
        </tr>
<tbody>

И я думаю, что это правильное решение. Вы помещаете элемент, где это не рекомендуется, так что это должно быть нормально для возникновения проблемы.

Изменить: как указано выше, изменение th на td не изменяет результат. Он работает только тогда, когда я переместил th в раздел thead. На данный момент я в недоумении, я не могу найти способ решить эту проблему.

Но, по крайней мере, я думаю, что могу рассказать о причине этой проблемы: : перед созданием псевдоэлемента внутри целевого элемента. Какой элемент мне неизвестен, но я подозреваю, что браузер создал td. Если это так, то после рендеринга ваш html должен выглядеть так:

<table>
       <td></td> /*the pseudo element*/
       <tbody>
                <tr>
                    <th colspan="2" class="fn org" style=""> Example text</th>
                </tr>
                <tr>
                    <th>Row head</th>
                    <td>Content</td>
                </tr>
        <tbody>
</table>

Излишне говорить, что этот взгляд странный. И если вы попробуете вышеуказанный html-выход, вы увидите, что результат похож на вашу проблему. border-collapse: collapse объединит 2 границы вместе, где есть две ячейки рядом друг с другом, или ячейка находится рядом с границей таблицы. Поэтому я подозреваю, что в этом случае псевдоэлемент, который не имеет соответствующего столбца, содержит только один столбец, остальная часть этой строки пуста: ничего нет. Вот где я думаю, что вызвал ошибку: потому что там нет ячеек рядом с границей таблицы, никакой границы вообще не создается.

Реальная причина может быть немного сложнее ( "почему ошибка не возникает, когда я помещаю в thead?" ), но я думаю, что мой ответ не слишком далек.:)

Ответ 3

Единственное разумное объяснение, о котором я могу думать, pseudo-element :before несовместимо с display: table режима table в collapsed. Вот почему border-collapse: separate; решает проблему. Внезапно браузер может отображать верхнюю границу, не заботясь о псевдоэлементе.

Если вы посмотрите внимательно, вы можете ясно видеть, что недостающая часть границы - это ширина второго столбца. Если вы измените его на after псевдоэлемент, в нижнем правом углу границы не будет, опять же из-за того, что границы таблицы и псевдоэлемента рухнули.

Если вы измените border-bottom of th на 3px solid red в режиме collapsed, th переназначает table, а рамка - красная. Я полагаю, что сила after и before соответствует тому же правилу. Было бы неплохо, если бы кто-то, кто знает спецификации, лучше ответил на это.

Размышляя таким образом, я не верю, что может быть любое другое решение, чем:

  • с использованием отдельных границ
  • установка псевдоэлемента в родительский div

Я проверял, что pseudo element фактически отображается как block и может быть изменен на table и list-item. Однако ничто из этого не меняет поведения.


Очень случайный материал, который фактически соответствует Av Avt ответу о том, где псевдоэлемент визуализируется в отношении DOM.

Если я добавлю :beofre, как это, граница останется:

.thumb.tright table.infobox.vcard tr:before

Очевидно, он создает столько новых псевдоэлементов, сколько строк.