SimpleGrid

An even grid whose column count follows a minimum column width.

ATRI

Sci-fi

Sakura no Uta

Drama

Afternoon at the Observatory

Slice of life

The Other Side of the Galaxy

Sci-fi
<script setup lang="ts">
  import { AspectRatio, Card, SimpleGrid, Stack, Tag, Text } from '@hina-ui/vue'

  const works = [
    { title: 'ATRI', tag: 'Sci-fi' },
    { title: 'Sakura no Uta', tag: 'Drama' },
    { title: 'Afternoon at the Observatory', tag: 'Slice of life' },
    { title: 'The Other Side of the Galaxy', tag: 'Sci-fi' },
  ]
</script>

<template>
  <SimpleGrid min="12rem" class="w-full max-w-2xl">
    <Card v-for="work in works" :key="work.title">
      <Stack gap="xs" align="start">
        <AspectRatio class="bg-inset w-full rounded-md" />
        <Text class="font-medium">{{ work.title }}</Text>
        <Tag>{{ work.tag }}</Tag>
      </Stack>
    </Card>
  </SimpleGrid>
</template>
vue

Usage

import { SimpleGrid } from '@hina-ui/vue'
ts

min is the smallest a column may be; the container fits as many equal columns as it can. The count follows the width of the container, so no breakpoints are needed. Use Grid where the count is fixed.

1
2
3
4
5
6
<script setup lang="ts">
  import { Card, SimpleGrid } from '@hina-ui/vue'
</script>

<template>
  <SimpleGrid min="8rem" class="w-full max-w-lg">
    <Card v-for="i in 6" :key="i" class="bg-inset grid h-16 place-items-center" :padded="false">
      {{ i }}
    </Card>
  </SimpleGrid>
</template>
vue

Examples

Minimum column width

min takes any CSS length and defaults to 14rem. The larger it is, the fewer columns fit in the same container.

min 6rem

min 10rem

min 16rem

<script setup lang="ts">
  import { Card, SimpleGrid, Stack, Text } from '@hina-ui/vue'

  const mins = ['6rem', '10rem', '16rem'] as const
</script>

<template>
  <Stack class="w-full max-w-lg">
    <Stack v-for="min in mins" :key="min" gap="xs">
      <Text tone="muted" size="sm">min {{ min }}</Text>
      <SimpleGrid :min="min" gap="sm">
        <Card v-for="i in 4" :key="i" class="bg-inset h-10" :padded="false" />
      </SimpleGrid>
    </Stack>
  </Stack>
</template>
vue

Filling the row

Tracks are laid out with auto-fill by default: the container divides into as many columns as it can hold, and empty tracks remain on the right when there are too few children. Setting fit switches to auto-fit, where empty tracks collapse and the children present share the whole row.

auto-fill by default: empty tracks stay, each item keeps one cell

1
2

With fit: empty tracks collapse and the two items share the row

1
2
<script setup lang="ts">
  import { Card, SimpleGrid, Stack, Text } from '@hina-ui/vue'
</script>

<template>
  <Stack class="w-full max-w-lg">
    <Stack gap="xs">
      <Text tone="muted" size="sm">
        auto-fill by default: empty tracks stay, each item keeps one cell
      </Text>
      <SimpleGrid min="8rem" gap="sm">
        <Card v-for="i in 2" :key="i" class="bg-inset grid h-12 place-items-center" :padded="false">
          {{ i }}
        </Card>
      </SimpleGrid>
    </Stack>
    <Stack gap="xs">
      <Text tone="muted" size="sm">
        With fit: empty tracks collapse and the two items share the row
      </Text>
      <SimpleGrid min="8rem" gap="sm" fit>
        <Card v-for="i in 2" :key="i" class="bg-inset grid h-12 place-items-center" :padded="false">
          {{ i }}
        </Card>
      </SimpleGrid>
    </Stack>
  </Stack>
</template>
vue

Gap

gap behaves as it does in Grid: the md step is 12 pixels between columns and 16 between rows, and every other step is the same on both axes.

API

Prop
Type
Default
Description
min
string
'14rem'
Smallest width of a column
fit
boolean
false
Whether empty tracks collapse
gap
'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl'
'md'
Space between cells
as
string
'div'
The rendered tag
class
string
—
Classes appended to the container
Slot
Description
default
The children