Position: absolute and parent height?
Asked Answered
V

8

164

I have some containers and their children are only absolute / relatively positioned. How to set the container's height so their children will be inside of them?

Here's the code:

HTML

<section id="foo">
  <header>Foo</header>

  <article>
    <div class="one"></div>
    <div class="two"></div>
  </article>
</section>    
    
<div style="clear:both">Clear won't do.</div>
<!-- I want to have a gap between sections here -->
    
<section id="bar">
  <header>bar</header>
  
  <article>
    <div class="one"></div>

    <div></div>

    <div class="two"></div>
  </article>
</section>  

CSS

article {
  position: relative;
}
    
.one {
  position: absolute;
  top: 10px;
  left: 10px;
  background: red;
  width: 30px;
  height: 30px;
}
    
.two {
  position: absolute;
  top: 10px;
  right: 10px;
  background: blue;
  width: 30px;
  height: 30px;
}

Here's a jsfiddle. I want the "bar" text to appear between 4 squares, not behind them.

http://jsfiddle.net/Ht9Qy/

Any easy fixes?

Note that I don't know the height of these children, and I can't set height: xxx for containers.

Vulvitis answered 24/11, 2012 at 21:47 Comment(1)
Possible duplicate of Make absolute positioned div expand parent div heightGrinder
N
111

2022 UPDATE. This answer is nearly 10 years old. When it was written we didn't have layout technologies like Flex or Grid available (they were dark, hacky/fun times).

Thankfully things have massively improved. Jöcker's answer shows you how to achieve this layout with Grid. If you can live with not supporting legacy browsers, do that instead!


Original Answer

If I understand what you're trying to do correctly, then I don't think this is possible with CSS while keeping the children absolutely positioned.

Absolutely positioned elements are completely removed from the document flow, and thus their dimensions cannot alter the dimensions of their parents.

If you really had to achieve this affect while keeping the children as position: absolute, you could do so with JavaScript by finding the height of the absolutely positioned children after they have rendered, and using that to set the height of the parent.

Alternatively, just use float: left/float:right and margins to get the same positioning effect while keeping the children in the document flow, you can then use overflow: hidden on the parent (or any other clearfix technique) to cause its height to expand to that of its children.

article {
  position: relative;
  overflow: hidden;
}
    
.one {
  position: relative;
  float: left;
  margin-top: 10px;
  margin-left: 10px;
  background: red;
  width: 30px;
  height: 30px;
}
    
.two {
  position: relative;
  float: right;
  margin-top: 10px;
  margin-right: 10px;
  background: blue;
  width: 30px;
  height: 30px;
}
Natalia answered 24/11, 2012 at 21:54 Comment(1)
For anyone stumbling here, trying to figure why your margin-left: -16px & overflow: hidden trick doesn't work. I didn't take into consideration that I had also right padding, so I needed margin-right: -16px. Also I used width: 100vw for the container, dunno if needed.Geyer
K
41

Here is my workaround,
In your example you can add a third element with "same styles" of .one & .two elements, but without the absolute position and with hidden visibility:

HTML

<article>
   <div class="one"></div>
   <div class="two"></div>
   <div class="three"></div>
</article>

CSS

.three{
    height: 30px;
    z-index: -1;
    visibility: hidden;
    width:0!important; /* if you got unnecessary horizontal scroll*/
}
Karen answered 18/9, 2017 at 14:5 Comment(1)
So to boil it down, have a clone of content that produces the same height.Periapt
W
37

You can do that with a grid:

article {
  display: grid;
}
    
.one {
  grid-area: 1 / 1 / 2 / 2;
}
    
.two {
  grid-area: 1 / 1 / 2 / 2;
}
Wakeup answered 2/9, 2020 at 18:58 Comment(4)
You are a freaking genius. Thank you! This seems the only way to maintain the height of an absolute element without setting a fixed value. Brilliant.Whencesoever
Does this also allow for parent elements of article to maintain the height? I'm having issues getting it 2 parents up the DOM tree to maintain the size. Even 1 parent above the article seems hard. There are no additional elements outisde of the article in my case.Chatterjee
My usecase was slightly different: I needed an overlap, so for anyone with a similar usecase running into issues still, this CSS REPLACES the possitioning... See updated fiddle here: jsfiddle.net/6xv4c1saMilda
In this case I think you can make use of grid-area: 1 / -1; if you're into short notations.Retortion
I
4

This is a late answer, but by looking at the source code, I noticed that when the video is fullscreen, the "mejs-container-fullscreen" class is added to the "mejs-container" element. It is thus possible to change the styling based on this class.

.mejs-container.mejs-container-fullscreen {
    // This rule applies only to the container when in fullscreen
    padding-top: 57%;
}

Also, if you wish to make your MediaElement video fluid using CSS, below is a great trick by Chris Coyier: http://css-tricks.com/rundown-of-handling-flexible-media/

Just add this to your CSS:

.mejs-container {
    width: 100% !important;
    height: auto !important;
    padding-top: 57%;
}
.mejs-overlay, .mejs-poster {
    width: 100% !important;
    height: 100% !important;
}
.mejs-mediaelement video {
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;
    width: 100% !important;
    height: 100% !important;
}

I hope it helps.

Ivo answered 9/4, 2014 at 21:49 Comment(0)
K
1

This kind of layout problem can be solved with flexbox now, avoiding the need to know heights or control layout with absolute positioning, or floats. OP's main question was how to get a parent to contain children of unknown height, and they wanted to do it within a certain layout. Setting height of the parent container to "fit-content" does this; using "display: flex" and "justify-content: space-between" produces the section/column layout I think the OP was trying to create.

<section id="foo">
    <header>Foo</header>
    <article>
        <div class="main one"></div>
        <div class="main two"></div>
    </article>
</section>    

<div style="clear:both">Clear won't do.</div>

<section id="bar">
    <header>bar</header>
    <article>
        <div class="main one"></div><div></div>
        <div class="main two"></div>
    </article>
</section> 

* { text-align: center; }
article {
    height: fit-content ;
    display: flex;
    justify-content: space-between;
    background: whitesmoke;
}
article div { 
    background: yellow;     
    margin:20px;
    width: 30px;
    height: 30px;
    }

.one {
    background: red;
}

.two {
    background: blue;
}

I modified the OP's fiddle: http://jsfiddle.net/taL4s9fj/

css-tricks on flexbox: https://css-tricks.com/snippets/css/a-guide-to-flexbox/

Kissable answered 8/8, 2019 at 15:52 Comment(2)
fit-content is what solved this for me!Quintessa
Well, OP actually was specifically seeking out a solution when using position:absolute, which a lot of us are.Periapt
F
1

article {
    position: relative;
   
}

//clear the float

article::after{
  content: '';
  clear: both;
  
}

.one {
    position: relative;
    float:left
    margin-top: 10px;
    margin-left: 10px;
    background: red;
    width: 30px;
    height: 30px;
}

.two {
    position: relative;
    float: right;
    margin-top: 10px;
    margin-right: 10px;
    background: blue;
    width: 30px;
    height: 30px;
}
Forwarder answered 17/5, 2021 at 11:39 Comment(0)
B
-1

Set element with style position:absolute top: 0, botton: 0

Brendis answered 12/12, 2022 at 8:54 Comment(1)
Welcome to SO! Please take a look at the other answers that were given before. Your approach is mentioned there already. In order to keep the site clear and make it easy to find answers, we try to avoid double answers.Dynasty
G
-20

This is another late answer but i figured out a fairly simple way of placing the "bar" text in between the four squares. Here are the changes i made; In the bar section i wrapped the "bar" text within a center and div tags.

<header><center><div class="bar">bar</div></center></header>

And in the CSS section i created a "bar" class which is used in the div tag above. After adding this the bar text was centered between the four colored blocks.

.bar{
    position: relative;
}
Gudrin answered 23/4, 2015 at 22:18 Comment(2)
Do not use <center>! It's been deprecated.Lemnos
...since HTML4 (A.D. 1997)Disenfranchise

© 2022 - 2024 — McMap. All rights reserved.