1
votes

I'm trying to create a simple HTML structure with FlexBox in Node.js Angular, using inline fxFlex and fxLayoutAlign. The main problem is fxFlex not stretching elements to match container, and fxLayoutAlign not giving correct layout to children. Perhaps these two issues are related.

I have a set of components, code can be seen below. The dashboard component has a layout with 3 children at the moment. The children, however, will not stretch to fit the container. Furthermore, I cannot use fxLayoutAlign to align the children with space-between. The header component has fxLayoutAlign as well, and here it works perfectly fine.

One of the children for the dashboard is another component, called quest-list. This component contains a list of "quests", which can vary in size, which leads to the container being scrollable with overflow. However, unless i specify the exact height of the quest-list in pixels, it will not stretch out to fit any of the children.

Stackblitz of the problem here

So far, my code has the following components (Using Angular Material, for some visual feedback while coding):

main-page.component.html:

<div fxLayout="column" fxFlex="100" fxLayoutGap="10px" class="main-container">
  <header></header>
  <dashboard fxFlex="grow"></dashboard>
</div>

header.html:

<mat-toolbar fxFlex fxLayoutAlign="space-between center" fxLayout="row" class="mat-elevation-z1" fxLayoutGap="20px">
  <div fxFlex="nogrow">
    <button mat-icon-button [matMenuTriggerFor]="menu" aria-label="Example icon-button with a menu">
      <mat-icon>more_vert</mat-icon>
    </button>
    <mat-menu #menu="matMenu" [overlapTrigger]="false">
      <button mat-menu-item *ngFor="let button of buttons" (click)="navigate(button.link)">
        <mat-icon>{{button.icon}}</mat-icon>
        <span>{{button.text}}</span>
      </button>
    </mat-menu>
  </div>
  <div fxLayout="row" fxFlex=nogrow fxLayoutGap="10px" fxLayoutAlign=" center">
    <div fxFlex>Username</div>
    <mat-icon fxFlex>account_circle</mat-icon>
  </div>
</mat-toolbar>

dashboard.component.html:

<div fxFlex="grow" fxLayout="column" *ngIf="loading==false" fxLayoutGap="20px" fxLayoutAlign="space-between center">
  
  <div fxFlex>
    {{getNameWithTitle()}}
  </div>

  <div fxFlex>
    {{getLevelWithCharacter()}}
  </div>
  
  <quest-list fxFlex
              class="quest-list"
              title="Quests"
              [quests]="quests"
              [showOnlyUserQuests]="true">
  </quest-list>

</div>

quest-list.component.html:

<mat-card fxFlex fxLayout="column" fxLayoutGap="20px" fxLayoutAlign=" center" class="quest-list-container">
  <div class="title" fxFlex="nogrow">
    {{title}}
  </div>
  <div fxFlex fxLayout="column" fxLayoutGap="10px" class="overflow-container">
      <mat-accordion *ngFor="let quest of quests">
        <mat-expansion-panel hideToggle>
          
          <mat-expansion-panel-header>
            <mat-panel-title fxFlex="nogrow">
              <img *ngIf="quest.skill.image" [src]="quest.skill.image.image">
              <mat-icon *ngIf="!quest.skill.image" fxFlex>not_interested</mat-icon>
            </mat-panel-title>
            <mat-panel-description fxFlex fxLayoutAlign="space-between center">
              {{quest.name}}
              <mat-icon>arrow_right</mat-icon>
            </mat-panel-description>
          </mat-expansion-panel-header>

          <p fxFlex>
            {{quest.description}}
          </p>

        </mat-expansion-panel>
      </mat-accordion>
  </div>
</mat-card>

quest-list-component.scss:

.quest-list-container {
    background-color: lightskyblue;
}

.overflow-container {
    overflow-y: scroll;
}

Images of the problem:

Without pixel height

With fxFlex="600px for <quest-list>

(Using global styling: @import '~@angular/material/prebuilt-themes/indigo-pink.css';

I find this problem very frustrating, as I am somewhat sure the solution is very simple. But as I have now spent hours looking at it, and still cannot see the problem, I hope someone here can help.

Thanks in advance.

1
It would be nice if you could create a stackblitz with your issue. Otherwise it's just guessing :). One of my guesses would be that you are missing a min-height: 0 somewherePoul Kruijt
Sure thing, here you goJaisBC

1 Answers

0
votes

The issue is that if you just use fxFlex on the overflow-container, it will add a style of: flex: 1 1 0.0000001%, in combination with your overflow-scroll this will result in the container to collapse to the smallest size possible. If you change this to fxFlex="auto" it will already look a bit better.

However, I suppose that's not all you've wanted. I guess you want it to just scroll that inner area, and not the complete page. This requires quite some changes as well. A lot of height: 100% on the parent elements starting from the body element. A couple min-height: 0 on a couple of elements, setting of the fxFlex directive to auto and the removal of fxFlex="100" on the .main-container. Because, if you add a fxFlex to an element, the parent element will automatically get display: flex attached to it, even though that's not something we want there.

I've made a fully working stackblitz here

Personally I've ditched the fxLayout package from angular. There is a definite speed sacrifice you make when using this package, and in 99% of the cases you can just use some utility classes. For the remaining 1% you can use some other way.