微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

html – 防止div扩展父表的宽度

我正在开发一个项目,我将把标记注入我无法控制的页面(嵌入脚本).一个有趣的案例出现了,我的注入div包含在一个表中.我的div的子节点是一个水平菜单,当它超出父元素的宽度时应该滚动(overflow-x:auto),但是如果父元素是没有table-layout的表:fixed,我注入的内容而是导致父表扩展,可怕地打破一些布局.

在这种情况下,表包含在固定宽度的div中,如下所示:

<div style="width: 600px;">
  <table width="100%">
    <tr>
      <td>
        <div> <!-- my content --> </div>
      </td>
    </tr>
  </table>
</div>

我发现在表上设置table-layout:fixed修复了这个问题.但是,这个标记是我无法控制的 – 我只能从最里面的div开始更改标记/ CSS.

我找到了一个有效的黑客:设置宽度:100%;显示:表; table-layout:fixed;在我的div.但是,我不确定这是否符合任何相关的规范,因为这个显示内容:table div都是display:block.

这是标记,重现问题,并演示黑客:

<div class="outer">
  <table class="bad-table">
    <tr>
      <td>
        <div class="wrapper">
          <div>Lorem ipsum dolor sit amet,consectetur adipiscing elit. Aliquam imperdiet pharetra nunc at condimentum.</div>
          <div class="target">
            <ul class="menu">
              <li style="background-color: #800;"></li>
              <li style="background-color: #880;"></li>
              <li style="background-color: #080;"></li>
              <li style="background-color: #008;"></li>
            </ul>
          </div>
          <div>Lorem ipsum dolor sit amet,consectetur adipiscing elit. Aliquam imperdiet pharetra nunc at condimentum.</div>
        </div>
      </td>
    </tr>
  </table>
</div>

<div class="outer">
  <table class="bad-table">
    <tr>
      <td>
        <div class="wrapper hack">
          <div>Lorem ipsum dolor sit amet,consectetur adipiscing elit. Aliquam imperdiet pharetra nunc at condimentum.</div>
        </div>
      </td>
    </tr>
  </table>
</div>

CSS:

.outer {
  width: 200px;
  border: 1px solid #0f0;
}

.bad-table {
  width: 100%;
  border: 1px solid #f00;
}

.target {
  width: 100%;
  overflow-x: auto;
  overflow-y: hidden;
}

.wrapper {
  width: 100%;
}

.wrapper.hack {
  display: table;
  table-layout: fixed;
}

ul.menu {
  list-style: none;
  padding: 0;
  margin: 0;
  white-space: Nowrap;
  width: 100%;
}

ul.menu li {
  display: inline-block;
  width: 100px;
  height: 50px;
  padding: 0;
  margin: 0;
}

(Fiddle)

请注意,在第一个示例中,菜单块会导致表格(红色边框)扩展到其包含的div(绿色边框)之外.与第二个示例相比,它使用我的(违反标准的?)hack成功阻止父表增长,同时还允许滚动菜单块. (经过Chrome和Firefox测试.)

请注意以下约束:

>我绝对无法编辑注入div之外的标记.这包括在我注入的div之外操作DOM,因为我不知道我对其他人的文档的更改可能导致什么不良影响.
>我注入的div的高度应该基于其内容(按照正常的文档流程),这意味着使用position:absolute的解决方案往往会有问题,因为它们会从页面流中删除我的内容,使之前和/或之后内容重叠注入的div.通常的解决方法(设置固定高度)意味着我的元素将无法适应其高度以匹配其内容.

这种黑客是解决这个问题的合法方式,还是有更好的方法

解决方法

桌子总是很棘手,但是我使用了位置:在很多情况下绝对成功,所以我的答案/问题是:这对你有用吗?

请注意,包装器只是一个包装器,应该只包含目标,因此所有内容都会进入目标,否则目标将与其兄弟重叠,除非设置了固定的边距/填充.

.outer {
  width: 200px;
}

.bad-table {
  width: 100%;
}

.wrapper {
  position: relative;
}
.target {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: auto;
  overflow: auto;
}

ul.menu {
  list-style: none;
  table-layout: fixed;
  padding: 0;
  margin: 0;
  white-space: Nowrap;
  width: 100%;
}
ul.menu li {
  display: inline-block;
  width: 100px;
  height: 50px;
  padding: 0;
  margin: 0;
}
<div class="outer">
  <table class="bad-table">
    <tr>
      <td>
        <div class="wrapper">
          <div class="target">
          
          
            <div>Lorem ipsum dolor sit amet,consectetur adipiscing elit. Aliquam imperdiet pharetra nunc at condimentum.</div>
            <ul class="menu">
              <li style="background-color: #800;"></li>
              <li style="background-color: #880;"></li>
              <li style="background-color: #080;"></li>
              <li style="background-color: #008;"></li>
            </ul>
            <div>Lorem ipsum dolor sit amet,consectetur adipiscing elit. Aliquam imperdiet pharetra nunc at condimentum.</div>


          </div>
        </div>
      </td>
    </tr>
  </table>
</div>

为了比较,这里是使用display:table的相同代码片段

.outer {
  width: 200px;
}

.bad-table {
  width: 100%;
}

.wrapper {
  width: 100%;
  display: table;
  table-layout: fixed;
}
.target {
  overflow: auto;
}

ul.menu {
  list-style: none;
  table-layout: fixed;
  padding: 0;
  margin: 0;
  white-space: Nowrap;
  width: 100%;
}
ul.menu li {
  display: inline-block;
  width: 100px;
  height: 50px;
  padding: 0;
  margin: 0;
}
<div class="outer">
  <table class="bad-table">
    <tr>
      <td>
        <div class="wrapper">
          <div class="target">
          
          
            <div>Lorem ipsum dolor sit amet,consectetur adipiscing elit. Aliquam imperdiet pharetra nunc at condimentum.</div>


          </div>
        </div>
      </td>
    </tr>
  </table>
</div>

更新

经过一些更多的测试,并阅读这些,

> https://www.w3.org/TR/CSS2/tables.html#anonymous-boxes
> Is a DIV inside a TD a bad idea?

我找不到任何其他方法解决这种情况,所以如果你的内容div的内容需要具有正常流量的不受控制的外部div / table之前和之后的内容,position:absolute可能不起作用取决于页面的其余部分已设置,但显示:table; table-layout:固定会.

根据以上消息来源,使用display:table1应该没有任何合规性问题,虽然你需要测试主要浏览器中的行为,因为它们都可以处理div内部td的不同(我测试过Chrome,FF,Edge,Windows上的IE11,全部工作).

1具体来说,这个文本允许直接在display:table元素内部显示:block元素,因为中间的table-row和table-cell框会自动创建为匿名:

  1. Generate missing child wrappers:
    1. If a child C of a ‘table’ or ‘inline-table’ Box is not a proper table child,then generate an anonymous ‘table-row’ Box around C and all consecutive siblings of C that are not proper table children.
    2. If a child C of a row group Box is not a ‘table-row’ Box,then generate an anonymous ‘table-row’ Box around C and all consecutive siblings of C that are not ‘table-row’ Boxes.
    3. If a child C of a ‘table-row’ Box is not a ‘table-cell’,then generate an anonymous ‘table-cell’ Box around C and all consecutive siblings of C that are not ‘table-cell’ Boxes.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐