浏览器:Chrome
我试图设置一排盒子,里面有一个可以展开的物品。我希望同一行上的项目具有相同的高度。当可扩展项目折叠时,我希望容器相应地缩小。不知何故,我创造了一些东西,当盒子扩大时它会不断增加它的大小。
此示例是从应用程序中提取的。因此div的多层可能对你没有多大意义。我刚刚提取了重现问题所需的最小部分。
const expandButtons = document.querySelectorAll('.expand');
for (let i = 0; i < expandButtons.length; i++) {
const button = expandButtons[i];
button.addEventListener("click", () => toggleExpand(button));
}
function toggleExpand(el) {
const content = el.parentElement.querySelector('.content');
content.classList.toggle('is-expanded');
}
.row {
display: flex;
}
.col {
display: flex;
}
.card {
display: flex;
flex-direction: column;
border: 1px solid black;
}
.wrapper {
height: 100%;
}
.card-block {
height: 100%;
display: flex;
flex-direction: column;
}
.content {
max-height: 0;
overflow: auto;
transition: max-height 500ms;
}
.content.is-expanded {
max-height: 6em;
}
.spacer {
display: flex;
flex-grow: 1;
}
<div class="row">
<div class="col">
<div class="card">
<div class="wrapper">
<div class="card-block">
<p>ASDF</p>
<div class="content">
<p>First</p>
<p>Second</p>
<p>Third</p>
</div>
<div class="spacer"></div>
<button type="button" class="expand">Expand</button>
</div>
</div>
</div>
</div>
<div class="col">
<div class="card">
<div class="wrapper">
<div class="card-block">
<div class="content">
<p>First</p>
<p>Second</p>
</div>
<div class="spacer"></div>
<button type="button" class="expand">Expand</button>
</div>
</div>
</div>
</div>
</div>
问题
展开第二个框会增加高度,折叠时不会缩回。扩展/折叠第一个修复它。为什么会这样? (我对解释而不是解决方案感兴趣)
修改
我添加了示例中证明height: 100%
合理的部分,以避免混淆。这样我就可以将按钮保持在底部。这包括将display: flex; flex-direction: column;
添加到.card-block
并添加.spacer
类和相应的元素。这些不会导致问题,但却是height: 100%
。
顺便说一下,解决问题的简便方法是从flex-direction: column
删除.card
。再一次,我对“为什么”感兴趣。
答案 0 :(得分:2)
请注意,奇怪的行为似乎是Chrome中的一个错误,因为在其他浏览器中不会发生这种情况。
无论为什么会发生这种情况,在height: 100%
上使用.wrapper
时,你需要问问自己,100%是什么?
height: 100%
元素从其父级中获取100%的元素,但为了使其工作,父级也需要一个card
没有的高度,因此{ {1}}将解析为100%
。
由于auto
将被解析wrapper
,auto
也将被解析,因为其父级(.card-block
)也没有定义的高度。 (它似乎在Chrome中有点表现,认为这不会跨浏览器工作。)
解决方案是一直使用Flexbox。
Stack snippet
wrapper
&#13;
const expandButtons = document.querySelectorAll('.expand');
for (let i = 0; i < expandButtons.length; i++) {
const button = expandButtons[i];
button.addEventListener("click", () => toggleExpand(button));
}
function toggleExpand(el) {
const content = el.parentElement.querySelector('.content');
content.classList.toggle('is-expanded');
}
&#13;
.row {
display: flex;
}
.col {
display: flex;
}
.card {
display: flex;
flex-direction: column;
border: 1px solid black;
}
.wrapper {
/*height: 100%; removed */
flex: 1; /* added, fill parent height */
display: flex; /* added */
/*align-items: stretch this is the default and make its item,
the "card-block", fill its parent height */
}
.card-block {
/*height: 100%; removed */
display: flex;
flex-direction: column;
}
.content {
max-height: 0;
overflow: auto;
transition: max-height 500ms;
}
.content.is-expanded {
max-height: 6em;
}
.spacer {
display: flex;
flex-grow: 1;
}
&#13;
答案 1 :(得分:0)
你应该使用height:auto,而不是height:100%;
const expandButtons = document.querySelectorAll('.expand');
expandButtons.forEach(x => {
x.addEventListener("click", () => toggleExpand(x));
});
function toggleExpand(el) {
const content = el.parentElement.querySelector('.content');
content.classList.toggle('is-expanded');
}
.row {
display: flex;
}
.col {
display: flex;
}
.card {
display: flex;
flex-direction: column;
border: 1px solid black;
}
.wrapper {
height: auto;
}
.card-block {
height: auto;
}
.content {
max-height: 0;
overflow: auto;
transition: max-height 500ms;
}
.content.is-expanded {
max-height: 6em;
}
<div class="row">
<div class="col">
<div class="card">
<div class="wrapper">
<div class="card-block">
<p>ASDF</p>
<div class="content">
<p>First</p>
<p>Second</p>
<p>Third</p>
</div>
<button type="button" class="expand">Expand</button>
</div>
</div>
</div>
</div>
<div class="col">
<div class="card">
<div class="wrapper">
<div class="card-block">
<div class="content">
<p>First</p>
<p>Second</p>
</div>
<button type="button" class="expand">Expand</button>
</div>
</div>
</div>
</div>
</div>
答案 2 :(得分:0)
据我所知,你的意思是这个。我只需将align-items:baseline;
添加到.card
课程。我还从margin-top
班级中删除了.card-block > p
。
const expandButtons = document.querySelectorAll('.expand');
for (let i = 0; i < expandButtons.length; i++) {
const button = expandButtons[i];
button.addEventListener("click", () => toggleExpand(button));
}
function toggleExpand(el) {
const content = el.parentElement.querySelector('.content');
content.classList.toggle('is-expanded');
}
.row {
display: flex;
}
.col {
display: flex;
}
.card {
display: flex;
flex-direction: column;
border: 1px solid black;
align-items: baseline;
}
.wrapper {
height: 100%;
}
.card-block {
height: 100%;
}
.card-block > p {
margin-top: 0;
}
.content {
max-height: 0;
overflow: auto;
transition: max-height 500ms;
}
.content.is-expanded {
max-height: 6em;
}
<div class="row">
<div class="col">
<div class="card">
<div class="wrapper">
<div class="card-block">
<p>ASDF</p>
<div class="content">
<p>First</p>
<p>Second</p>
<p>Third</p>
</div>
<button type="button" class="expand">Expand</button>
</div>
</div>
</div>
</div>
<div class="col">
<div class="card">
<div class="wrapper">
<div class="card-block">
<div class="content">
<p>First</p>
<p>Second</p>
</div>
<button type="button" class="expand">Expand</button>
</div>
</div>
</div>
</div>
</div>
答案 3 :(得分:0)
可能的解决方案是使用
.wrapper {
flex: 1;
display: flex;
}
而不是.wrapper {height: 100%}
。
const expandButtons = document.querySelectorAll('.expand');
for (let i = 0; i < expandButtons.length; i++) {
const button = expandButtons[i];
button.addEventListener("click", () => toggleExpand(button));
}
function toggleExpand(el) {
const content = el.parentElement.querySelector('.content');
content.classList.toggle('is-expanded');
}
&#13;
.row {
display: flex;
}
.col {
display: flex;
}
.card {
display: flex;
flex-direction: column;
border: 1px solid black;
}
.wrapper {
flex: 1;
display: flex;
}
.card-block {
height: 100%;
display: flex;
flex-direction: column;
}
.content {
max-height: 0;
overflow: auto;
transition: max-height 500ms;
}
.content.is-expanded {
max-height: 6em;
}
.spacer {
display: flex;
flex-grow: 1;
}
&#13;
<div class="row">
<div class="col">
<div class="card">
<div class="wrapper">
<div class="card-block">
<p>ASDF</p>
<div class="content">
<p>First</p>
<p>Second</p>
<p>Third</p>
</div>
<div class="spacer"></div>
<button type="button" class="expand">Expand</button>
</div>
</div>
</div>
</div>
<div class="col">
<div class="card">
<div class="wrapper">
<div class="card-block">
<div class="content">
<p>First</p>
<p>Second</p>
</div>
<div class="spacer"></div>
<button type="button" class="expand">Expand</button>
</div>
</div>
</div>
</div>
</div>
&#13;
根据我的理解,height: 100%
会混淆元素,因为它的父级高度是扩展的(转换后),所以它想要填充它。使用flex: 1;
和display: flex
,元素将填充剩余高度,也将成为弹性框,这意味着其子级也不会更改.card
高度。