Ionic 3 / Angular 5 / Chrome Absolute position + z-index problem on mobile device

Viewed 1907

I'm working on an Ionic project where I have a page that displays, for each day of the week, items in horizontal scrolls (ion-slides). It also contains an ion-refresh.

I want to display a label with the name of the day on top of each list so that it overlaps it (in my css; position: absolute + top:... + left: ... + z-index).

When I serve my project and view it in my computer's browser, no problem, it's working fine. But on my Android device (accessing my development server via browser or in compiled app), the following happens : The labels that are visible without scrolling down are OK When I scroll down to see the other days, the labels are displayed behind the items. When I tap a label, it's "refreshed" and displayed correctly until I scroll again. When I pull the ion-refresh, even without getting at the point where the refresh function is triggered, all the labels are and stay displayed correctly.

screen capture of the problem

I guess it's a problem with Angular rendering but I was not able to find out which...

Here is my code:

pages/home/home.html

  <ion-navbar>
    <ion-title>Items</ion-title>
  </ion-navbar>

</ion-header>


<ion-content>

  <ion-refresher (ionRefresh)="doRefresh($event)">
    <ion-refresher-content></ion-refresher-content>
  </ion-refresher>


  <div *ngIf="productStatus == 'loaded'" class="productsContainer">
    <day-products *ngFor="let day of weekdays" [products]="products[day.index]" [day]="day.longName"></day-products>
  </div>
</ion-content>

pages/home/home.ts

import { Component } from '@angular/core';
import { NavController, Refresher } from 'ionic-angular';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

  public weekdays = [
    { longName: "Monday", index: 0 },
    { longName: "Tuesday", index: 1 },
    { longName: "Wednesday", index: 2 },
    { longName: "Thursday", index: 3 },
    { longName: "Friday", index: 4 },
    { longName: "Saturday", index: 5 },
    { longName: "Sunday", index: 6 }
  ];

  products: Array<any>
  productStatus: string;

  constructor(public navCtrl: NavController) {
    this.products = new Array<any>();
    this.productStatus = 'loading';
  }

  ionViewDidLoad() {
    this.fillProductArray();
  }

  fillProductArray() {
    this.productStatus = 'loading';
    this.products = new Array<any>();
    for (let dayIndex = 0; dayIndex < 7; dayIndex++) {
      let day = new Array<any>();
      for (let productIndex = 0; productIndex < 5; productIndex++) {
        day.push({
          name: 'Item ' + productIndex,
          description: 'Description for item ' + productIndex + ' of day number ' + dayIndex
        });
      }
      this.products.push(day);
    }
    this.productStatus = 'loaded';
  }


  doRefresh(refresher: Refresher) {
    this.fillProductArray();
    refresher.complete();
  }

}

pages/home/home.module.ts

import { HomePage } from "./home";
import { NgModule } from "@angular/core";
import { IonicPageModule } from "ionic-angular";
import { DayProductsComponentModule } from "../../components/day-products/day-products.module";


@NgModule({
  declarations: [HomePage],
  imports: [
    IonicPageModule.forChild(HomePage),
    DayProductsComponentModule
  ]
})
export class HomePageModule {}

components/day-products/day-products.html

<div class="wrapper">
  <div class="day-name" ion-button #dayName>{{day}}</div>
  <ion-slides centeredSlides="false" #slider>
    <ion-slide *ngFor="let product of products">
      <div class="card-container">
        <ion-card class="scroll-item" #productCard>
          <div class="image_wrapper">
            <div class="image" [style.backgroundImage]="'url(http://placehold.it/500x500)'">
            </div>
          </div>
          <ion-item class="product" text-wrap>
            <h2>{{product.name}}</h2>
            <p>{{product.description}}</p>
          </ion-item>
        </ion-card>
      </div>
    </ion-slide>
  </ion-slides>
</div>

components/day-products/day-products.scss

day-products {
    .wrapper {
        position: relative;
        .day-name {
            top: -16px;
            left: 24px;
            position: absolute;
            width: 120px;
            padding-top: 0;
            z-index: 100;
        }
        ion-slides {
            margin-top: 10px;
            margin-bottom: 10px;
            padding-top: 8px;
            .swiper-slide {
                height: auto;
                width: 90%;
                .slide-zoom {
                    height: 100%;
                    .card-container {
                        height: calc(100% - 10px);
                        ion-card {
                            margin-top: 0;
                            height: 100%;
                            display: inline-block;
                            .image_wrapper {
                                height: 150px;
                                width: 100%;
                                position: relative;
                                .image {
                                    position: absolute;
                                    width: 100%;
                                    height: 100%;
                                    background-position: center;
                                    background-size: cover;
                                    background-repeat: none;
                                }
                            }
                        }
                    }
                }
            }
            .swiper-slide:only-child {
            width: 100%;
            }
        }
    }
}

components/day-products/day-products.ts

import { Component, ViewChild, Input } from '@angular/core';
import { Slides } from "ionic-angular";

@Component({
  selector: 'day-products',
  templateUrl: 'day-products.html'
})
export class DayProductsComponent {

  @Input()
  day: string;

  @Input()
  products: Array<any>;
  @ViewChild('slider') slider: Slides;

  constructor() {
  }

  ngAfterViewInit() {
    this.slider.freeMode = true;
    this.slider.slidesPerView = 'auto';
  }

}

components/day-products/day-products.module.ts

import { NgModule } from "@angular/core";
import { DayProductsComponent } from "./day-products";
import { IonicModule, } from "ionic-angular";

@NgModule({
    declarations: [DayProductsComponent],
    imports: [
        IonicModule
    ],
    exports: [DayProductsComponent]
})
export class DayProductsComponentModule { }

package.json

{
  "name": "horizontalScrollDemo",
  "version": "0.0.1",
  "author": "Ionic Framework",
  "homepage": "http://ionicframework.com/",
  "private": true,
  "scripts": {
    "start": "ionic-app-scripts serve",
    "clean": "ionic-app-scripts clean",
    "build": "ionic-app-scripts build",
    "lint": "ionic-app-scripts lint"
  },
  "dependencies": {
    "@angular/common": "5.0.3",
    "@angular/compiler": "5.0.3",
    "@angular/compiler-cli": "5.0.3",
    "@angular/core": "5.0.3",
    "@angular/forms": "5.0.3",
    "@angular/http": "5.0.3",
    "@angular/platform-browser": "5.0.3",
    "@angular/platform-browser-dynamic": "5.0.3",
    "@ionic-native/core": "4.4.0",
    "@ionic-native/splash-screen": "4.4.0",
    "@ionic-native/status-bar": "4.4.0",
    "@ionic/storage": "2.1.3",
    "cordova-android": "7.0.0",
    "cordova-plugin-device": "^2.0.2",
    "cordova-plugin-ionic-keyboard": "^2.1.2",
    "cordova-plugin-ionic-webview": "^2.1.4",
    "cordova-plugin-splashscreen": "^5.0.2",
    "cordova-plugin-statusbar": "^2.4.2",
    "cordova-plugin-whitelist": "^1.3.3",
    "ionic-angular": "3.9.2",
    "ionicons": "3.0.0",
    "rxjs": "^5.5.7",
    "sw-toolbox": "3.6.0",
    "zone.js": "0.8.18"
  },
  "devDependencies": {
    "@ionic/app-scripts": "3.1.8",
    "typescript": "2.4.2"
  },
  "description": "An Ionic project",
  "cordova": {
    "plugins": {
      "cordova-plugin-whitelist": {},
      "cordova-plugin-statusbar": {},
      "cordova-plugin-device": {},
      "cordova-plugin-splashscreen": {},
      "cordova-plugin-ionic-webview": {
        "ANDROID_SUPPORT_ANNOTATIONS_VERSION": "27.+"
      },
      "cordova-plugin-ionic-keyboard": {}
    },
    "platforms": [
      "android"
    ]
  }
}

I really would appreciate some help!!

EDIT:

On my device, in Firefox and native browser (Samsung), labels are displayed as they should be. The problem seems to occurs only in Chrome (v. 69.0.3497.100). On my computer, in Chrome and Firefox, display is fine.

2 Answers

I think your ion slides can be breaking your css. Try this way of horizontal scrolling its much more simpler w3schools link.

Related