2
votes

Using Ionic 3 Framework and components, attributes, properties only (no media queries if possible), does someone know how to define a responsive grid based on screen-orientation? I want the layout to be displayed in one column when screen-orientation is "portrait" and in two columns when screen-orientation is "landscape", no matter what the screen size is.

I did it using the showWhen attribute like below but it makes me duplicate the code contained in each <ion-col>.

Is there any better solution?

<ion-grid>
  <ion-row>
    <ion-col showWhen="portrait" col-12>
    ...[content_1]...
    </ion-col>
    <ion-col showWhen="landscape" col-6 push-6>
    ...[content_1]...
    </ion-col>
    <ion-col showWhen="portrait" col-12>
    ...[content_2]...
    </ion-col>
    <ion-col showWhen="landscape" col-6 push-6>
    ...[content_2]...
    </ion-col>
  </ion-row>
</ion-grid>
2

2 Answers

0
votes

found ! Using the screen-orientation plugin. That's better because I don't have to duplicate the code like my previous solution.

<ion-grid>
  <ion-row>

    <ion-col [attr.col-12]="screenOrientation.type == 'portrait-primary' ? true : null" [attr.col-6]="screenOrientation.type == 'landscape-primary' ? true : null" [attr.push-6]="screenOrientation.type == 'landscape-primary' ? true : null">
    ...[content_1]...
    </ion-col>

    <ion-col [attr.col-12]="screenOrientation.type == 'portrait-primary' ? true : null" [attr.col-6]="screenOrientation.type == 'landscape-primary' ? true : null" [attr.pull-6]="screenOrientation.type == 'landscape-primary' ? true : null" >
    ...[content_2]...
    </ion-col>

  </ion-row>
</ion-grid>
0
votes

screen-orientation type can be known using the screen-orientation plugin https://ionicframework.com/docs/native/screen-orientation/

if there is only one row:

<ion-grid>
   <ion-row>

           // show columns in the row depending on what screen-orientation type

           <div *ngFor="let content of contents">
               <ion-col *ngIf="screen-orientation-type = 'portrait'" col-6>
                   <div text-wrap [innerHtml]="content.title"></div>
                   <div text-wrap [innerHtml]="content.body"></div>
               </ion-col>
               <ion-col *ngIf="screen-orientation-type = 'landscape'" col-12>
                   <div text-wrap [innerHtml]="content.title"></div>
                   <div text-wrap [innerHtml]="content.body"></div>
               </ion-col>
           </div>
   </ion-row>
</ion-grid>

if you are getting the contents from a server, create an api that will return content values

or set your content list in the ts

contents:[
    {
        title?: string,
        body?: string 
    },
    {
        title?: string,
        body?: string 
    }
];

in same ts file under constructor:

this.contents = [
    {
        title: '<h1>Content 1</h1>',
        body: '<p>Body here</p>'
    },
    {
        title: '<h1>Content 2</h1>',
        body: '<p>Body here</p>'
    }
]