Search code examples
angulardomstylingngfor

Styling dom elements generated by ngfor


Background: So im gettting some data from the back end that I'm storing as an Array on my Angular front end. Now Im trying to display each of these elements (which are products) on the template. What I'm basically trying to achieve is products on a page that users can browse.

Problem: The problem is that ngfor is simply drawing the elements one after the other in a vertical line on the template. What I want is to be able to apply general style settings(perhaps on the parent element hosting ngfor?) so the elements go from the top left of the page to the top right in a line from 1 to X number of elements according to viewport width, and then continue as such on the following rows untill there are none left in the original array. PS. I have tried using css grid and flexbox in the parent element but they simply get ignored by the template.

I would appreciate if someone could point me in the direction from where I could achieve the desired outcome.

My Template code is as follows:

<div id="backGroundImage">
  <div id="salesPageContainer">
    <div id="saleItemsContainer" >
      <div *ngFor="let saleItem of saleItems" id="itemContainer" >
        <p id="itemName">{{ saleItem.itemName }}</p>
        <p id="itemPrice">{{ saleItem.itemPrice }}</p>
        <img [src]="imageUrl + saleItem.imageID" alt="" id="itemImage" />
      </div>
    </div>
  </div>
</div>

Solution

  • Check sample implementation here WORKING STACKBLITZ

    If you have bootstrap in your app add class="d-flex flex-wrap" like below

    <div id="backGroundImage">
      <div id="salesPageContainer">
        <div id="saleItemsContainer" class="d-flex flex-wrap">
          <div *ngFor="let saleItem of saleItems" id="itemContainer" >
            <p id="itemName">{{ saleItem.itemName }}</p>
            <p id="itemPrice">{{ saleItem.itemPrice }}</p>
            <img [src]="imageUrl + saleItem.imageID" alt="" id="itemImage" />
          </div>
        </div>
      </div>
    </div>
    

    In plain css apply css display: flex; flex-wrap: wrap; to id="saleItemsContainer"

    <div id="backGroundImage">
      <div id="salesPageContainer">
        <div id="saleItemsContainer">
          <div *ngFor="let saleItem of saleItems" id="itemContainer" >
            <p id="itemName">{{ saleItem.itemName }}</p>
            <p id="itemPrice">{{ saleItem.itemPrice }}</p>
            <img [src]="imageUrl + saleItem.imageID" alt="" id="itemImage" />
          </div>
        </div>
      </div>
    </div>
    

    Using CSS Grid

    <div id="backGroundImage">
      <div id="salesPageContainer">
        <div id="saleItemsContainer">
          <div *ngFor="let saleItem of saleItems" id="itemContainer" >
            <p id="itemName">{{ saleItem.itemName }}</p>
            <p id="itemPrice">{{ saleItem.itemPrice }}</p>
            <img [src]="imageUrl + saleItem.imageID" alt="" id="itemImage" />
          </div>
        </div>
      </div>
    </div>
    

    Add css to saleItemsContainer

    #saleItemsContainer {
      display: grid;
      grid-column-gap: 0.5rem;
      grid-row-gap: 0.4rem;
      grid-template-columns: auto auto auto;
    }