Fit last item in grid to same space as others [CSS]

I’m trying to make a page that show some items as a grid when the user is using the web app and the same items as a list when using in the mobile app. For this I used the example of this tutorial in Ionic’s blog.

The main problem is that the last item in the grid is showing as a full size item in larger screens:

Another problem is that I configured the column to show a maximum of 4 items in larger screens, but it is showing 5.

Here is what I did:

<ion-grid>
	<ion-row>
		<ion-col *ngFor="let project of projects" col-xs-12 col-xl-3 col-lg-4 col-md-6>
			<ion-item lines="none" class="project-item">
				<ion-thumbnail slot="start"  (click)="openMap(project.projectId, project.name, project.area, project.date)">
					<img src="assets/images/project.png">
				</ion-thumbnail>
				<ion-label>
					<h2>{{project.name}}</h2>
					<p>{{project.user}} • {{project.date}}</p>
				</ion-label>	    
				<ion-button clear slot="end">Opções</ion-button>
			</ion-item>
		</ion-col>
	</ion-row>
</ion-grid>

Where, according to the blog article (modified in my code, maybe this is the problem?):

col-12: If no other rules match, the column will take all 12 units
col-md-4: At a minimum width of 768px, each column will only use 4 units. This means, a row can now handle 3 columns
col-lg-3: As the screen gets bigger than 992px, a column only needs 3 units which means the row now holds 4 columns
col-xl-2: On the largest screens (1200px+), a column only needs 2 units and a row will display 6 columns

While you wait for better answers from somebody who actually uses Ionic’s grid, maybe take a look at CSS Tricks’ Grid Layout Guide. I’m not entirely clear what you’re attempting to achieve, but I am pretty confident that there’s a CSS Grid way of doing it.

I am very poor in CSS knowledge, I am trying to format some pages to be more interesting in the browser layout. My goal on this specific page is to transform this grid into something like Google Drive’s folders when the user is using a tablet or using in browser:

All the items work like expected, but when there is only one or there is an item left at the end, it has this characteristic occupying the entire page. In short, when the screen is at its largest size, I would like the item to be presented in the smallest size, regardless of how many items there are.

I thank you in advance for this link, I will try these methodologies to see if I can solve the problem.

Ok, I couldn’t do with the CSS, but I “solved” the problem in another way. I’m pretty sure this isn’t the best approach, but worked for me:

html

<ion-grid>
	<ion-row>
		<ion-col *ngFor="let project of projects" [size]="columnSize">
			<ion-item lines="none" class="project-item">
				<ion-thumbnail slot="start">
					<img src="assets/images/project.png">
				</ion-thumbnail>
				<ion-label>
					<h2>{{project.name}}</h2>
					<p>{{project.user}} • {{project.date}}</p>
				</ion-label>	    
				<ion-button clear slot="end">Opções</ion-button>
			</ion-item>
		</ion-col>
	</ion-row>
</ion-grid>

ts

columnSize: string = "12";

ngOnInit() {
	this.adjustColumnSize();
	this.platform.resize.subscribe(() => {
		this.adjustColumnSize();
	});
}

adjustColumnSize() {
	this.platform.ready().then(() => {
		if (this.platform.width() < 576) {
			this.columnSize = "12";

		} else if (this.platform.width() > 576 && this.platform.width() < 768) {
			this.columnSize = "6";

		} else if (this.platform.width() > 768 && this.platform.width() < 1200) {
			this.columnSize = "4";

		} else if (this.platform.width() > 1200) {
			this.columnSize = "3";
		}
	});
}

Now that I understand a bit better, I don’t think you really need grid, because you really have a one-dimensional layout. There is a companion guide to flexbox, and the crucial property here is flex-wrap. Something like this (you can play around with the width property of .basket to fit your situation, but I’m assuming you have a sense of how wide a single cell needs to be - this ordinarily is independent of the layout). I used 13 items here so as to have your problematic straggler in virtually all window widths:

 fruits = ["apple", "banana", "cherry", "durian",
    "elderberry", "fig", "grape", "honeydew",
    "jackfruit", "kiwi", "lemon", "mango",
    "nectarine"];
<ion-content>
  <div class="shelf">
    <div class="basket" *ngFor="let fruit of fruits">
      <div class="fruit">{{fruit}}</div>
    </div>
  </div>
</ion-content>
.shelf {
  display: flex;
  flex-wrap: wrap;
}

.basket {
  width: 200px;
  height: 90px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px dotted green;
  margin: 12px;
}

.fruit {
  background-color: #f0afec;
  color: black;
}

The margin setting determines the spacing between cells - if you want, you can break it out into margin-left, margin-top, etc to give more or less horizontal versus vertical padding.

So with the values I gave here, I see four cells per row at >900px window width, dropping to three per row under that, two per row at around 670px, and finally one per row at around 470px.

1 Like

This solution is very interesting, I tried to use it, but I ended up having difficulty making it responsive and changing the width of the items as the screen changed. However it works perfectly if I wanted to keep the item size fixed.

During this attempt, I read again the ion-grid documentation and noticed a page I hadn’t seen before, the ion-col page. There I found exactly what I was looking for and the reason why my initial method didn’t work. Instead of using ex: col-lg-4, I should have used sizeLg = "4" , which will solve the problem without using additional scripts and achive the responsive look. Thank you so much again for your help!

Final code

<ion-grid>
	<ion-row>
		<ion-col *ngFor="let project of projects" sizeSm="12" sizeMd="6" sizeLg="4" sizeXl="3">
			<ion-item lines="none" class="project-item">
				<ion-thumbnail slot="start">
					<img src="assets/images/project.png">
				</ion-thumbnail>
				<ion-label>
					<h2>{{project.name}}</h2>
					<p>{{project.user}} • {{project.date}}</p>
				</ion-label>	    
				<ion-button clear slot="end">Opções</ion-button>
			</ion-item>
		</ion-col>
	</ion-row>
</ion-grid>