Search code examples
csstailwind-csscss-grid

How do I center/stretch a grid layout if there are fewer items than columns?


I want a responsive grid layout where the number of columns changes dynamically based on screen size. If there are fewer items than columns, they should use the available space or at least be centered and not aligned on the left side.

Basically: "If you have many items, then you are allowed to put a maximum of x items in a row on screen size y. If you have less items than you are allowed to display in a row, then use the available space in the row."

Any idea how to solve that with css?

I am using tailwind in a nextjs project and this are my classes so far:

px-2.5 grid grid-cols-1 mobile:grid-cols-2 tablet:grid-cols-3 laptop:grid-cols-4 desktop:grid-cols-5 gap-y-12 gap-x-1 w-full font-lrg font-medium flex-1 bg-white

Solution

  • I'm afraid using a fixed predefined number of columns won't achieve this effect. The closest method I can think of is using a responsive grid.

    Specifically, by using auto-fit, the grid will occupy all the space even when there are not enough child elements. Then, by limiting the maximum width of elements in the repeat function, you can achieve a responsive layout for the child elements:

    <script src="https://cdn.tailwindcss.com/3.4.5"></script>
    
    <ul class="grid grid-cols-[repeat(auto-fit,minmax(200px,1fr))] gap-x-1 gap-y-12">
      <li class="h-32 bg-amber-200"></li>
      <li class="h-32 bg-amber-200"></li>
      <li class="h-32 bg-amber-200"></li>
      <li class="h-32 bg-amber-200"></li>
    </ul>

    (👆Change the viewport width to see the effect.)

    Demo on Tailwind Play


    You need to adjust the allowed width of the child elements (here it is 200px) based on your actual requirements to achieve the best visual effect. You can also use multiple column definitions with different widths depending on the viewport width to achieve better control:

    <ul class="grid grid-cols-[repeat(auto-fit,minmax(200px,1fr))] lg:grid-cols-[repeat(auto-fit,minmax(320px,1fr))] gap-x-1 gap-y-12">
      <!-- ... -->
    </ul>