0
votes

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:

  • fluid images are flexible but they basically resize based on their ratio
  • a fluid div element with text contents resizes based on its parents dimensions

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

thanx

1

1 Answers

1
votes

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>