Lesson 2 of 12

Bootstrap Grid System

The Bootstrap grid system is the part of the framework you will use on almost every page. It lets you place content side by side in columns that stack neatly on phones and spread out on wider screens. Once you understand three pieces, container, row and column, you can build most page layouts without writing a media query.

“Bootstrap grid system: container, row and column

Every grid follows the same nesting order:

  1. Container: centres your content and adds side padding. container has a fixed maximum width at each breakpoint; container-fluid is always full width; container-md is full width until the md breakpoint and fixed after it.
  2. Row: a row is a flex container that holds columns. It uses negative margins so the content inside columns lines up with content outside the row.
  3. Column: classes such as col or col-4. Only columns should be direct children of a row, and your content goes inside the columns.

The Bootstrap grid system has 12 columns. A class like col-4 means “take 4 of the 12 columns”, which is one third of the row. Twelve was chosen because it divides evenly by 2, 3, 4 and 6, so halves, thirds and quarters are all easy. If the numbers in a row add up to more than 12, the extra columns wrap onto a new line.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Equal and sized columns</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
<style>
.demo-col { padding: 12px; background: #e7f1ff; border: 1px solid #9ec5fe; border-radius: 6px; text-align: center; }
</style>
</head>
<body>
<div class="container py-4">
  <h2 class="h5">Three equal columns: col</h2>
  <div class="row mb-4">
    <div class="col"><div class="demo-col">col</div></div>
    <div class="col"><div class="demo-col">col</div></div>
    <div class="col"><div class="demo-col">col</div></div>
  </div>

  <h2 class="h5">Sized columns: col-8 and col-4</h2>
  <div class="row mb-4">
    <div class="col-8"><div class="demo-col">col-8 (two thirds)</div></div>
    <div class="col-4"><div class="demo-col">col-4 (one third)</div></div>
  </div>

  <h2 class="h5">Mixing: col-6 with two auto columns</h2>
  <div class="row">
    <div class="col"><div class="demo-col">col</div></div>
    <div class="col-6"><div class="demo-col">col-6</div></div>
    <div class="col"><div class="demo-col">col</div></div>
  </div>
</div>
</body>
</html>

A plain col shares the leftover space equally with its siblings. In the last row, col-6 takes half and the two col columns split the other half. The coloured boxes are a small custom style so you can see the columns; the grid itself adds no colours.

Responsive columns

Add a breakpoint to a column class to change it at that screen width. col-md-6 means “half width from 768px upwards”. Below that width, the column is full width (12 of 12) by default. You can stack several classes on one element to describe each screen size:

ClassPhones (below 576px)Tablets (768px+)Laptops (992px+)
col-12 col-md-6 col-lg-4Full widthHalfOne third
col-6 col-lg-3HalfHalfOne quarter
col-mdFull widthEqual shareEqual share
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>A responsive card grid</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container py-4">
  <h1 class="h3 mb-3">Hill stations of South India</h1>
  <div class="row g-3">
    <div class="col-12 col-sm-6 col-lg-4"><div class="p-3 border rounded h-100"><h2 class="h5">Ooty</h2><p class="mb-0">Tea gardens and the Nilgiri toy train.</p></div></div>
    <div class="col-12 col-sm-6 col-lg-4"><div class="p-3 border rounded h-100"><h2 class="h5">Kodaikanal</h2><p class="mb-0">A star-shaped lake and pine forests.</p></div></div>
    <div class="col-12 col-sm-6 col-lg-4"><div class="p-3 border rounded h-100"><h2 class="h5">Munnar</h2><p class="mb-0">Rolling tea estates in Kerala.</p></div></div>
    <div class="col-12 col-sm-6 col-lg-4"><div class="p-3 border rounded h-100"><h2 class="h5">Coorg</h2><p class="mb-0">Coffee plantations and waterfalls.</p></div></div>
    <div class="col-12 col-sm-6 col-lg-4"><div class="p-3 border rounded h-100"><h2 class="h5">Yercaud</h2><p class="mb-0">A quiet hill town near Salem.</p></div></div>
    <div class="col-12 col-sm-6 col-lg-4"><div class="p-3 border rounded h-100"><h2 class="h5">Chikmagalur</h2><p class="mb-0">Hills, coffee and trekking trails.</p></div></div>
  </div>
</div>
</body>
</html>

Resize the preview: one card per row on a phone, two from 576px and three from 992px. Because Bootstrap is mobile-first, you only add a class where the layout should change. col-12 is the default anyway, so many developers leave it out.

Gutters, row-cols and offsets

Gutters are the gaps between columns. The default is 1.5rem. Change them on the row with g-0 to g-5 (both directions), gx-* (horizontal only) or gy-* (vertical only). Vertical gutters matter when columns wrap onto several lines, as in the card grid above.

Row columns set the number of columns on the row instead of on each child. row-cols-2 row-cols-md-4 gives two per line on small screens and four from 768px, and the children only need col. This keeps repeated items, such as a product list from a database, short and tidy.

Offsets push a column to the right by a number of columns: offset-md-2 leaves two empty columns first. You can also use mx-auto to centre a sized column. Order classes such as order-first or order-md-2 change the visual order without changing the HTML.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>row-cols, gutters, offset and order</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
<style>
.demo-col { padding: 12px; background: #e7f1ff; border: 1px solid #9ec5fe; border-radius: 6px; text-align: center; }
</style>
</head>
<body>
<div class="container py-4">
  <h2 class="h5">row-cols-2 row-cols-md-4 with g-2</h2>
  <div class="row row-cols-2 row-cols-md-4 g-2 mb-4">
    <div class="col"><div class="demo-col">Idli</div></div>
    <div class="col"><div class="demo-col">Dosa</div></div>
    <div class="col"><div class="demo-col">Pongal</div></div>
    <div class="col"><div class="demo-col">Vada</div></div>
  </div>

  <h2 class="h5">A centred column: col-md-8 offset-md-2</h2>
  <div class="row mb-4">
    <div class="col-md-8 offset-md-2"><div class="demo-col">Centred reading column</div></div>
  </div>

  <h2 class="h5">Order: the sidebar comes first in HTML but shows second from md</h2>
  <div class="row g-2">
    <div class="col-md-4 order-md-2"><div class="demo-col">Sidebar (HTML first)</div></div>
    <div class="col-md-8 order-md-1"><div class="demo-col">Main content (HTML second)</div></div>
  </div>
</div>
</body>
</html>

Watch out: Order classes only move things visually. Keyboard and screen reader users still follow the HTML order. Put the most important content first in your HTML and use order-* for small visual adjustments only.

Nesting and common mistakes

You can put a new row inside any column to create a nested grid. The inner row again has 12 columns, which are counted within the parent column’s width, not the whole page.

  • Columns must be direct children of a row. Content placed straight in a row loses the gutters and alignment.
  • Do not put padding or borders on the column itself if it breaks the gutters. Place a box inside the column, as the examples do.
  • Forgetting the container gives you a horizontal scrollbar, because the row’s negative margins stick out of the page.
  • Use col-auto when a column should be only as wide as its content, such as a button next to a search field.

Tip: Under the hood, a row is display: flex with flex-wrap: wrap, and columns are flex items with percentage widths. Knowing CSS Flexbox makes the Bootstrap grid system easier to debug. For a longer walk-through with more diagrams, read Bootstrap 5 Grid Explained. If you need true two-dimensional layouts, compare it with CSS Grid.

Further reading

Key takeaways

  • Grid structure is always container, then row, then columns, with content inside the columns.
  • The grid has 12 columns; col-4 takes one third and plain col shares space equally.
  • Breakpoint classes such as col-md-6 apply from that width upwards; below it, columns stack.
  • Use g-*, gx-* and gy-* on the row for gutters, and row-cols-* to set columns per line.
  • offset-* and order-* adjust position, but keep the HTML order meaningful.

Quick quiz

Check what you learned – pick an answer.

1. What width does col-md-4 have on a 400px-wide phone?

2. Which class on a row makes all its col children show three per line from 768px?

3. Why does a page without a container sometimes scroll sideways?

Practice exercise

Build a blog layout: a full-width header row, then a main article column and a sidebar. On screens of 768px and wider, the article should take 8 columns and the sidebar 4. On phones, they should stack. Add a 4-unit gutter between them.

Show a hint

Use row g-4 with col-md-8 and col-md-4.

Show the solution
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Blog layout</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container py-4">
  <div class="row">
    <div class="col"><header class="p-3 mb-4 bg-body-tertiary border rounded"><h1 class="h3 mb-0">Kochi Food Diary</h1></header></div>
  </div>
  <div class="row g-4">
    <main class="col-md-8">
      <article class="p-3 border rounded">
        <h2 class="h4">Appam and stew for breakfast</h2>
        <p>Soft, lacy appams with a mild coconut stew are a classic Kerala breakfast.</p>
      </article>
    </main>
    <aside class="col-md-4">
      <div class="p-3 border rounded bg-body-tertiary">
        <h2 class="h5">Popular posts</h2>
        <p class="mb-0">Puttu and kadala curry</p>
      </div>
    </aside>
  </div>
</div>
</body>
</html>

Progress is saved in this browser only.