FlameDra
FlameDra

Reputation: 2087

How to ensure a CSS grid has cards with fixed width and height using Tailwind CSS

I'm using Tailwind CSS and React to build an app, and in one of view I have a grid of cards. Currently it looks something like this:

enter image description here


enter image description here


enter image description here


As you can see, the cards squeeze in as I make the window smaller. I want to ensure that the cards size (width and height) always stays the same, and it just moves to the next row if the amount of cards don't fit on one row as the window gets smaller.

Something like (made in MS paint):

enter image description here


enter image description here


enter image description here


Where the size of the cards stay fixed (same aspect ratio) even though the screen is getting smaller.

Here's how my code looks currently:

Grid:

<div>
    <ul className="grid grid-cols-1 gap-4 sm:grid-cols-2 sm:gap-4 md:grid-cols-6 md:gap-4 lg:grid-cols-8 lg:gap-4">
        {props.trips.map((trip: TTrip) => (
            <TripCard trip={trip} href={currentPath + trip.id} />
        ))}
    </ul>
</div>

Card:

    <li
        key={props.trip.id}
        className="card card-compact shadow-xl col-span-1 w-128 h-fit bg-gray-100 hover:bg-base-200"
    >
        <div className="relative w-128 h-32">
            <Image src="https://placeimg.com/500/225/arch" layout="fill" objectFit="cover" />
        </div>
        <div className="card-body">
            <h2 className="card-title">{props.trip.name}</h2>
            <h2>Time - Time</h2>
        </div>
    </li>

Any idea how to set this up using tailwind-css?

Upvotes: 1

Views: 4850

Answers (2)

sayandcode
sayandcode

Reputation: 3204

I know you wanted to set this up using Grid, but unfortunately, it is not the right tool for this job. Flexbox would be best suited for your needs. Here is a tailwind playground that shows your desired output. The playground I linked doesn't use NextJS, as it does in your example. So, I have modified a few things such as images, as they are non-NextJS specific.

I have modified the styling a bit, in a way I felt is more efficient. Namely, I have moved the width setting from the image, to the container div. You can further modify this setup, as per your requirement.

In your setup, the code would translate roughly like this.

// Grid
<div>
    <ul className="flex flex-row gap-4 flex-wrap">
        {props.trips.map((trip: TTrip) => (
            <TripCard trip={trip} href={currentPath + trip.id} />
        ))}
    </ul>
</div>

// Card
    <li
        key={props.trip.id}
        className="card card-compact shadow-xl col-span-1 w-32 md:w-72 lg:w-96 h-fit bg-gray-100 hover:bg-base-200"
    >
        <div className="relative h-32">
            <Image src="https://placeimg.com/500/225/arch" layout="fill" objectFit="cover" />
        </div>
        <div className="card-body">
            <h2 className="card-title">{props.trip.name}</h2>
            <h2>Time - Time</h2>
        </div>
    </li>

Here's how it would look:

Largest with wrapping

Largest with wrapping

Medium without wrapping

Medium without wrapping

Small without wrapping

Small without wrapping

Small with wrapping

Small with wrapping

The exact breakpoints where the size and wrapping changes, depends on how you decide to implement it. If you are unhappy with the above points, you can simply modify the lg, md prefixes, as per your needs.

Upvotes: 2

krishnaacharyaa
krishnaacharyaa

Reputation: 24940

The simplest way of getting this done is via flex and flex-wrap and setting fixed desired height and width for the cards

Code Structure:

<div class="flex flex-wrap"> 👈 Use flex flex-wrap
    <card>
    <card>
    <card>
</div>

Tailwind-play


Code:

<div class="flex flex-wrap">
  <div class="w-56 rounded-lg bg-gray-200 shadow-lg">
    <div class="h-40"><img src="https://placeimg.com/500/225/hous" class="h-full" /></div>
    <div class="pl-2 text-4xl">Title</div>
    <div class="pl-2 text-2xl">Subtitle</div>
  </div>
  <div class="w-56 rounded-lg bg-gray-200 shadow-lg">
    <div class="h-40"><img src="https://placeimg.com/500/225/hous" class="h-full" /></div>
    <div class="pl-2 text-4xl">Title</div>
    <div class="pl-2 text-2xl">Subtitle</div>
  </div>
  <div class="w-56 rounded-lg bg-gray-200 shadow-lg">
    <div class="h-40"><img src="https://placeimg.com/500/225/hous" class="h-full" /></div>
    <div class="pl-2 text-4xl">Title</div>
    <div class="pl-2 text-2xl">Subtitle</div>
  </div>
  <div class="w-56 rounded-lg bg-gray-200 shadow-lg">
    <div class="h-40"><img src="https://placeimg.com/500/225/hous" class="h-full" /></div>
    <div class="pl-2 text-4xl">Title</div>
    <div class="pl-2 text-2xl">Subtitle</div>
  </div>
  <div class="w-56 rounded-lg bg-gray-200 shadow-lg">
    <div class="h-40"><img src="https://placeimg.com/500/225/hous" class="h-full" /></div>
    <div class="pl-2 text-4xl">Title</div>
    <div class="pl-2 text-2xl">Subtitle</div>
  </div>
  <div class="w-56 rounded-lg bg-gray-200 shadow-lg">
    <div class="h-40"><img src="https://placeimg.com/500/225/hous" class="h-full" /></div>
    <div class="pl-2 text-4xl">Title</div>
    <div class="pl-2 text-2xl">Subtitle</div>
  </div>
  <div class="w-56 rounded-lg bg-gray-200 shadow-lg">
    <div class="h-40"><img src="https://placeimg.com/500/225/hous" class="h-full" /></div>
    <div class="pl-2 text-4xl">Title</div>
    <div class="pl-2 text-2xl">Subtitle</div>
  </div>
</div>

Output in different screens:

enter image description here

enter image description here

Upvotes: 1

Related Questions