:之前伪元素导致边界间隙

时间:2013-09-13 22:12:03

标签: css border

我想要这个HTML格式。 html是一个表(和实际表),我想给它一个边框。 该元素还有一个:before伪元素,我用它在顶角放一个小三角形。

JSFiddle就在这里。 我希望这是有道理的。我尽可能地删除了标记和CSS,因为它实际上是一个大网站的一小部分。

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

现在的问题是,在表上有border-collapse: collapse;的2列和: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;时它会起作用,但我不确定这是一个正确的解决方案,即使它是,我真的想要解释发生了什么。

顺便说一下。我在Chrome 29和Internet Explorer 10中都遇到了这个问题。还没有测试过其他浏览器。

更新

我没有使用-or 而不是使用''border-collapse'来解决问题,而是发现这也有效:

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

所以表本身仍然是一个表,伪元素仍然在桌子上,边框,定位等等。之前没有样式的tbody现在是一个块,并且问题在两个浏览器中都得到了解决。我通过反复试验找到了这个,但仍然不知道背后的原因。

更新了小提琴:http://jsfiddle.net/GolezTrol/28yDb/9/

3 个答案:

答案 0 :(得分:2)

成为StackOverflow的新手 jsFiddle我updated the Fiddle我认为是解决方案。除了将伪类从表本身移动到表头,并将其更改为:after之后,我没有更改CSS。适用于Firefox和Chrome!

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

边界崩溃:IE8不支持单独但我认为这将是。

  • 编辑:nevermind;)

答案 1 :(得分:0)

这个问题只发生在我认为的Webkit浏览器上。它可以被视为“浏览器错误”imo。

应该在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>

我认为这是正确的解决方案。您正在放置一个不建议使用的元素,因此发生问题应该是正常的。

编辑:正如thirtydot指出的那样,将th更改为td不会改变结果。它只有在我移动到thead部分时才有效。在这一点上我不知所措,我找不到解决这个问题的方法。

但至少我认为我可以提出我对这个问题的原因的猜测: :在target元素内创建一个伪元素之前。我不知道什么样的元素,但我怀疑浏览器创建了一个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个边框合并在一起,其中有2个单元格彼此相邻,或者单元格位于表格的边框旁边。所以我怀疑在这种情况下,伪元素 - 没有合适的colspan - 只持续1列,该行的其余部分为空:没有任何东西。这是我认为导致错误的地方:因为那里的表边框旁边没有单元格,所以根本没有创建边框。

真正的原因可能有点复杂(“当我放入thead时,为什么不会发生错误?”),但我认为我的回答并没有太远。 :)

答案 2 :(得分:0)

我能想到的唯一合理解释是pseudo-element :beforedisplay: table模式中table的{​​{1}}不兼容。这就是collapsed解决问题的原因。突然,浏览器可以显示顶部边框,而不是关心伪元素。

如果仔细观察,可以清楚地看到边框的缺失部分是第二列的宽度。如果将其更改为border-collapse: separate;伪元素,则右下角缺少边框,这是因为表格的边框和伪元素已折叠。

如果您在after模式下将border-bottom的{​​{1}}更改为th,则3px solid red会覆盖collapsed并且边框为红色。我认为,thtable的力量遵循相同的规则。如果知道规格的人能够更好地回答这个问题,那就太好了。

以这种方式思考,我认为不存在任何其他解决方案:

  • 使用单独的边框
  • 将伪元素放在父after

我检查的是before实际上呈现为div,可以更改为pseudo elementblock。但是,这些都不会改变行为。


非常随机的东西,实际上符合Av Avt关于在DOM中呈现伪元素的位置的答案。

如果我像这样附加table,边框会停留:

list-item

显然,它会创建与行数一样多的新伪元素。