How do I hide or show content depending on screen size?


#1

Just like Bootstrap, Ionic (Ionic 3) lets us resize the width of a column based on screen size using col-sm-8, col-md-6, col-lg-4. Bootstrap also comes with classes like visible-xs, hidden-sm, etc. that enables us to show or hide content according to the screen size. Does Ionic 3 ship with anything that lets us do the same?


#2

There is no such class or attribute built-in to ionic but we can user angular’s [hidden] attribute with ionic’s platform.width() function to get this done.

in ts file:
public devWidth = this.platform.width();

in html:
<div [hidden]="devWidth > 576">Hello</div>

Hope this helps!


#3

I would suggest looking into SplitPane.


#4

That is proper solution. Thanks!


#5

I was unknown about this feature. Thanks a lot.


#6

@a_nonamous I am glad I could help. Can you please mark it as a solution so that it closes as solved?


#7

same as I wrote in this post:


#8

I would go with sth. like (add it to your app.scss or any other global scss file):

@each $size, $size-value in $screen-breakpoints {
  .hide-#{$size} {
    @media (min-width: $size-value) {
      display: none;
    }
  }
}

This will generate CSS classes hide-xs, hide-sm etc.
show-xs etc. is not so easy because you may need display: block, display: inline-block or any other. So I would stick to hiding if possible.

Here is the list of current Ionic $screen-breakpoints:

(
  xs: 0,
  sm: 576px,
  md: 768px,
  lg: 992px,
  xl: 1200px
)

#9

I’m trying to make use of these in order to make an ion-row hidden when the screen is too small. How should that be done? Here’s what I’ve tried…

in the app.scss

@each $size, $size-value in $screen-breakpoints {
    .hide-#{$size} {
      @media (min-width: $size-value) {
        display: none;
      }
    }
  }

I have this content added to the home.html page from the standard sidemenu template.

<ion-content padding>
    <ion-grid>
        <ion-row class="hide-xs hide-sm">
            <ion-col>
                Top Banner
            </ion-col>
        </ion-row>
       ... more rows and columns

When this page displays I can find the item in the dom, but it doesn’t appear when the window is any size. Of course it shows just fine if I clear the checkboxes for those classes in the dev tools. Am I supposed to use these classes in cooperation with platform.width?

TIA, Mike


#10

It won’t work that way.
hide-xs will hide content on all screen sizes,
hide-sm on all except xs
hide-md on all except sm and xs etc.
It works like hidden-*-up from https://v4-alpha.getbootstrap.com/layout/responsive-utilities/

If you would like to hide only on selected screen size (like hidden-* from http://bootstrapdocs.com/v3.3.6/docs/css/#responsive-utilities) here is the code:

$breakpoints-keys: map-keys($screen-breakpoints);
$breakpoints-values: map-values($screen-breakpoints);
@for $i from 1 to length($breakpoints-keys)+1 {
  @if $i < length($breakpoints-keys) {
    .hidden-#{nth($breakpoints-keys, $i)} {
      @media (min-width: nth($breakpoints-values, $i)) and (max-width: #{nth($breakpoints-values, $i+1)}) {
        display: none;
      }
    }
  } @else {
    .hidden-#{nth($breakpoints-keys, $i)} {
      @media (min-width: nth($breakpoints-values, $i)) {
        display: none;
      }
    }
  }
}

In order to check CSS produced visit https://www.sassmeister.com/gist/d2af1ee566d454337663caa4b462c9ba

Usage example:

<div class="hidden-xs hidden-lg">
Not visible on XS and LG screens, but visible on any other screen sizes
</div>

I’ve turn my answer into a blog post where there is further explanation of SCSS code.


#11

Thank you so much! Now I follow much better what was going on. I combined yours with the first one, and a new one with ‘max’ vs. ‘min’, so I have hide--up, hide--down, and hidden-* to use as needed.

Mike


#12

I like this solution a lot! Thanks for sharing. The only problem is, you overlap some of the sizes. So if it lands on an iPad size for instance (768px) and you have hidden-md or hidden-sm on it, it won’t show up at all because the bound for hidden-md would be: (max-width: 1000px) and (min-width: 768px) and the bound for hidden-sm would be (max-width: 768px) and (min-width: 576px).

So if you wanted to hide something on a smaller screen with hidden-sm and you expect it to show up on the iPad similar to how the splitpane does, it won’t show up because the 768px width is covered on both the hidden-md and the hidden-sm, therefore it will be hidden in either case.

The good news is that all you need is a minor tweak, just add -1 in the max-width setting:

$breakpoints-keys: map-keys($grid-breakpoints);
$breakpoints-values: map-values($grid-breakpoints);
@for $i from 1 to length($breakpoints-keys)+1 {
  @if $i < length($breakpoints-keys) {
    .hidden-#{nth($breakpoints-keys, $i)} {
      @media (min-width: nth($breakpoints-values, $i)) and (max-width: #{nth($breakpoints-values, $i+1) - 1}) {
        display: none !important;
      }
    }
  } @else {
    .hidden-#{nth($breakpoints-keys, $i)} {
      @media (min-width: nth($breakpoints-values, $i)) {
        display: none !important;
      }
    }
  }
}

Also, something to think about:
With this set up it’s great for hiding stuff, but if you have any async pipes in your DOM that you have hidden it’ll still subscribe to that observable. If you don’t want it to run the observable then you need to remove it from the DOM with *ngIf