我有一个网格,元素角可能会或可能不会对齐,但所有边都接触,所以没有间隙。也没有重叠。例如,它可能有这样的东西:
+----+-------+
| | B |
| +---+---+
| A | C | |
| |---| D |
| | E | |
+----+---+---+
网格是通过绝对定位的元素创建的。 (我意识到通过树创建这样的网格可能更容易,其中父节点是与相邻元素形成矩形的容器,但我认为这可能会限制我能够的方式调整元素大小 - 我稍后会解释。
我希望能够调整单个元素的大小并让相邻元素重新计算其尺寸,以便它们捕捉到新元素尺寸而不留下间隙。例如,我们假设我们正在调整元素C
的大小:
现在,如前所述,我意识到将这些元素嵌套在容器元素(树状结构)中会更容易处理上述情况。我认为树形结构对我不起作用的原因(除了我已经有太多代码依赖于绝对位置的事实)是我不想要以下情况&# 39;调整大小取决于恰好位于下面的基础树结构:
+---+---+---+
| | | |
+---+---+---+
| | | |
+---+---+---+
| | | |
+---+---+---+
使用树,此示例不起作用,因为中间图块调整大小会调整碰巧共享同一父/容器的元素,即使他们不需要调整大小。
我试图弄清楚如何计算需要为我的绝对元素有效地调整哪些额外元素。我正在考虑以下几点:
在第一个子弹中解释的搜索将是这样的,然后我会检查后面的副作用:
document.elementsFromPoint()
我过度复杂吗?有更好的方法吗?这可以通过树木来实现,我只是没有看到它吗?
答案 0 :(得分:1)
如果底层结构没有改变,那么你可以用树结构css flexbox来解决你的问题。
Flexbox是非常强大的布局工具,是现代浏览器引擎的原生工具。您可以使用css使用display: flex;
以及其他简单的css来声明布局。
CSS技巧的flexbox教程可以比我更好地解释它,所以请参考this to understand what's going on。下面的代码更像是一个演示。
想法是改变元素的flexbox样式。要调整元素的大小,请使用javascript更改flex-basis
。我只有下面的按钮来显示概念证明,但最终,您希望使用鼠标事件来调整元素的大小。您可以将event.clientX
除以容器宽度(container.clientWidth
),以获得鼠标相对于容器的位置百分比,并将该值用于flexbasis。
在下面的演示中,我使用了一个变量,用于跟踪元素.a
和.a-complement
的flexbasis。单击按钮时,每个元素的flexbasis更新。它们都以50%50%开始,每按一次按钮增长/缩小10%。可以扩展此示例以包含使用相同技术调整所有元素的大小。他们都会尊重彼此的大小,他们都没有差距等。
故事的道德:让布局引擎为您完成工作!除非你真的需要,否则不要使用绝对定位。
解决树结构问题:您可以在需要时将树移动div重组为其他div。如果这太复杂了,那么很遗憾浏览器可能没有对文档结构的原生支持。
但未来可能......
如果flexbox无法解决您的问题,那么实验性CSS GRID可能会越多,但请注意,CSS网格仅在最新的浏览器中实现,并且没有移动浏览器可能会给您的目标受众带来好处。
let aBasis = 0.5;
const elementA = document.querySelector('.a');
const aComplement = document.querySelector('.a-complement');
document.querySelector('#left').addEventListener('click', () => {
aBasis -= 0.1;
elementA.style.flexBasis = (aBasis * 100) + '%';
aComplement.style.flexBasis = ((1 - aBasis) * 100) + '%';
console.log((aBasis * 100) + '%', ((1 - aBasis) * 100) + '%');
});
document.querySelector('#right').addEventListener('click', () => {
aBasis += 0.1;
elementA.style.flexBasis = (aBasis * 100) + '%';
aComplement.style.flexBasis = ((1 - aBasis) * 100) + '%';
console.log((aBasis * 100) + '%', ((1 - aBasis) * 100) + '%');
});
.a {
display: flex;
background-color: red;
flex: 1;
justify-content: center;
align-items: center;
}
.b {
display: flex;
background-color: blue;
flex: 1;
justify-content: center;
align-items: center;
}
.c {
display: flex;
background-color: green;
flex: 1;
justify-content: center;
align-items: center;
}
.d {
display: flex;
background-color: yellow;
flex: 1;
justify-content: center;
align-items: center;
}
.e {
display: flex;
background-color: orange;
flex: 1;
justify-content: center;
align-items: center;
}
.h-container {
display: flex;
align-items: stretch;
flex: 1;
}
.v-container {
display: flex;
flex: 1;
flex-direction: column;
}
.container {
display: flex;
height: 200px;
width: 200px;
flex: 1
}
.example-container {
display: flex;
width: 100%;
}
<div class="example-container">
<div class="container">
<div class="h-container">
<div class="a">
<span>A</span>
</div>
<div class="a-complement v-container">
<div class="b">
<span>B</span>
</div>
<div class="h-container">
<div class="v-container">
<div class="c"><span>C</span></div>
<div class="e"><span>E</span></div>
</div>
<div class="d"><span>D</span></div>
</div>
</div>
</div>
</div>
<div>
<button id="left">move a to the left</button>
<button id="right">move a to the right</button>
</div>
</div>