问题
I'm building an html/javascript theme designer for a CMS. Elements are positioned absolutely and can be moved/resized via the mouse, and/or contain editable text whose height may be determined by the number of lines. However I'm running into the problem where a parent element's height does not expand to include its absolutely positioned children.
Minimal code (also on JSFiddle here):
<style>
div.layer { position: absolute }
div.layer1 { width: 400px; border: 1px solid #ccc }
div.layer2 { top: 15px; left: 100px; width: 100px; border: 1px solid blue }
</style>
<div class="layer layer1">container should expand to the bottom of the child.
<div class="layer layer2" contentEditable>Child with<br/>editable text.</div>
</div>
A CSS-only solution is ideal and I'm not concerned about older browsers. But I'm mostly looking for any way to prevent the need for javascript to run on every page using a created theme to set their height (since pages with the same theme may have different amounts of text).
There are already a few similar questions but their accepted answers (e.g. don't use absolute positioning) won't work in my case. Unless there is a way to have multiple layers of draggable/resizable elements without them being position: absolute.
回答1:
I found a pure-css solution! In summary:
- Set the child elements to position: relative instead of absolute.
- Set their margin-right to be their negative width, to give them zero effective width, and make them float: left to keep them all on the same line. This makes all of them have an origin of 0, 0.
- Then we can set their left and margin-top properties to position them absolutely within their parents. Note that margin-top is required instead of top because top won't push down the bottom of the parent element.
JSFiddle here or code below:
<style>
div.layer { position: relative; float: left; }
div.layer1 { width: 400px; border: 1px solid black }
div.layer2 { margin-top: 20px; left: 100px; width: 100px; margin-right: -100px; border: 1px solid blue }
div.layer3 { margin-top: 30px; left: 170px; width: 100px; margin-right: -100px; border: 1px solid red }
div.layer4 { margin-top: 30px; left: 20px; width: 60px; margin-right: -60px; border: 1px solid green }
</style>
<div class="layer layer1" style="position: relative; display: block; width: 400px; border: 1px solid black;">
Container
<div class="layer layer2" contentEditable>Edit me</div>
<div class="layer layer3">
<div class="layer layer4" contentEditable>Edit me</div>
</div>
</div>
回答2:
absolute positioned elements are removed from the flow, thus ignored by other elements
the only way you have is to set the child position to position:relative, in this way it is possible to move it using right,left,top and bottom and also change parent display to display:inline-block
回答3:
If you want keep the children absolutely positioned, you can use the following script to resize the container : http://jsfiddle.net/6csrV/7/
var layer1 = document.getElementsByClassName('layer1'),
i = 0, len = layer1.length, childHeight;
for(; i < len; i++) {
childHeight = layer1[i].getElementsByClassName('layer')[0].clientHeight;
layer1[i].style.height = childHeight + 'px';
}
document.addEventListener('keyup', function(e) {
if(e.target.className.indexOf('layer2') !== false) {
e.target.parentNode.style.height = e.target.clientHeight + 'px';
}
});
来源:https://stackoverflow.com/questions/18947691/extend-height-to-include-absolutely-positioned-children