【问题标题】:IE :before/:after 100% height issues on tdIE :before/:after td 100% 高度问题
【发布时间】:2015-03-10 19:07:20
【问题描述】:

有没有人知道如何使用 td 上的 :before/:after 高度来修复(明显的)IE 渲染错误?

从外观上看,IE 似乎只认为 :before/:after 伪元素与它内部的父级 <TD> 内容一样高。如果<TD> #1 是 x2 行高 w 内容,<TD> #2 只有 x1 行内容,IE 将仅渲染 <TD> #2 的 :before/:after 高度与 x1 行的值一样高内容。

我在这里创建了一个小提琴示例以更好地说明我的问题:http://jsfiddle.net/231gnfpz/ 注意:我为 :before/:after 添加了红色背景,以更好地帮助我在 IE 中可视化我的问题

在我的示例中,我有一个中间 <TD>,我应用了一个 :before/:after 来尝试在特定列的外部创建一个盒子阴影。它是一个旧项目,所以我无权重写整个表格,FireFox/Chrome 似乎对此没有问题,IE8-11 似乎与我的 :before/:after 有同样的问题 height:100% .

代码:

table {
  background: grey;
  width: 100%;
}
table td {
  text-align: center;
  vertical-align: top;
  background: white;
  padding: 4px;
  width: 33.33%;
  position: relative;
}
.testTD:before {
  box-shadow: -15px 0 15px -15px grey inset;
  content: " ";
  height: 100%;
  left: -15px;
  position: absolute;
  top: 0;
  width: 15px;
  background: Red;
}
.testTD:after {
  z-index: 1;
  box-shadow: 15px 0 15px -15px grey inset;
  content: " ";
  height: 100%;
  right: -15px;
  position: absolute;
  top: 0;
  width: 15px;
  background: Red;
}
<table cellspacing="1" cellpadding "0" border="0">
  <tr>
    <td>test1</td>
    <td class="testTD">test1</td>
    <td>test1</td>
  </tr>
  <tr>
    <td>test2
      <br/>test2
    </td>
    <td class="testTD">test2</td>
    <td>test2</td>
  </tr>
  <tr>
    <td>test3
      <br/>test3
      <br/>test3
    </td>
    <td class="testTD">test3</td>
    <td>test3</td>
  </tr>
</table>

【问题讨论】:

    标签: css internet-explorer


    【解决方案1】:

    已解决: 此问题已在 Windows 10 上 Internet Explorer 的当前预览版本中得到解决。您目前可以通过http://remote.modern.ie 在 Windows 或 Mac OS X 上进行测试。如果您需要 IE 11(及更低版本)支持,则后续解决方案应该仍能满足您的需求。

    一般来说,表格单元格的尺寸很大程度上取决于其内容。在这种情况下,我们可以看到伪元素与共享单元格容器中的相邻内容一样高。这就是 Internet Explorer 理解 100% 的意思。

    您的伪元素是绝对定位的,并受相对定位的表格单元格的约束。很自然地,我们希望伪元素与约束元素一样高,而不是其相邻内容的高度。 Internet Explorer 似乎在这里判断错误。

    如果您希望在所有浏览器中使用相同的演示文稿,我建议进行以下更改:

    1. 此处避免使用伪元素,而是使用实际元素(见下文)
    2. 循环遍历您的元素,将它们调整为父元素的offsetHeight

    所以你的标记应该是这样的:

    <td class="testTD">
        <span class="bar"></span>
        <!-- content -->
        <span class="bar"></span>
    </td>
    

    然后,您可以像原来的伪元素一样设置它们的样式:

    .testTD .bar:first-child,
    .testTD .bar:last-child {
        display: block;
        background: #F00;
        width: 15px; height: 100%;
        position: absolute; top: 0; z-index: 1;
        box-shadow: -15px 0 15px -15px grey inset;
    }
    
    .testTD .bar:first-child {
        left: -15px;
    }
    
    .testTD .bar:last-child {
        right: -15px;
    }
    

    在 Chrome 和 Firefox 中,您已经设置好了。你不需要做任何进一步的事情。但是,在 Internet Explorer 中,您需要手动设置这些元素的高度。出于这个原因,我们将以document 对象上存在documentMode 属性为条件来编写以下脚本:

    (function () {
    
      "use strict";
    
      if ( document.documentMode && document.documentMode < 12 ) {
          var spans = document.querySelectorAll( "span.bar" ),
              count = spans.length;
          while ( count-- ) {
              spans[count].style.height = spans[count].parentElement.offsetHeight + "px";
          }
      }
    
    }());
    

    end-result 应该在所有主流浏览器中保持一致。

    我将在内部以互操作为由提交一个错误。如果 Chrome 和 Firefox 以一种方式运行,而 Internet Explorer 以另一种方式运行,我们的团队应该考虑出现这种情况的原因。我会将此问题添加到我打开的工单中,并确保在必要时更新此答案。

    更新以下 cmets 中的讨论

    在 cmets 中指出,在这种特殊情况下无法更改原始标记。脚本在此处被正确识别为可能的解决方案。

    (function () {
    
        "use strict";
    
        // Get target cells, and create clone-able span element
        var tds = document.querySelectorAll( ".testTD" ),
            span = document.createElement( "span" );
            span.className = "bar";
    
        // Cycle over every matched <td>
        for ( var i = 0; i < tds.length; i++ ) {
    
            // Create references to current <td>, and a(fter)/b(efore) clones
            var t = tds[i], a = span.cloneNode(), b = span.cloneNode();
    
            // Insert cloned elements before/after <td> content
            t.appendChild( a );
            t.insertBefore( b, t.firstChild );
    
            // If the user is in Internet Explorer, avoid table-cell height bug
            if ( document.documentMode && document.documentMode < 12 ) {
                a.style.height = b.style.height = t.getBoundingClientRect().height + "px";
            }
    
        }
    
    }());
    

    如果你使用 jQuery,这可以写得更简洁:

    (function () {
    
        "use strict";
    
        // Create our clone-able element
        var span = $("<span></span>").addClass("bar");
    
        // Add cloned <span> elements at beginning/end of all .testTD cells
        $(".testTD").prepend( span.clone() ).append( span.clone() );
    
        // If the user is in Internet Explorer, avoid table-cell height bug
        if ( document.documentMode && document.documentMode < 12 ) {
            $(".testTD .bar").height(function () {
                return $(this).parent().outerHeight();
            });
        }
    
    }());
    

    【讨论】:

    • hmm 有趣的想法,我可能可以使用 jQuery 来创建跨度标签,因为我无法再将它们物理添加到这个旧项目中。感谢@Jonathan Sampson 的想法,非常感谢!
    • jQuery 也可以。如果此答案解决了您的问题,请考虑相应地投票/接受。
    • @user4447070 我很高兴地宣布我们发现了这个问题,并且已经从我们这边解决了这个问题。您可以通过remote.modern.ie 测试我们的 IE 预览版。
    • 猜我还没有足够的代表来投票/接受你的回答,所以我想我只需要给你一个“谢谢!”
    • 遇到了同样的问题,通过简单的“height: 999em”伪元素和“overflow: hidden”为表格单元格解决了这个问题(由于 CSS 媒体黑客,仅适用于 IE)。对我有帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-24
    • 2011-10-03
    • 2017-10-19
    • 2011-09-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多