没有预定义高度的嵌套元素溢出



我正在构建一个网格组件,并试图让主体在内容超过外部元素的视口时触发滚动条。不幸的是,只有当在.body元素上应用高度时,我才能实现这一点。我希望避免这种情况,因为这需要我通过脚本在运行时应用高度,并且必须跟踪影响其高度的元素上的任何更改。

有什么我可以探索的,纯粹的CSS智慧来完成这件事吗?请注意,代码段中可见的滚动条是基于溢出的代码段内容,而不是基于溢出的body元素。

.outer {
overflow: hidden;
height: 500px;
}
.grid {
border: 1px solid black;
}
.headerwrap {
overflow: hidden;
border: 1px solid blue;
}
.bodywrap {
overflow: hidden;
border: 1px solid red;
}
.body {
overflow: auto;
border: 1px solid green;
/*height:300px;*/
}
<div class="outer">
<div class="grid">
<div class="headerwrap">
<div class="header">
<table border="1" style="width:2000px;">
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
<td>e</td>
<td>f</td>
</tr>
</table>
</div>
</div>
<div class="bodywrap">
<div class="body">
<table border="1" style="width:2000px;height:1000px">
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
</tr>
</table>
</div>
</div>
</div>
</div>

您可以在outer上添加overflow: scroll;,以便在内容超过y-axis的视口时进行滚动。这样,当内容超过水平视口时,也可以在x-axis上滚动。

当使用tables时,我喜欢使用body::-webkit-scrollbar添加手动滚动条。有关演示,请参阅~Snippet 2

.outer {
overflow: scroll;
height: 500px;
}
.grid {
border: 1px solid black;
}
.headerwrap {
overflow: hidden;
border: 1px solid blue;
}
.bodywrap {
overflow: hidden;
border: 1px solid red;
}
.body {
overflow: auto;
border: 1px solid green;
/*height:300px;*/
}
<div class="outer">
<div class="grid">
<div class="headerwrap">
<div class="header">
<table border="1" style="width:2000px;">
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
<td>e</td>
<td>f</td>
</tr>
</table>
</div>
</div>
<div class="bodywrap">
<div class="body">
<table border="1" style="width:2000px;height:1000px">
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
</tr>
</table>
</div>
</div>
</div>
</div>

编辑~代码段2

.outer {
overflow-y: scroll;
}
.grid {
border: 1px solid black;
}
.headerwrap {
overflow: hidden;
border: 1px solid blue;
}
.bodywrap {
overflow: hidden;
border: 1px solid red;
}
.body {
overflow-y: auto;
border: 1px solid green;
/*height:300px;*/
}
body::-webkit-scrollbar {
width: 1em;
}

body::-webkit-scrollbar-track {
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
}

body::-webkit-scrollbar-thumb {
background-color: darkgray;
border-radius: 10px;
outline: 1px solid slategrey;
}
<div class="outer">
<div class="grid">
<div class="headerwrap">
<div class="header">
<table border="1" style="width:2000px;">
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
<td>e</td>
<td>f</td>
</tr>
</table>
</div>
</div>
<div class="bodywrap">
<div class="body">
<table border="1" style="width:2000px;height:1000px">
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
</tr>
</table>
</div>
</div>
</div>
</div>

求解解决方案;必须使用柔性箱,这样就有点受限了,因为我必须设置固定的收割台高度。但这已经比必须把所有东西都写在一起要好得多了。

function Throttle(ms, callback) {
let lastCall = 0;
return function () {
let now = new Date().getTime(),
diff = now - lastCall;
if (diff >= ms) {
lastCall = now;
callback.apply(this, arguments);
}
};
}
function Grid(){
this.head = document.querySelector('.head');
this.body = document.querySelector('.body');
this.frozenBody = document.querySelector('.bodywrap>.frozen');

this.body.addEventListener('scroll', Throttle(5, this.Scroll.bind(this)));
}
Grid.prototype = {
Scroll : function(){
let scrollLeft = event.srcElement.scrollLeft;
let scrollTop = event.srcElement.scrollTop;
this.head.style.transform = `translateX(-${scrollLeft}px)`;
this.frozenBody.style.transform = `translateY(-${scrollTop}px)`;
}
}
new Grid();
html,margin{
margin:0;
border:0;
}
.outer{
border:1px solid red;
height:500px;
}
.grid{
position:relative;
height:100%;
display:flex;
flex-direction:column;  
}
.headwrap{
display:flex;
flex:0 0 75px;
flex-direction:row;     
margin-right:20px;
overflow:hidden;
background:blue;
}   
.headwrap .frozen{
flex:0 0 50px;
overflow:hidden;
background:lime;
z-index:1;

}
.head{
flex:1 1 auto;
overflow:hidden;
z-index:0;
}
.bodywrap{
display:flex;
flex:1 1 auto;
flex-direction:row;         
overflow:auto;

}
.bodywrap .frozen{
flex:0 0 50px;
overflow:hidden;
margin-bottom:20px;
background:lime;
z-index:1;
}
.body{
flex:1 1 auto;
overflow:auto;
background:silver;
z-index:0;
}
td{
height:100px;
}
<div class="outer">
<div class="grid">
<div class="headwrap">
<div class="frozen">
<table border="1" style="height:75px">
<tr>
<td style="width:50">1</td>
</tr>
</table>
</div>
<div class="head">
<table border="1" style="width:2000px;height:75px">
<tr>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>                  
</tr>
</table>
</div>
</div>
<div class="bodywrap">
<div class="frozen">
<table border="1" style="width:50px;">
<tr>
<td>1</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td>3</td>
</tr>
<tr>
<td>4</td>
</tr>
<tr>
<td>5</td>
</tr>
<tr>
<td>6</td>
</tr>
</table>
</div>
<div class="body">
<table border="1" style="width:2000px;">
<tr>
<td>1</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td>3</td>
</tr>
<tr>
<td>4</td>
</tr>
<tr>
<td>5</td>
</tr>
<tr>
<td>6</td>
</tr>
</table>
</div>
</div>
</div>
</div>

最新更新