How to implement Best Fit Layout like google meet with grid using tailwind

Viewed 1009

I want to build a video conference screen layout using Tailwindcss, I want it to fit items automatically in cols and rows:

enter image description here

enter image description here

enter image description here

If I style like this:

<div class="grid grid-flow-col gap-4">
    <video-app class="video" *ngFor="let video of studentsVideo" [video]="video" ></video-app>
</div>

it only expands columns and does not create new rows. how can I style this layout?

Update:

We know that we have users to join the conference. we have the length of users and we can dynamically set grid-cols-{n} and grid-rows-{n} but how we can calculate it to detect the best-fit numbers for rows and cols?

thank you.

3 Answers

You can define variable with grid-cols-{} and grid-rows-{}, check official to use Grid Flow

so try this,

<div class="grid grid-flow-col grid-cols-4 grid-rows-4 gap-4 bg-gray-200">
...
    <video-app class="video bg-red-300 text-center" *ngFor="let video of studentsVideo" [video]="video" >5</video-app>
    <video-app class="video bg-red-300 text-center" *ngFor="let video of studentsVideo" [video]="video" >6</video-app>
...
</div>

check tailwind.playground

Answer to additional question:

If you can with javascript then you will be able to adjust it easily :)

The Math.sqrt() function returns the square root of a number, that is

1 => 1

2 => 2

4 => 2*2

9 => 3*3

...

  const totalMembers = 4;
  const shape = round(Math.sqrt(totalMembers));
  const result = `grid-cols-${shape} grid-rows-${shape}`;
  const VideoComponent = () => <video-app class="video" *ngFor="let video of studentsVideo" [video]="video" >6</video-app>;

    return (
    <div class={`grid grid-flow-col ${result} gap-4 bg-gray-200 min-w-full`}>
        {
          let i =0;
          while (i < totalMembers) {
           return <VideoComponent />
          }
        }
    </div>
  );

As you are using Angular I answer in Angular too. You can easily do this by using [ngClass]:

<div class="grid grid-flow-col"
[ngClass]="{
'grid-cols-1': currentUsers.length === 1,
'grid-cols-2': currentUsers.length > 1 && currentUsers.length <= 4,
'grid-cols-3': currentUsers.length > 4 && currentUsers.length <= 9,
'grid-cols-4': currentUsers.length > 9
}"
...
</div>

by using this code on your grid element you can vary the columns of the grid based on user count.

Feel free to play around with it in the Stackblitz I made.

Thanks to @JsWizard and @Al00X,

I mixed your solutions together:

Component.ts

calculateGridLayout() {
        this.gridLayoutColsCount = Math.ceil(Math.sqrt(this.studentsVideo.length));
    }

Component.html

<div
    [ngClass]="[
        'grid',
        'grid-cols-' + gridLayoutColsCount,
        'grid-rows-' + gridLayoutColsCount,
        'gap-4'
    ]"
>
    <video
        *ngFor="let video of studentsVideo"
        [video]="video"
    ></video>
</div>
Related