1

I have a div (the red box) that is in a horizontal flex box (black outline). Its height is calculated according to the heights of the other things in the flex box, in this case the tall blue boxes; this is all good.

Green box not tall enough

The red div has a child -- the green box in the picture. Which is positioned relative to the red box. I'd like the green box to exactly normally cover the red box. The width is no problem, since the red box has a fixed width. But how can I say that the height of the green box should equal the height of its parent, the red box?

The reason for the green box on top of the red box is that I want the green box to expand horizontally when hovered over, but I don't want this expansion to affect the layout of other elements. Like this:

green box expanded horizontally

There is a JSFiddle here

div.dropZone {
  position: relative;
  font-family: serif;
  margin: 0px;
  border-radius: 5px;
  left: 0px;
  top: 0px;
  width: 2em;
  height: inherit;
  min-height: 3ex;
  background-color: green;
}

div.dropZone:hover {
  width: 4em;
  left: -1em;
}

div.dzContainer {
  position: static;
  font-family: serif;
  margin: 0px 0px 0px 0px;
  -webkit-align-self: stretch;
  align-self: stretch;
  width: 2em;
  height: auto;
  min-height: 3ex;
  background-color: red;
}

div.tall {
  position: static;
  font-family: serif;
  margin: 0px 0px 0px 0px;
  -webkit-align-self: stretch;
  align-self: stretch;
  background-color: blue;
  width: 3em;
  height: 10ex;
}

.H {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -webkit-flex-direction: row;
  flex-direction: row;
  -webkit-flex-wrap: nowrap;
  flex-wrap: nowrap;
  -webkit-justify-content: flex-start;
  justify-content: flex-start;
  -webkit-align-items: flex-start;
  align-items: flex-start;
  border: 1px solid black;
}
<div class="H">
  <!-- black flex-->
  <div class="tall"> </div>
  <!-- blue static-->
  <div class="dzContainer">
    <!-- red static-->
    <div class="dropZone"> </div>
    <!-- green relative-->
  </div>
  <div class="tall"> </div>
  <!-- blue static-->
</div>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Theodore Norvell
  • 15,366
  • 6
  • 31
  • 45
  • 1
    `height: 100%` on `dropZone`? – kukkuz Apr 19 '19 at 18:55
  • in div.dropzone, have you tried setting the height to 100%? In your jsfiddle it works. – imvain2 Apr 19 '19 at 18:55
  • If to make the green box fill the red parent, add `display: flex` to `div.dzContainer`. Note, the given answer might get you in trouble, as setting 100% of a parent that doesn't have a set, static, height won't work properly cross browsers, the `display: flex` will. – Asons Apr 19 '19 at 19:06
  • On hover to increase the width of `div.dropZone`? – Marios Nikolaou Apr 19 '19 at 19:09
  • @LGSon. I'm not sure I follow. Are you saying that in addition to `height:100%` for the `dropZone` class (green box), I should also have `display:flex` for the `dzContainer` class (red box)? I thought the red box should be `display:block` since it acts as a leaf in the layout. (I mean that, while it does have a child, since that child is absolute, the red box is like a childless node for purposes of layout.) Can you point to a reference? – Theodore Norvell Apr 19 '19 at 20:55
  • @imvain2 The embarrasing fact is that I thought I had, but I used "pc" instead of "%". One thing I learned today is that "pc" does not stand for "percent"! – Theodore Norvell Apr 19 '19 at 20:58
  • 1
    I can't see an absolute child? ... Before I'll try to explain, have you tried the given solution on e.g Safari 11 ? – Asons Apr 19 '19 at 21:20
  • @LGSon Sorry I meant `relative` child, not `absolute`. I didn't try Safari 11. The JSFiddle seems to work on Safari 12. But in the context of my actual application, I am still having some trouble with Safari 12 and also Chrome 73. – Theodore Norvell Apr 20 '19 at 12:36
  • 1
    That's why I suggest to use `display: flex`. When using Flexbox it is generally a bad idea to start using `height` with a percent value, and the main reason is that when a child uses it, its parent needs to have a height set, which is not how one most of the time want. Nesting flex parents/children is a better, cross browser solution. E.g. like this: https://jsfiddle.net/kzL693ex/ – Asons Apr 20 '19 at 13:43
  • @LGSon Would you like to write a new answer? Your approach is completely different from the two answers we have now. You are saying that: *instead* of adding `height:100%` to the green box, we can add `display:flex` to the red box; and that it's a better approach because it works with more browswers. While, I can see that it works in practice, even with older versions of webkit, I'm not sure I see why it works in theory. – Theodore Norvell Apr 20 '19 at 16:57
  • 1
    The theory is that a flex child will by default, in flex row direction, stretch to fill its parent's height (`align-items: stretch`), which is what makes it work. – Asons Apr 20 '19 at 17:08
  • 1
    To add another answer is not necessary. These 3 answers of mine all describes and show how it all works (and would be a possible duplicate if you find that okay). https://stackoverflow.com/questions/46954952/how-to-stretch-flex-child-to-fill-height-of-the-container/46956430#46956430 ... https://stackoverflow.com/questions/46997189/why-height-100-doesnt-work/46997591#46997591 ... https://stackoverflow.com/questions/47839762/expandable-box-keeps-growing/47840161#47840161 – Asons Apr 20 '19 at 17:23
  • I ended up using @LGSon's suggestion (above). One thing I found was that, with firefox, when the green box expanded, so did the red. The fix for that was to give the red box a `max-width` equal to its width. To see the full effect in both horizontal and vertical directions, see https://jsfiddle.net/TheodoreNorvell/5od3afnm/ – Theodore Norvell Apr 21 '19 at 14:02
  • Possible duplicate of [How to stretch flex child to fill height of the container?](https://stackoverflow.com/questions/46954952/how-to-stretch-flex-child-to-fill-height-of-the-container) – recnac Apr 26 '19 at 01:32

2 Answers2

4

If you want the green box to fill the parent height add height: 100%; to the .dropZone class.

div.dropZone {
  position: relative;
  font-family: serif;
  margin: 0px;
  border-radius: 5px;
  left: 0px;
  top: 0px;
  width: 2em;
  height: 100%;
  min-height: 3ex;
  background-color: green;
}
jeninja
  • 788
  • 1
  • 13
  • 27
2

You just have to make one change in your CSS. Add "height:100%" to your div.dropZone selector. I hope that helps.

You can run the code snippet below to try it out.

div.dropZone {
    position: relative;
    font-family: serif;
    margin: 0px;
    border-radius: 5px;
    left: 0px;
    top: 0px;
    width: 2em;
    height: inherit;
    min-height: 3ex;
    background-color: green;
    height: 100%;
}

div.dropZone:hover {
  width: 4em;
  left: -1em;
}

div.dzContainer {
    position: static;
    font-family: serif;
    margin: 0px 0px 0px 0px;
    -webkit-align-self: stretch;
    align-self: stretch;
    width: 2em;
    height: auto;
    min-height: 3ex;
    background-color: red;
}

div.tall {
    position: static;
    font-family: serif;
    margin: 0px 0px 0px 0px;
    -webkit-align-self: stretch;
    align-self: stretch;
    background-color: blue;
    width: 3em;
    height: 10ex;
}

.H {
    display: -webkit-box;
    display: -moz-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;
    -webkit-flex-direction: row;
    flex-direction: row;
    -webkit-flex-wrap: nowrap;
    flex-wrap: nowrap;
    -webkit-justify-content: flex-start;
    justify-content: flex-start;
    -webkit-align-items: flex-start;
    align-items: flex-start;
    border: 1px solid black;
}
   <div class="H">                      <!-- black flex-->
    <div class="tall"> </div>          <!-- blue static-->
    <div class="dzContainer">           <!-- red static-->
        <div class="dropZone"> </div>   <!-- green relative-->
    </div>
    <div class="tall"> </div>          <!-- blue static-->
   </div>
Salmaniac
  • 189
  • 1
  • 7