IonContent Size incorrect if content contains <ng-content>

Hi everyone,

I looked through the whole Forum & though Stackoverflow and Github, but it seems nobody has ever given an answer to this question, so here I am, maybe someone has an idea :slight_smile:.

When the content of ion-content is played into ng-content, the size of the scrollarea is not calculated correctly.

I tried this on the ionic conference app to demonstrate the issue:

1st, we have the common header+content, which can then be used on any component
MyWrapper

<ion-header>
  <ion-toolbar>
    <ion-buttons slot="start">
      <ion-menu-button></ion-menu-button>
    </ion-buttons>
    <ion-title>Speakers</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content fullscreen="true">

  <ng-content></ng-content>

</ion-content>

2nd we have some content

<my-wrapper>
    <!-- here can be any content that should be on the page-->
</my-wrapper>

Result:
-When the content of mywrapper is played directly in the ion-content, everything works like expected
-When ng-content is used, the ion-content with is incorrect (1 full page height too big on chrome, a few pixels too small on firefox, totally missing (height 0) on IE),
-When resizing the browser, ion-content also does not resize!

Images: 1) Without ng-content 2) with ng-content

This can be easily reproduced in the ion-conference app on every page.

So how can I achieve to have 1 common ion-header + ion-content, on many pages of my application, where only the pagecontent + the footer can be different (which means ion-content cannot be its parent, as ion-footer must not be placed in content)

I have read something about refreshing the ion-content size in ngAfterViewInit(), but this was early 2018 and with ionic 4 & 5 it seems like this is no longer an option?

As always, I appreciate any hint in the right direction!

As always, no help from the official forum :stuck_out_tongue:

For anyone facing the same issue, I found a solution after looking into it today:

The problem is that ionic does not work as soon as the page structure is not like this:

<ion-app>
  <ion-header>
     ...
  </ion-header>
  <ion-content>
      ...
  </ion-content>
</ion-app>

Now when using a router outlet, the result is this

<ion-app>
     <ion-router-outlet>
         <example-page class="ion-page">
            <ion-header>
                ...
            </ion-header>
            <ion-content class="ion-padding">
                ...
            </ion-content>
       <example-page>
    </ion-router-outlet>
</ion-app>

Using a common component to have the same header/content behaviour on all pages results in another wrapper element after and , which is the root cause of ionic stuff like correct resizing stopping to work.

The solution:

For any custom component that wraps BEFORE or , add class="ion-page"

<ion-app>
     <ion-router-outlet>
         <example-page class="ion-page">
                <my-custom-header  **class="ion-page"**>
                   <!-- header + content are part of the custom header-->
                  <ion-header>
                      ...
                  </ion-header>
                  <ion-content class="ion-padding">
                     <!-- here comes anything inserted from the actual parent "example-page", replacing the ng-content -->
                      ...
                  </ion-content>
            </my-custom-header>
       <example-page>
    </ion-router-outlet>
</ion-app>

I hope this helps the next one who is doing a little bit more sophisticated applications in ionic :slight_smile:

If this helped you leave a thanks in the comments, this brightens my day :slight_smile:

3 Likes

Thank you so much) It`s realy work for me

Made this account just to thank you @KevinB1 for this solution. Saved me countless hours of debugging and still I think, I would never be able to figure it out myself that it’s just as simple as adding a class to the wrapper component.

What I did was to directly add it to the wrapper :slight_smile:

constructor(private elRef: ElementRef) {
    this.elRef.nativeElement.classList.add('ion-page');
  }

PS: This should be mentioned in docs instead of mentioning that ion-content should be a root element which makes no sense.

1 Like