Ion-modal-view height and width are too big; scrolling in browser and android (with crosswalk) goes "off-page"

Modal View:


As you can see in the first image, the calculated size of the modal is too large (it runs off the bottom and right of page). This happens on Android build as well (with Crosswalk).

When scrolling to the end of the page, the modal scrolls off page by about 20px or so, and the header bar scrolls out of view. See the second image. This second issue is also happening with a few of my ion-views.

Any idea what’s happening? Thanks!

Can you provide the code the contents of that modal?

Ionic modals usually don’t go bigger than your screen size but in some cases your modal contents might have something that’s forcing the element to go more than 100%.

Absolutely, here it is. I can’t think of anything that’s common between all my modals that might be causing this. Perhaps the slidebox? The modals that are displaying this behavior do all have slideboxes, BUT the ion-view that’s displaying the issue (with height only – width is fine), does not have a slidebox in it.

<ion-modal-view id="productdetails">

  <section ng-controller="cartControl">
<ion-header-bar class="navbar">
  <button unbind-details class="button cartclose button-clear ion-ios-close-empty black lefttap" ng-click="closeModal(2)"></button>
  <h1 class="title">{{thisItem.name}}</h1>
  <div class="detailsbuttonholder buttons">
    <button add-to-favorites-details ng-hide="$root.favorites | inFavorites: thisItem.identifier" class="button button-icon ion-ios-heart-outline"></button>
    <button remove-from-favorites-details ng-show="$root.favorites | inFavorites: thisItem.identifier" class="button button-icon ion-ios-heart"></button>
  </div>
</ion-header-bar>
<article>

  <ion-content delegate-handle="productDetails" id="productdetailscontent" class="productcontentdetails has-footer">

    <ion-slide-box class="detailslide" id="detailsimagewrap" does-continue="true" delegate-handle="productDetails">
      <ion-slide ng-repeat="photo in thisItem.photos | orderObjectBy:'order'" class="detailsimagewrapper">
        <img class="productdetailsimage" ng-src="{{ photo.url }}" spinkit-image-preloader="three-bounce-spinner">
      </ion-slide>
    </ion-slide-box>


    <div class="detailplaceholder"></div>

    <div class="detailscontentwrapper">
      <div class="detailstop">
        <h3>{{ thisItem.name }}</h3>
        <h5 class="detailsubname">{{ thisItem.brand}}</h5>
        <h4>${{thisItem.price}}</h4>
      </div>


      <h5 class="detailsheadline">{{ thisItem.headline }}</h5>
      <p class="detailsdescription">{{ thisItem.description }}</p>

      <ul class="detailsbullets">
        <li ng-repeat="bullet in thisItem.bullets">{{ bullet }}</li>
      </ul>

      <figure ng-if="thisItem.disclaimer" class="detailsdisclaimer">
        <h6>Note:</h6>
        <div>{{ thisItem.disclaimer }}</div>
      </figure>

      <!-- COLOR OPTIONS -->
      <section ng-if="thisItem.colors" class="sizeoptionswrap item-select item item-input">
        <div class="input-label">Color</div>
        <select ng-model="thisItem.clr" ng-init="thisItem.clr=undefined">
          <option value="{{color.name}}" ng-repeat="color in thisItem.colors" ng-if="color.quantity != undefined && color.quantity != ''">{{color.name}}</option>
        </select>
      </section>

      <!-- SIZE OPTIONS -->
      <section ng-if="thisItem.sizes" class="sizeoptionswrap item-select item item-input">
        <div class="input-label">Size</div>
        <select ng-model="thisItem.sz" ng-init="thisItem.sz=undefined">
          <option value="{{size.name}}" ng-repeat="size in thisItem.sizes" ng-if="size.quantity != undefined && size.quantity != ''">{{size.name}}</option>
        </select>
      </section>

      <!-- RECOMMENDED PRODUCTS -->
      <div class="recommendedwrap" ng-controller="shopControl" ng-if="thisItem.recommended || thisItem.recommended2">
        <h5>Makes a great gift with...</h5>
        <article ng-repeat="shop in shops">
          <div show-related ng-repeat="item in shop.products" ng-if="item.identifier == thisItem.recommended || item.identifier == thisItem.recommended2" class="recommendeditem">
            <div class="recommendedimg">
              <img ng-src="{{ item.photos[0] }}">
            </div>
            <h6>{{ item.name }}</h6>
          </div>
        </article>
      </div>


    </div>

  </ion-content>

  <button ng-hide="$state.current.name == 'openorder' || $state.current.name == 'completedorders' || thisItem.quantity == 0" add-to-cart class="footerbutton button button-full product-button">Add to Bag</button>

  <button ng-show="thisItem.quantity == 0" class="soldoutbutton footerbutton button button-full">Sold Out</button>

</article>
   </section>

</ion-modal-view>

Also worth noting that this behavior hasn’t always happened – while I don’t think I’ve made any significant code-base changes that could have caused this change, I have updated ionic versions at various times. Perhaps I should try updating again.

While continuing to debug, I’m noticing a few things:

  1. I removed crosswalk, and the behavior no longer happens in Android. But it still happens in Chrome.

  2. It stops happening in chrome when I turn off device mode in dev tools.

I wouldn’t put any tags outside the ion-content element unless if you’re adding a navbar. Not sure why you have the section and article elements there. These elements probably have width/padding/margin CSS properties that cause your modal to not function properly. Here is how my Ionic 1 modals usually look like:

<ion-modal-view ng-controller="myControllersName">
  <ion-nav-bar>
    <ion-nav-buttons side="left">
      <button class="button button-clear icon ion-close" ng-click="dismiss()"></button>
    </ion-nav-buttons>
    <ion-nav-title>Edit Time Elapsed</ion-nav-title>
    <ion-nav-buttons side="right">
      <button class="button button-clear icon ion-checkmark" ng-click="save()"></button>
    </ion-nav-buttons>
  </ion-nav-bar>
  <ion-content class="has-header padding">
    <!-- my content goes here -->
  </ion-content>
</ion-modal-view>

I’m not sure why I had the section tag in there (there was some reason I thought it necessary a while back, but I can’t remember it – so I removed it). As for the article, I do that so I can have a footer button with fixed positioning on the screen. I removed it (and the buttons) to see if that made a difference – it did not.

the class .has-footer is used if you are using the ion-footer-bar tag.

Here is how I implement footer buttons:

<ion-footer-bar class="bar-light" keyboard-attach>
  <button class="button button-icon icon ion-android-send" ng-click="send()"></button>
</ion-footer-bar>

This code will be between your ion-content closing tag and the ion-modal-view closing tag.

<ion-modal-view ng-controller="myControllersName">
    <ion-nav-bar>
        <ion-nav-buttons side="left">
            <button class="button button-clear icon ion-close" ng-click="dismiss()"></button>
        </ion-nav-buttons>
        <ion-nav-title>Edit Time Elapsed</ion-nav-title>
        <ion-nav-buttons side="right">
            <button class="button button-clear icon ion-checkmark" ng-click="save()"></button>
        </ion-nav-buttons>
    </ion-nav-bar>

    <ion-content class="has-header padding">
        <!-- my content goes here -->
    </ion-content>

    <ion-footer-bar class="bar-light" keyboard-attach>
        <button class="button button-icon icon ion-android-send" ng-click="send()"></button>
    </ion-footer-bar>
</ion-modal-view>
<ion-modal-view id="productdetails" ng-controller="cartControl">
<ion-header-bar class="navbar">
    <button unbind-details class="button cartclose button-clear ion-ios-close-empty black lefttap" ng-click="closeModal(2)"></button>
    <h1 class="title">{{thisItem.name}}</h1>
    <div class="detailsbuttonholder buttons">
        <button add-to-favorites-details ng-hide="$root.favorites | inFavorites: thisItem.identifier" class="button button-icon ion-ios-heart-outline"></button>
        <button remove-from-favorites-details ng-show="$root.favorites | inFavorites: thisItem.identifier" class="button button-icon ion-ios-heart"></button>
    </div>
</ion-header-bar>

<ion-content delegate-handle="productDetails" id="productdetailscontent" class="productcontentdetails has-footer">

    <ion-slide-box class="detailslide" id="detailsimagewrap" does-continue="true" delegate-handle="productDetails">
        <ion-slide ng-repeat="photo in thisItem.photos | orderObjectBy:'order'" class="detailsimagewrapper">
            <img class="productdetailsimage" ng-src="{{ photo.url }}" spinkit-image-preloader="three-bounce-spinner">
        </ion-slide>
    </ion-slide-box>


    <div class="detailplaceholder"></div>

    <div class="detailscontentwrapper">
        <div class="detailstop">
            <h3>{{ thisItem.name }}</h3>
            <h5 class="detailsubname">{{ thisItem.brand}}</h5>
            <h4>${{thisItem.price}}</h4>
        </div>


        <h5 class="detailsheadline">{{ thisItem.headline }}</h5>
        <p class="detailsdescription">{{ thisItem.description }}</p>

        <ul class="detailsbullets">
            <li ng-repeat="bullet in thisItem.bullets">{{ bullet }}</li>
        </ul>

        <figure ng-if="thisItem.disclaimer" class="detailsdisclaimer">
            <h6>Note:</h6>
            <div>{{ thisItem.disclaimer }}</div>
        </figure>

        <!-- COLOR OPTIONS -->
        <section ng-if="thisItem.colors" class="sizeoptionswrap item-select item item-input">
            <div class="input-label">Color</div>
            <select ng-model="thisItem.clr" ng-init="thisItem.clr=undefined">
                <option value="{{color.name}}" ng-repeat="color in thisItem.colors" ng-if="color.quantity != undefined && color.quantity != ''">{{color.name}}</option>
            </select>
        </section>

        <!-- SIZE OPTIONS -->
        <section ng-if="thisItem.sizes" class="sizeoptionswrap item-select item item-input">
            <div class="input-label">Size</div>
            <select ng-model="thisItem.sz" ng-init="thisItem.sz=undefined">
                <option value="{{size.name}}" ng-repeat="size in thisItem.sizes" ng-if="size.quantity != undefined && size.quantity != ''">{{size.name}}</option>
            </select>
        </section>

        <!-- RECOMMENDED PRODUCTS -->
        <div class="recommendedwrap" ng-controller="shopControl" ng-if="thisItem.recommended || thisItem.recommended2">
            <h5>Makes a great gift with...</h5>
            <article ng-repeat="shop in shops">
                <div show-related ng-repeat="item in shop.products" ng-if="item.identifier == thisItem.recommended || item.identifier == thisItem.recommended2" class="recommendeditem">
                    <div class="recommendedimg">
                        <img ng-src="{{ item.photos[0] }}">
                    </div>
                    <h6>{{ item.name }}</h6>
                </div>
            </article>
        </div>

    </div>

</ion-content>
<ion-footer-bar>
    <button ng-if="$state.current.name != 'openorder' && $state.current.name !== 'completedorders' && thisItem.quantity > 0" add-to-cart class="button button-full product-button">Add to Bag</button>
    <button ng-if="thisItem.quantity == 0" class="soldoutbutton button button-full">Sold Out</button>
</ion-footer-bar>
</ion-modal-view>