BeniaminoBaggins
BeniaminoBaggins

Reputation: 12433

Angular 2 *ngFor causing bootstrap 4 column content to be too skinny

I have a results div that displays search results. The results are in bootstrap columns. However, the columns appear to have a heap of padding or margin, causing my results to be super skinny. If I take out the *ngFor and instead hardcode each result, it displays correctly.

Here is the div that iterates over a list of results, creating a result to display for each result:

<div id="results" class="text-uppercase">
    <div id="up-button-row" class="row">
        <div class="col-sm-8 offset-sm-2 col-md-6 offset-md-3 col-xl-4 
            offset-xl-4">
            <button id="up-button" class="m-x-auto" md-fab [disableRipple]="true" (click)="scrollUp()"></button>
        </div>
    </div>
    <div class="row" *ngIf="noResults">
        <div class="col-sm-8 offset-sm-2 col-md-6 offset-md-3 col-xl-4 
            offset-xl-4">
            <h2 class="m-x-auto">No vegan stuff found :-(</h2>
        </div>
    </div>
    <div class="row" *ngIf="!noResults">
        <div *ngFor="let result of results">
            <result [result]="result"></result>
        </div>
    </div>
</div>

this is the bit that holds the search results:

<div class="row" *ngIf="!noResults">
    <div *ngFor="let result of results">
        <result [result]="result"></result>
    </div>
</div>

Each search result is a component called result.component. Here is the template for that:

<div class="col-sm-6 col-md-4 col-xl-3">
   <div class="product-item scale-on-hover">
      <div [ngStyle]="{background: result.image}" id="image"></div>
      <div id="info">
         <h6 id="brand" class="medium-text">{{result.brand}}</h6>
         <h6 id="name" class="medium-text">{{result.name}}</h6>
      </div>
   </div>
</div>

For some reason, the results are super skinny, cutting out most of the content in the result.

Here is an image of what I mean:

enter image description here

So that is hovering over the actual result (which I am calling a product item).

Here is hovering over the bootstrap column:

enter image description here

So the column seems to have a heap of padding or margin.

Here is the output styling of the column copy and pasted from the styles tab of the console in Google Chrome:

element.style {
}
@media (min-width: 1200px)
.col-xl-3 {
    -webkit-box-flex: 0;
    -webkit-flex: 0 0 25%;
    -ms-flex: 0 0 25%;
    flex: 0 0 25%;
    max-width: 25%;
}
@media (min-width: 768px)
.col-md-4 {
    -webkit-box-flex: 0;
    -webkit-flex: 0 0 33.333333%;
    -ms-flex: 0 0 33.333333%;
    flex: 0 0 33.333333%;
    max-width: 33.333333%;
}

@media (min-width: 544px)
.col-sm-6 {
    -webkit-box-flex: 0;
    -webkit-flex: 0 0 50%;
    -ms-flex: 0 0 50%;
    flex: 0 0 50%;
    max-width: 50%;
}
.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12 {
    position: relative;
    min-height: 1px;
    padding-right: 15px;
    padding-left: 15px;
    width: 100%;
}
*, *::before, *::after {
    -webkit-box-sizing: inherit;
    box-sizing: inherit;
}
user agent stylesheet
div {
    display: block;
}
Inherited from div#results.text-uppercase
.text-uppercase {
    text-transform: uppercase !important;
}
Inherited from body
body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    font-size: 1rem;
    line-height: 1.5;
    color: #373a3c;
    background-color: #fff;
}
Inherited from html
html {
    font-size: 16px;
    -ms-overflow-style: scrollbar;
    -webkit-tap-highlight-color: transparent;
}
html {
    font-family: sans-serif;
    -ms-text-size-adjust: 100%;
    -webkit-text-size-adjust: 100%;
}
Pseudo ::before element
*, *::before, *::after {
    -webkit-box-sizing: inherit;
    box-sizing: inherit;
}
Pseudo ::after element
*, *::before, *::after {
    -webkit-box-sizing: inherit;
    box-sizing: inherit;
}

Why are the results so skinny? What is causing the margin or padding in the bootstrap columns? The default width is 100%. I want the width of each result to be 100% of the column width. I cannot set a static width. I need them to scale with the bootstrap columns.

Here is my css for results:

#results {
  overflow-y: auto;
  overflow-x: hidden;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-bottom: 50px;
  padding-top: 10px; }

h1 {
  margin-left: 25px;
  color: #ff8282; }

h2 {
  color: #ff8282;
  text-align: center; }

button {
  display: inherit;
  background: #00BFA5 url("../images/up-arrow.png") center no-repeat;
  background-size: 40%;
  position: fixed;
  top: 60px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 9999; }

#up-button-row {
  padding-bottom: 40px; }

Here is my css for result:

#image {
  height: 160px;
  border-top-left-radius: 10px;
  border-top-right-radius: 10px;
  color: white;
  background: center no-repeat;
  background-size: cover;
  vertical-align: bottom; }

#info {
  height: 110px;
  padding: 10px;
  background: #fc4747; }

#brand {
  text-transform: uppercase;
  color: white;
  margin-top: 0;
  margin-bottom: 5px; }

#name {
  text-transform: uppercase;
  color: white;
  margin-bottom: 5px;
  display: inline; }

div.product-item.scale-on-hover:hover {
  transform: scale(1.15); }

div.product-item {
  border: 5px solid brand-red;
  border-radius: 15px;
  height: 240px;
  overflow: hidden;
  cursor: pointer; }

edit: when I change the bootstrap column to col-xl-12 it looks like this:

enter image description here

So weird. col-xl-12 should make the column take up the whole width of the screen as I'm on an xl size screen.

It is something to do with the bootstrap row. Because I have 10 results, they do not all fit on one row. However I thought bootstrap simply pushes content down to a new row if content goes over the allotted columns.

If I take out class="row" I get this:

enter image description here

If I hardcode the results into the results template like this instead of using *ngfor, it works!! But i need to iterate over the list rather than hardcode :(

<div id="results" class="text-uppercase">
    <div id="up-button-row" class="row">
        <div class="col-sm-8 offset-sm-2 col-md-6 offset-md-3 col-xl-4 
            offset-xl-4">
            <button id="up-button" class="m-x-auto" md-fab [disableRipple]="true" (click)="scrollUp()"></button>
        </div>
    </div>
    <div class="row" *ngIf="noResults">
        <div class="col-sm-8 offset-sm-2 col-md-6 offset-md-3 col-xl-4 
            offset-xl-4">
            <h2 class="m-x-auto">No vegan stuff found :-(</h2>
        </div>
    </div>
    <div class="row" *ngIf="!noResults">
        <!--<div *ngFor="let result of results">
            <result [result]="result"></result>
        </div>-->
        <div class="col-sm-6 col-md-4 col-xl-3">
   <div class="product-item scale-on-hover">
      <div  id="image"></div>
      <div id="info">
         <h6 id="brand" class="medium-text">result.brand</h6>
         <h6 id="name" class="medium-text">result.name</h6>
      </div>
   </div>
</div>
<div class="col-sm-6 col-md-4 col-xl-3">
   <div class="product-item scale-on-hover">
      <div  id="image"></div>
      <div id="info">
         <h6 id="brand" class="medium-text">result.brand</h6>
         <h6 id="name" class="medium-text">result.name</h6>
      </div>
   </div>
</div>
<div class="col-sm-6 col-md-4 col-xl-3">
   <div class="product-item scale-on-hover">
      <div  id="image"></div>
      <div id="info">
         <h6 id="brand" class="medium-text">result.brand</h6>
         <h6 id="name" class="medium-text">result.name</h6>
      </div>
   </div>
</div>
<div class="col-sm-6 col-md-4 col-xl-3">
   <div class="product-item scale-on-hover">
      <div  id="image"></div>
      <div id="info">
         <h6 id="brand" class="medium-text">result.brand</h6>
         <h6 id="name" class="medium-text">result.name</h6>
      </div>
   </div>
</div>
<div class="col-sm-6 col-md-4 col-xl-3">
   <div class="product-item scale-on-hover">
      <div  id="image"></div>
      <div id="info">
         <h6 id="brand" class="medium-text">result.brand</h6>
         <h6 id="name" class="medium-text">result.name</h6>
      </div>
   </div>
</div>
<div class="col-sm-6 col-md-4 col-xl-3">
   <div class="product-item scale-on-hover">
      <div  id="image"></div>
      <div id="info">
         <h6 id="brand" class="medium-text">result.brand</h6>
         <h6 id="name" class="medium-text">result.name</h6>
      </div>
   </div>
</div>
<div class="col-sm-6 col-md-4 col-xl-3">
   <div class="product-item scale-on-hover">
      <div  id="image"></div>
      <div id="info">
         <h6 id="brand" class="medium-text">result.brand</h6>
         <h6 id="name" class="medium-text">result.name</h6>
      </div>
   </div>
</div>
<div class="col-sm-6 col-md-4 col-xl-3">
   <div class="product-item scale-on-hover">
      <div  id="image"></div>
      <div id="info">
         <h6 id="brand" class="medium-text">result.brand</h6>
         <h6 id="name" class="medium-text">result.name</h6>
      </div>
   </div>
</div>
<div class="col-sm-6 col-md-4 col-xl-3">
   <div class="product-item scale-on-hover">
      <div  id="image"></div>
      <div id="info">
         <h6 id="brand" class="medium-text">result.brand</h6>
         <h6 id="name" class="medium-text">result.name</h6>
      </div>
   </div>
</div>
<div class="col-sm-6 col-md-4 col-xl-3">
   <div class="product-item scale-on-hover">
      <div  id="image"></div>
      <div id="info">
         <h6 id="brand" class="medium-text">result.brand</h6>
         <h6 id="name" class="medium-text">result.name</h6>
      </div>
   </div>
</div>
    </div>
</div>

result (never mind the image not being there - I just didnt add it):

enter image description here

I am open to workarounds such as not having a seperate component for the result, or trying to use something other than *ngFor to iterate the results collection. However the result will get more complex so ideally it should be a seperate component.

Here is a jsfiddle. It has console errors, however, it is only one component so if you can make an angular 2 jsfiddle with that exact component that doesn't have any console errors then we are in business: https://jsfiddle.net/n5pjgev6/89/ I started it from this one: https://jsfiddle.net/langdonx/u7c89uuz/ Now I am not sure which version of angular 2 he used so that may be the issue. I cannot find the angular 2 cdn. He bootstraps the app with different syntax than rc5. However, my component doesnt really look like it has anything that is rc5 specific so I wouldn't have thought it would matter.

Upvotes: 2

Views: 6249

Answers (2)

Michel Douglas Tank
Michel Douglas Tank

Reputation: 51

Other answer doens't work for me, but this works:

<div class="row">
<div *ngFor="let item of items" class="col-md-4 col-sm-6 col-12">
    <p>{{item.awesome}}</p>
</div>
</div>

Upvotes: 3

ssuhas76
ssuhas76

Reputation: 103

the below code worked for me. One more thing to note here - I forgot to include the bootstrap.css in the index.html file. Please check that as well

<div class="container">
<div *ngIf='projects && projects.length'>
    <div class="row">
    <div *ngFor='let project of projects'> 
        <div class="col-md-3 col-sm-4 col-xs-6">
        <h4>{{project.by}}</h4>
        </div>
    </div>
    </div>
</div>
</div>

Upvotes: 0

Related Questions