我有一个单列布局,其中主体元素充当一列并具有独特的背景颜色。我希望 body 元素填充视口高度(目前使用
100vh
),以便内部元素可以使用 height: 100%
,但是如果 body 的内容大于视口,则 body 应该增长(以便其背景-颜色与内容一致)。
这是一些演示代码:
// This is just a helper code for the demo
// it's unrelated to the problem. Please, review the CSS block
let height = '';
document.querySelector('button').addEventListener('click', () => {
const newHeight = height === '' ? '2400px' : '';
height = newHeight;
const filler = document.querySelector('.content-filler')
filler.style.height = newHeight;
})
* {
box-sizing: border-box;
}
html {
background-color: white;
}
body {
width: 300px;
background-color: #b39ddb;
height: 100vh; /* fixed height is defined here */
padding: 0;
margin: 0;
margin-inline: auto;
}
.column {
height: 100%; /* this is inherited from the body's 100vh */
display: flex;
flex-direction: column;
}
.bottom-row {
margin-top: auto;
padding: 12px;
background: blueviolet;
}
.content-filler {
flex-shrink: 0;
background: #673ab7;
color: white;
padding: 8px;
}
<div class="column">
<div style="padding: 8px">
Hello world
<div>
<button>Toggle large content</button>
</div>
<br>
<div class="content-filler">Dynamic content</div>
</div>
<div class="bottom-row">bottom-row</div>
</div>
此实现的问题是,当内容高度很大时,body 元素保持固定在
100vh
并且其背景颜色似乎被“切断”。
显然这是固定高度值所期望的,但是我该如何解决这个问题呢?
如果我将
height: 100vh
更改为min-height: 100vh
,那么子元素的height: 100%
将不再生效。
我尝试使用类似
height: minmax(100vh, fit-content)
的值作为 height
值,但不幸的是它不起作用。
有没有办法解决这个问题,然后将树中的所有元素从 body 开始转换为弹性列?
更新:我错过了一个重要的用例:
.column
的更多子级也需要能够设置height: 100%
,依此类推,在树中进一步。
我简直不敢相信,我想我解决了!虽然感觉更像是中了彩票,意外地发现了有效的方法。
将这些样式用于
body
:
body {
display: grid;
min-height: 100vh;
}
我花了很多功夫将 body 设置为
flex
,但它也需要更新所有子项以弯曲列。但令我惊讶的是,display: grid
的行为有所不同!本质上,它允许高度由 min-height
设置的元素的子元素使用 height: 100%
来增长!这正是我想要实现的目标。
这是更新的演示:
// This is just a helper code for the demo
// it's unrelated to the problem. Please, review the CSS block
let height = '';
document.querySelector('button').addEventListener('click', () => {
const newHeight = height === '' ? '2400px' : '';
height = newHeight;
const filler = document.querySelector('.content-filler')
filler.style.height = newHeight;
})
* {
box-sizing: border-box;
}
html {
background-color: white;
}
body {
width: 300px;
background-color: #b39ddb;
display: grid; /* <-- this is the solution */
min-height: 100vh; /* <-- this is the solution */
padding: 0;
margin: 0;
margin-inline: auto;
}
.column {
height: 100%; /* this is inherited from the body's 100vh */
display: flex;
flex-direction: column;
}
.bottom-row {
margin-top: auto;
padding: 12px;
background: blueviolet;
}
.content-filler {
flex-shrink: 0;
background: #673ab7;
color: white;
padding: 8px;
}
<div class="column">
<div style="padding: 8px">
Hello world
<div>
<button>Toggle large content</button>
</div>
<br>
<div class="content-filler">Dynamic content</div>
</div>
<div class="bottom-row">bottom-row</div>
</div>
到目前为止,我只发现一个问题:当我的页面位于 iframe 内时,它会出现不必要的过度滚动。幸运的是,在我的例子中,我可以控制它并将
.is-iframe
类设置为 body,为此我将显示值更改回 block
。
我会再玩一些,如果我没有发现严重的问题,我会将其标记为答案