Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FxFlex Calc sets min-height, while raw value sets max-height

<div fxFill fxLayout="column">
    <div fxFlex="8" fxLayout="column"> Fixed Header </div>
    <div fxFlex="20" fxLayout="row" [fxHide]="isShow"> Colapsable Header </div>
    <div fxFlex="72" fxLayout="column"> Page content </div>
</div>

Like this, if I hide the header, 20% of the page remains blank, cause the div containing the pagecontent occupies still only 72%

But if I use the with calc <div fxFlex="calc(92% - 20%)">, this respective div modifies her height depending if the above div is hidden or shown, so there's never a blank space even if the div gets collapsed..

Why does it work like this ? calc(92% - 20%) its always 72%, so why does it behave differently ?

More context after editing title of question:

After observing the generated Html I've gathered that

  • fxFlex="72" sets a max-height="72%"
  • fxFlex="calc(92%-20%)" sets min-height="72%"
like image 254
Greggz Avatar asked Mar 24 '21 14:03

Greggz


Video Answer


1 Answers

The short answer is because you are using calc.

The long answer is that the fxLayout library is checking if you are using concrete values(e.g. just a number) or a calc function and based on that decides if min or max height should be applied

    // Fix for issues 277, 534, and 728
    if (basis !== '0%' && basis !== '0px' && basis !== '0.000000001px' && basis !== 'auto') {
      css[min] = isFixed || (isValue && grow) ? basis : null;
      css[max] = isFixed || (!usingCalc && shrink) ? basis : null;
    }

snippet form the source that you can find on here

As visible in the snippet the max-height won't be applied in the cases where the input has calc value.

So now that we have cleared the calc case let's dive in the fxFlex="72" case.

The fxFlex directive/input accepts up to 3 space separated arguments that are as so fxFlex="{grow} {shrink}" {base} if only one input is provided like in your case fxFlex="72" , this will be evaluated the same way as fxFlex="1 1 72"

So now when we go in if statement we will check first the result for css[min], in the first half we see isFixed property (which will be false, we can skip this one as it's not related to the case). In the second we have a mix of (isValue && grow), so the grow property will be truthy, as it will take a default value of 1. The more interesting thing here is the isValue property, which represent the following logic (again as seen in the source)

   let isValue = (hasCalc || hasUnits);

We already discussed the hasCalc which will be false in this case (as we have the following input fxFlex="72" ), about hasUnits this is a property that checks if there is any unit beside % following the basis value (units like %,px,rem...), so in this case the hasUnits will also be false.

To sum it up we will have css[min] value equal to null.

Going on the next line we see again isFixed value equall to false and in the second half of the expression we see the following (!usingCalc && shrink) , this time there is no calc function so !usingCalc will be true, and because we have a default value of 1 for shrink, the whole expression will be evaluated as true and it will apply the basis value as css[max].

If you don't won't to use calc i would suggest to do the following

  <div fxFill fxFlex="100" fxLayout="column">
    <div style="background-color: palegreen;" fxFlex="8" fxLayout="column"> Fixed Header <button (click)="toggle()">Toggle</button> </div>
    <div style="background-color: rgb(179, 24, 174);" fxFlex="20" fxLayout="row" [fxHide]="show"> Colapsable Header </div>
    <div style="background-color: orange;" fxFlex="1 0 72" fxLayout="column"> Page content </div>
  </div>

Here instead of fxFlex="72" which will have a default shrink value of 1, I'm setting the value to 0 by doing so the fxLayout will skip the min-max check that we are looking at right now and will fill the available space.

like image 195
Християн Христов Avatar answered Sep 19 '22 16:09

Християн Христов