3

I use a third-party component that occupies all the available space, i.e. width=100% and height=100%. I don't have control over it.

I'm trying to fit it in the following layout, but its height=100% doesn't work (I expect the third-party component to occupy all the green space).

enter image description here

Why? How would you fix that?

.container {
  display: flex;
  flex-direction: column;
  width: 200px;
  height: 100px;
}

.header {
  display: flex;
  background-color: rgba(255, 0, 0, 0.5);
}

.content {
  flex-grow: 1;
  background-color: rgba(0, 255, 0, 0.5);
}

.third-party-component {
  height: 100%;
  width: 100%;
  background-color: rgba(0, 0, 255, 0.5);
}
<div class="container">
  <div class="header">Header</div>
  <div class="content">
    <div class="third-party-component">
      Third party component
    </div>
  </div>
</div>
Asons
  • 84,923
  • 12
  • 110
  • 165
Misha Moroshko
  • 166,356
  • 226
  • 505
  • 746

3 Answers3

3

In general, for an element using percent on height to pick up its parent's height, the parent need a height other than auto or being positioned absolute, or the height will be computed as auto.

Based on those 2 options, and as you mentioned in a comment, your own header is dynamic in height, you are left with absolute positioning.

The problem with adding absolute to the content, it will be taken out of flow and stop behaving as a normal flowed flex item, the good news, one can add a wrapper set to absolute.

Stack snippet

.container {
  display: flex;
  flex-direction: column;
  width: 200px;
  height: 100px;
}

.header {
  display: flex;
  background-color: rgba(255, 0, 0, 0.5);
}

.content {
  position: relative;                               /*  added  */
  flex-grow: 1;
  background-color: rgba(0, 255, 0, 0.5);
}

.wrapper {
  position: absolute;                               /*  added  */
  left: 0;                                          /*  added  */
  top: 0;                                           /*  added  */
  right: 0;                                         /*  added  */
  bottom: 0;                                        /*  added  */
}

.third-party-component {
  height: 100%;
  width: 100%;
  background-color: rgba(0, 0, 255, 0.5);
}
<div class="container">
  <div class="header">Header</div>
  <div class="content">
    <div class="wrapper">
      <div class="third-party-component">
       Third party component
      </div>
    </div>
  </div>
</div>

Another option could be to update the Flexbox properties, to give the content a height, using flex: 1 1 100% and give header flex-shrink: 0; so it doesn't shrink (as content got 100%).

This might not work on Safari though, as I know it have had issues when the height property is not set, though can't test that now as I don't have access to Safari.

.container {
  display: flex;
  flex-direction: column;
  width: 200px;
  height: 100px;
}

.header {
  display: flex;
  flex-shrink: 0;
  background-color: rgba(255, 0, 0, 0.5);
}

.content {
  flex: 1 1 100%;
  background-color: rgba(0, 255, 0, 0.5);
}

.third-party-component {
  height: 100%;
  width: 100%;
  background-color: rgba(0, 0, 255, 0.5);
}
<div class="container">
  <div class="header">Header</div>
  <div class="content">
    <div class="third-party-component">
      Third party component
    </div>
  </div>
</div>
Asons
  • 84,923
  • 12
  • 110
  • 165
1

Because .content haven't height (height = 0px) and .third-party-component have 100% of 0px. You can add propety height : calc (100% - <height of .header>) into .content

.container {
  display: flex;
  flex-direction: column;
  width: 200px;
  height: 100px;
}

.header {
  display: flex;
  background-color: rgba(255, 0, 0, 0.5);
}

.content {
  height: calc(100% - 18px);
  flex-grow: 1;
  background-color: rgba(0, 255, 0, 0.5);
}

.third-party-component {
  height: 100%;
  width: 100%;
  background-color: rgba(0, 0, 255, 0.5);
}
<div class="container">
  <div class="header">Header</div>
  <div class="content">
    <div class="third-party-component">
      Third party component
    </div>
  </div>
</div>
Thuc Nguyen
  • 235
  • 2
  • 8
  • Because `.content` haven't height (height = 0px) and `.third-party-component` have 100% of 0px. You can add propety `height : calc (100% - )` into `.content` – Thuc Nguyen Oct 29 '17 at 06:06
  • The thing is the height of the header is dynamic/unknown. – Misha Moroshko Oct 29 '17 at 06:09
  • Example: height of `.header` is 20%, you have to set height of `.content` is 80% OR if unset height of `.header`, I thing that you should use JS to get height of `.header` then set propety height for `.content` – Thuc Nguyen Oct 29 '17 at 06:42
  • I see you got down voted (and not by me), and as that someone didn't told why, I will. The statements that _(height = 0px)_ and that the component have _100% of 0px_ is both wrong. Check my answer how it works. – Asons Oct 29 '17 at 12:29
0

You can simply use another flex container in the .content element:

.container {
  display: flex;
  flex-direction: column;
  width: 200px;
  height: 100px;
}

.header {
  display: flex;
  background-color: rgba(255, 0, 0, 0.5);
}

.content {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  background-color: rgba(0, 255, 0, 0.5);
}

.third-party-component {
  flex-grow: 1;
  height: 100%;
  width: 100%;
  background-color: rgba(0, 0, 255, 0.5);
}
<div class="container">
  <div class="header">Header</div>
  <div class="content">
    <div class="third-party-component">
      Third party component
    </div>
  </div>
</div>
Amit
  • 45,440
  • 9
  • 78
  • 110
  • Note that you can't modify the third-party component, so adding `flex-grow: 1` to it doesn't count as a solution. – Misha Moroshko Oct 29 '17 at 05:59
  • Defining css selectors and rules doesn't modify "a component". You can always do that. You can use a nesting selector if you don't want to target by class (`.content > div`, or some other variation) if that makes a difference to you. – Amit Oct 29 '17 at 06:10
  • I appreciate your answer, but the whole point of this question is how to consume a third-party component without messing up with its styles. – Misha Moroshko Oct 29 '17 at 06:17