A 3x3 grid in CSS is created by setting both grid-template-columns and grid-template-rows to repeat(3, 1fr) on a parent element with display: grid, then placing nine child items inside it. The shorthand repeat(3, 1fr) tells the browser to draw three equal columns and three equal rows, and each direct child automatically flows into the next available cell. To control spacing between the cells you add a gap value, and to control how every item sits inside its cell you use justify-items and align-items. The full minimal declaration looks like this: .grid { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr); gap: 10px; }, with nine children inside <div class="grid">.

The reason a 3x3 layout comes up so often is that it is one of the smallest two-dimensional grids that still feels balanced on a page. A 2x2 layout is a quadrant, a 4x4 starts looking like a control panel, but 3x3 hits a sweet spot for image galleries, feature matrices, dashboard tiles, Tic-Tac-Toe boards, pricing summaries, and onboarding screens. CSS Grid is the right tool for the job because it works on two axes at once, unlike Flexbox which only handles one. The CSS Grid specification is maintained by the W3C and is fully supported in every current browser, so the declarations you write today will still render correctly years from now.

how to make 3x3 grid css
how to make 3x3 grid css

What You Need Before You Start

You only need three things: an HTML file, a CSS file (or a <style> block), and a way to test the result in a browser. The HTML should contain one parent container and nine child elements, because a 3x3 grid has nine cells. The parent gets a class or id you can target in CSS, and the children can be <div>, <button>, <img>, or anything else that flows as a block-level element.

You do not need any build tooling, framework, or JavaScript. CSS Grid is part of plain CSS, which means the same rules apply whether you are working in a static HTML file, a React component, a Vue template, or a WordPress theme. The only thing that changes between frameworks is how the markup is generated, not how the grid is defined.

Choosing the Right Column and Row Values

For a true 3x3 grid, both axes must repeat three times. The most common unit is 1fr, which means "one fraction of the available space." Three columns of 1fr split the container width into three equal slices, and three rows of 1fr split the container height the same way. If you want fixed-width columns instead, you can use repeat(3, 200px), or mix units with repeat(2, 1fr) 200px for an asymmetric layout.

PatternResultCommon use case
repeat(3, 1fr)Three equal flexible columns and rowsTiles, galleries, dashboards
repeat(3, 200px)Three fixed 200 px columns and rowsIcon grids, button panels
repeat(3, minmax(120px, 1fr))Three columns that never shrink below 120 pxResponsive card grids
repeat(3, auto)Columns sized to their contentMixed-width labels or thumbnails

The minmax() pattern is worth knowing because it lets your grid stay readable on narrow screens without media queries. Each column will grow to fill space but never collapse below 120 px, so your nine tiles remain visible even on a phone.

Controlling Gap, Alignment, and Item Behavior

The gap property (formerly grid-gap) sets the gutter between cells. A value of 0 gives a flush tile look, 8px or 10px reads as a clean modern card grid, and 20px plus starts looking like distinct panels. You can use two values — gap: 10px 20px — to set the row gap and column gap independently.

For alignment, four properties matter on a 3x3 grid: justify-items, align-items, justify-content, and align-content. The first two control how items sit inside their own cells; the last two control how the whole grid sits inside its container. For a typical 3x3 tile layout you want justify-items: stretch and align-items: stretch so every child fills its cell, then add internal padding to the children themselves. If you want content centered inside each cell, switch both to center.

You can also place specific items with grid-column and grid-row shorthand, which is useful when one tile should span multiple cells (for example, a hero block covering the first two columns of the first row).

Build a 3x3 Grid with the CSS Grid Generator

  1. Open the CSS Grid Generator in your browser.
  2. Enter 3 for the column count and 3 for the row count. The generator accepts any whole number from 1 through 12 on each axis.
  3. Set a gap value between 0 and 100 pixels — 10 px is a safe starting point for most layouts.
  4. Pick a justify-items value (stretch, start, center, or end) and an align-items value with the same options.
  5. Watch the always-visible live preview update with every change so you can confirm the cells line up the way you want.
  6. Click the generate or copy button to copy the validated .grid rule. If clipboard permission is blocked, select the output manually with your cursor and press Ctrl+C or Cmd+C.
  7. Paste the declaration into your stylesheet and add the class grid to your container element. Place nine children inside and you have a working 3x3 layout.

The generated rule is standards-based, meaning it follows the CSS Grid Level 1 specification published by the W3C. You do not need to add vendor prefixes for any current browser, and the declaration will work in Chrome, Firefox, Safari, and Edge without modification.

Writing the CSS by Hand

If you prefer to skip the tool and write the rule yourself, here is a complete example you can drop into a stylesheet:

.grid { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr); gap: 10px; justify-items: stretch; align-items: stretch; } .grid > * { background: #f3f4f6; padding: 16px; border-radius: 6px; }

Pair that with this HTML:

<div class="grid"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> <div>6</div> <div>7</div> <div>8</div> <div>9</div> </div>

Each numbered cell will fill its slot, the gap will create visible breathing room, and the rounded background tiles will give you a clear visual confirmation that the grid is working.

Common Variations You Can Try Next

Once your basic 3x3 grid renders, a few small tweaks open up a lot of new layouts. Adding grid-auto-flow: dense lets the browser backfill small items into gaps left by larger ones, which is useful for masonry-style galleries. Switching the columns to repeat(3, minmax(0, 1fr)) prevents wide content from forcing the grid to overflow. And setting aspect-ratio: 1 on every child gives you perfectly square tiles for photo grids and icon boards.

For more advanced layouts, the Flexbox Generator handles one-dimensional layouts, while the PX to REM Converter helps you convert your gap and padding values into scalable rem units. If you need to format a JSON config file used by your component, the JSON Formatter keeps the data file readable while you tweak settings.

Troubleshooting a 3x3 Grid That Does Not Look Right

If your grid only shows one row, the most common cause is that grid-template-rows is missing — without it, the browser still creates rows, but they collapse to fit content rather than filling the container height. Give the parent an explicit height (height: 100vh or a fixed pixel value) or use grid-auto-rows: 1fr instead.

If items overflow their cells, check that min-width: 0 is set on the children, because long unbroken text or images will otherwise push the column wider than its share. If the gap looks uneven between the last row and the bottom of the container, add the same gap value to the bottom padding or remove any margin on the parent.

Finally, if you are debugging a stylesheet that does not behave the way you expect, the Diff Checker can quickly show you what changed between a working version and a broken one, which is often the fastest way to spot a missing semicolon or a typo in a property name.

Why CSS Grid Beats Older Layout Methods for 3x3

Before CSS Grid shipped, a 3x3 layout typically meant floating nine divs, clearing them with a wrapper, and calculating widths by hand to leave room for margins. That approach broke the moment you changed the column count or added padding. CSS Grid replaces all of that arithmetic with a single declarative rule, and the browser does the math for you. Flexbox can simulate a grid by stacking flex containers, but it adds nested elements and never gives you true two-axis control. For a 3x3 specifically — and for any bounded grid up to 12 by 12 — CSS Grid is the shortest, clearest, and most maintainable solution.

More on this topic: How to Check if Your JSON Format Is Correct.

If you're weighing options, How to Create a Directory Tree in CMD: A Practical Walkthrough covers this in detail.