meysam
meysam

Reputation: 61

Make parents height to 100% of absolutely positioned child

I googled a lot but didn't find a good answer.

assume parent element has two child elements: a fluid image (width: 100% of its parent) and an absolute div element. if I decide to overlay div to completely fit over image (ofcourse if the div has not much content to override image boundaries) I can. example:

*{
  box-sizing: border-box;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

.container{
    position: relative;
    width: 30%;
    min-width: 250px;
}

img{
    display: block;
    width: 100%;
}

.caption{
    display: flex;
    flex-direction: column;
    padding: 20px;
    background-color: rgba(0, 0, 150, .2);

    position: absolute;
    top: 0;

    width: 100%;
    height: 100%;
}
.caption .caption-text{margin: auto; text-align: center;}
<div class="container">
  <img src="https://via.placeholder.com/400x300"  alt="">
  <div class="caption">
    <div class="caption-text">
      <h3>Hello World</h3>
      <p>Some random text</p>
    </div>
  </div>
</div>

but otherwise if I decide to position the same fluid image absolutely to overlay the div element, heights won't meet each other and that's because:

So how am I suppose to make parents height to be exactly 100% height of absolutely positioned child img?

thanx

Upvotes: 2

Views: 3648

Answers (1)

tao
tao

Reputation: 90068

That's not how it works. The position: absolute gets removed from parent's flow. Which effectively means: "its parent behaves like it does not have it as a child".

So, when you have two elements you want to overlap, you give one of them position:absolute (the one that should be ignored by parent) and you leave the content that should size the parent unpositioned (or with a position value of static or relative) (you leave it in the flow, thus allowing it to size the parent).

See this answer for a more detailed explanation.


If you want to size your image based on current contents of parent, your best bet is to use it as a background-image on the parent. background-size allows it to size it accordingly (cover, contain, etc...):

*{
  box-sizing: border-box;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

.container{
    position: relative;
    width: 30%;
    min-width: 250px;
    background: url(https://via.placeholder.com/400x300) no-repeat center /cover;
}

.caption{
    display: flex;
    flex-direction: column;
    padding: 20px;
    background-color: rgba(0, 0, 150, .2);
}
.caption .caption-text{margin: auto; text-align: center;}
<div class="container">
  <div class="caption">
    <div class="caption-text">
      <h3>Hello World</h3>
      <p>Some random text</p>
    </div>
  </div>
</div>

Notice I removed position:absolute from the content I want to size the parent (because I want it to size the parent).

Obviously you can achieve the same by still using an <img> tag and positioning it absolute and making sure it gets displayed under the contents, but background has been natively developed for this purpose, so it makes more sense to use it.

For the kicks, here's how it would look with the <img> positioned absolute:

a) contain:

*{
  box-sizing: border-box;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

.container{
    position: relative;
    width: 30%;
    min-width: 250px;
}
.container .positioner {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: -1;
  display: flex;
  align-items: center;
  justify-content: center;
}
.positioner img {
  max-width: 100%;
  max-height: 100%;
}

.caption{
    display: flex;
    flex-direction: column;
    padding: 20px;
    background-color: rgba(0, 0, 150, .2);
}
.caption .caption-text{margin: auto; text-align: center;}
<div class="container">
  <div class="positioner">
    <img src="https://via.placeholder.com/400x300">
  </div>
  <div class="caption">
    <div class="caption-text">
      <h3>Hello World</h3>
      <p>Some random text</p>
    </div>
  </div>
</div>

b) cover:

*{
  box-sizing: border-box;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

.container{
    position: relative;
    width: 30%;
    min-width: 250px;
}
.container .positioner {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: -1;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.positioner img {
  max-width: 100%;
}

.caption{
    display: flex;
    flex-direction: column;
    padding: 20px;
    background-color: rgba(0, 0, 150, .2);
}
.caption .caption-text{margin: auto; text-align: center;}
<div class="container">
  <div class="positioner">
    <img src="https://via.placeholder.com/400x300">
  </div>
  <div class="caption">
    <div class="caption-text">
      <h3>Hello World</h3>
      <p>Some random text</p>
    </div>
  </div>
</div>

Upvotes: 1

Related Questions