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.
Absolute positioning defines the position of a given bounding box from the top and left side margins of the web page. This not only allows objects to be placed in an exact location, it also allows objects to be placed one on top of another.
Absolutely positioned elements are positioned with respect to a containing block, which is the nearest postioned ancestor. If there is no positioned ancestor, the viewport will be the containing block. Elements with fixed positioning are fixed with respect to the viewport—the viewport is always their containing block.
position: sticky;A sticky element toggles between relative and fixed , depending on the scroll position. It is positioned relative until a given offset position is met in the viewport - then it "sticks" in place (like position:fixed).
What is the CSS position property? The CSS position property defines the position of an element in a document. This property works with the left, right, top, bottom and z-index properties to determine the final position of an element on a page.
I found a pure-css solution! In summary:
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>
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
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';
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With