我正在开发一个项目,我将把标记注入到我无法控制的页面(嵌入脚本)中。出现了一个有趣的情况,我注入的 div 包含在表中。overflow-x: auto我的 div 的子级是一个水平菜单,当它超过父元素的宽度时,应该滚动 ( ) ,但在父元素是没有 的 table-layout: fixed表格的情况下,我注入的内容反而会导致父表格展开,严重破坏一些布局。
在本例中,表格包含在固定宽度的 div 中,如下所示:
<div style="width: 600px;">
<table width="100%">
<tr>
<td>
<div> <!-- my content --> </div>
</td>
</tr>
</table>
</div>
Run Code Online (Sandbox Code Playgroud)
我发现table-layout: fixed桌子上的设置可以解决这个问题。然而,这个标记超出了我的控制范围——我只能从最里面的 div 开始更改标记/CSS。
我确实找到了一种有效的方法:width: 100%; display: table; table-layout: fixed;在我的 div 上进行设置。但是,我不确定这是否符合任何相关规范,因为该display: tablediv 的内容都是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 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>
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
(小提琴)
请注意,在第一个示例中,菜单块导致表格(红色边框)扩展到其包含的 div(绿色边框)之外。与第二个示例相比,第二个示例使用我的(违反标准?)黑客成功阻止父表增长,同时还允许滚动菜单块。(使用 Chrome 和 Firefox 进行测试。)
请注意以下限制:
position: absolute往往会出现问题,因为它们将从页面流中删除我的内容,使前面和/或后面的内容与注入的内容重叠分区 通常的修复方法(设置固定高度)意味着我的元素将无法调整其高度以匹配其内容。这个黑客是解决这个问题的合法方法,还是有更好的方法?
table总是很棘手,但我position: absolute在很多情况下都成功使用过,所以我的答案/问题是:这对你有用吗?
但请注意,wrapper仅仅是一个包装器,应该只包含target,因此所有内容都会进入target,否则target将会与其同级内容重叠,除非设置了固定的边距/填充。
.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;
}Run Code Online (Sandbox Code Playgroud)
<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>Run Code Online (Sandbox Code Playgroud)
为了进行比较,这里是使用相同的代码片段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;
}Run Code Online (Sandbox Code Playgroud)
<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>Run Code Online (Sandbox Code Playgroud)
更新
经过更多测试并阅读这些内容后,
我找不到任何其他方法来解决这种情况,因此,如果在不受控制的外部 div/table之前和之后存在内容,而您的内容 div的内容需要具有正常的流程,position: absolute则可能无法工作,具体取决于其余部分的方式页面内容的一部分已设置,但display: table; table-layout: fixed将会。
根据上述来源,使用display: table1不应该出现任何合规性问题,尽管您需要测试主要浏览器中的行为,因为它们都可能处理div's insidetd的不同(我确实测试了 Chrome,FF, Edge、Windows 上的 IE11,全部有效)。
1具体来说,此文本允许display: block元素直接位于元素内部display: table,因为中间表格行和表格单元格框会自动创建为匿名:
- 生成缺失的子包装器:
- 如果“table”或“inline-table”框的子 C 不是正确的表子项,则在 C 周围以及 C 的所有不是正确的表子项的连续兄弟项生成一个匿名“table-row”框。
- 如果行组框的子 C 不是“表行”框,则在 C 周围以及 C 的所有不是“表行”框的连续同级框生成匿名“表行”框。
- 如果“table-row”框的子 C 不是“table-cell”,则在 C 周围以及 C 的所有不是“table-cell”框的连续同级框生成一个匿名“table-cell”框。
| 归档时间: |
|
| 查看次数: |
4189 次 |
| 最近记录: |