当一个元素的高度增加时(等高列),增加所有元素的高度。

3
我希望所有高度为100%的元素在body大小扩展时都会扩展。
例如,按下按钮将添加一个红色的
,相邻的两列应该伸展以适应此情况。最终,所有列都应完全到达底部,其中一个是蓝色,然后是红色,另外两个只是蓝色。
我正在研究flex,但似乎这不起作用,但欢迎任何建议。
无论如何,最好的解决方案是CSS,但如果这不可能,则使用纯JS也可以。

span = document.getElementsByTagName("span")[0];
function addelem() {
  span.appendChild(document.createElement('div'));
};
html, body{
  height: 100%;
}

span {
  display: inline-block;
  background-color: blue;
  width: 30px;
  height: 100%;
  vertical-align: top;
}

div {
  background-color: red;
  width: 30px;
  height: 30px;
}
<span><span></span></span>
<span></span>
<span><button onclick="return addelem()">+</button></span>

这是我期望在按钮被按下并向下滚动后底部框架的样子:

enter image description here

编辑

根据下方的评论建议,我修改了代码片段,使按钮将div附加到现有子元素并导致溢出。


1
点击“+”时不清楚应该发生什么? - Asons
蓝色的跨度应该在添加div的下一个跨度开始,向底部增加它们的大小,一直延伸到红色div的结束处。 - kabanus
不太确定这是否是您所需的:https://codepen.io/anon/pen/pPKzON 不太灵活和可靠。我想我理解了第一部分... :) - G-Cyrillus
@Michael_B 这与我的实际布局类似。一个按钮调用JavaScript来添加元素。我不介意将其作为子元素附加到其中一个蓝色列中,从而导致当前元素扩展。我不确定这是否更容易,但如果是,请继续。 - kabanus
是的,这很重要。如果元素是在容器内添加的,则可以使用纯CSS轻松实现布局而不会有太多复杂性。我发布了一个答案。 - Michael Benjamin
2个回答

2
一个flex容器的初始设置是 align-items: stretch。这意味着flex项目将会在交叉轴上展开以覆盖整个容器的长度。
在一个具有flex-direction: row的容器中,交叉轴是垂直的,因此项目将会展开到完整的高度。
在你的演示代码中,红色的div被添加为蓝色span列的子元素。这些div被添加到末尾,迫使该列增长。
在没有指定高度覆盖align-items: stretch的情况下,行方向的flex容器中,其他列也会效仿。

span = document.getElementsByTagName("span")[0];
function addelem() {
  span.appendChild(document.createElement('div'));
};
body {
  display: flex;
  min-height: 100vh;
}

body > span {
  width: 30px;
  margin-right: 5px;
  background-color: blue;
  display: flex;
  flex-direction: column;
}

body > span:first-child span {
  flex: 0 0 100vh;
}

div {
  background-color: red;
  width: 30px;
  height: 30px;
}

button {
  margin-bottom: auto;
}
<span><span></span></span>
<span></span>
<span><button onclick="return addelem()">+</button></span>


1
谢谢,发现得好。 - kabanus
快速问题 - 使用视口高度(vh)单位与百分比相比有什么优势?这对于此解决方案是必须的吗? - kabanus
使用百分比高度需要您在父元素上定义高度,而一些浏览器处理方式不同。使用vh单位,高度更简单。但是,这并不是解决方案工作的要求。 - Michael Benjamin

0

你应该两次使用Flexbox,一次在外部容器中,一次在包含附加子元素的容器中。

这是您修改后的代码:

span = document.getElementsByTagName("span")[0];
function addelem() {
  span.appendChild(document.createElement('div'));
};
html, body{
  height: 100%;

  /* new */
  display: flex;
}

/* new */
body > span{margin-right: 4px;}

span {
  /*display: inline-block;*/
  background-color: blue;
  width: 30px;
  height: 100%;
  vertical-align: top;

  /* new */
  display: flex;
  flex-flow: column;
  align-items: flex-end;
}

div {
  background-color: red;
  width: 30px;
  height: 30px;

  /* new */
  flex: 1 0 auto;
}
<span><span></span></span>
<span></span>
<span><button onclick="return addelem()">+</button></span>


1
这个解决方案不起作用。它只是用红色的div填充了蓝色列。一旦空间用尽,它会扩展该列,但其他两列则被留在原地。(观察滚动条或在开发工具中检查高度。) - Michael Benjamin
@Michael_B,我不明白你的负投票。除了溢出副作用之外,这难道不是他想要的吗?而且如果你从逻辑上考虑,解决方案不应该溢出吗?否则你怎么计算三个容器的高度,其中两个设置为100%,另一个设置为100%加上任何未知值呢? - Gabe Hiemstra
@Michael_B 我错过了这个 bug。Gabe,请点击按钮,直到蓝色 span 完全变成红色 div,然后继续点击。你会发现红色的 div 附加在 span 的原始尺寸之上,留下其他两个。我还是点赞了,因为可能有人正在寻找这个。相反,在 Michal 的解决方案中,我可以不断地点击,直到我的内存耗尽或手指疲劳 - 列保持相等。 - kabanus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接