Build a Photography Website with AI

Tutorial 2 — Bootstrap Fundamentals

Build your first responsive photography page using Bootstrap's grid, cards, images and navigation components.

Previous: Tutorial 1 — Choosing an ArchitectureBack to: Build a Photography Website with AI

What you'll learn

By the end of this tutorial you should understand:

  • what Bootstrap does
  • how Bootstrap is added to an HTML page
  • the basic structure of an HTML document
  • Bootstrap containers
  • rows and the 12-column grid
  • responsive breakpoints and images
  • Bootstrap cards
  • responsive navigation and the mobile burger menu
  • when a small amount of custom CSS is appropriate

You will finish with a simple working photography homepage. Our principle is straightforward: understand it by building it.

1What Does Bootstrap Actually Do?

HTML provides a page's structure and content. CSS controls its presentation. JavaScript can provide interactive behaviour. Bootstrap supplies a mature collection of CSS styles, layout rules and JavaScript components that solve many common website problems.

Bootstrap is an open-source framework that originated at Twitter. Think of it as a dependable foundation, not a tool that designs the whole website automatically. You still choose the content, photographs, structure and visual identity.

2Create the First HTML File

Create a folder for your project, then create a text file named index.html. Add this complete minimum HTML5 page:

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>My Photography</title>
</head>
<body>
    <h1>My Photography</h1>
</body>
</html>

<!doctype html> identifies modern HTML. <html> wraps the page. <head> holds information for the browser; the character-set metadata supports text correctly, the viewport metadata makes mobile sizing behave properly, and <title> names the browser tab. Visible content belongs in <body>.

Try it

Save the file and open it in a browser. Change the heading, save again and refresh. You are already editing a working website.

3Add Bootstrap

A content delivery network (CDN) stores commonly used files on servers that browsers can reach over the internet. It lets us load Bootstrap without installing it locally.

This learning path uses the same tested Bootstrap 4.5.2 references as the existing website. Add the CSS inside <head>:

<link rel="stylesheet"
      href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">

Add these scripts just before the closing </body> tag. They make interactive components such as the collapsed navigation work:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
Checkpoint

At this point the page may still look almost empty. Bootstrap is available, but we haven't used any Bootstrap components yet.

4Containers

Bootstrap's .container provides a sensible responsive maximum width and horizontal spacing. It keeps content away from the edges on a phone and centres it within a comfortable width on larger screens.

<div class="container">
    <h1>My Photography</h1>
    <p>A simple responsive photography website.</p>
</div>
Try it

Remove class="container", refresh, and then put it back. Notice the change in the content's width, centring and side spacing.

5Rows, Columns and the 12-Column Grid

Inside a container, .row groups columns. Classes beginning with .col- say how much of the row each item uses. Bootstrap imagines every row as 12 equal units:

123456789101112

Three equal large-screen columns each use four units: 4 + 4 + 4 = 12.

<div class="container">
    <div class="row">
        <div class="col-12 col-md-6 col-lg-4">Landscape card</div>
        <div class="col-12 col-md-6 col-lg-4">Wildlife card</div>
        <div class="col-12 col-md-6 col-lg-4">Travel card</div>
    </div>
</div>

A breakpoint means “from this screen width upwards”. The more specific medium and large rules take effect only when enough room is available.

Try it

Change every col-lg-4 to col-lg-6 and refresh. On a large screen, each card now uses half of the 12-unit row, so only two fit side by side and the third moves down.

6Responsive Images

A large fixed-width photograph can extend beyond a narrow phone screen. Bootstrap's img-fluid class gives an image a maximum width of 100% and an automatic height, allowing it to scale within its parent while keeping its proportions.

<img src="images/photo1.jpg"
     class="img-fluid"
     alt="Mountain landscape at sunrise">

Substitute your own image filename and write alternative text that describes your photograph. The sample images/photo1.jpg path assumes an images folder beside index.html.

7Bootstrap Cards

A card is useful for combining a photograph, title, short description and link or button into one clear unit:

<div class="card h-100">
    <img src="images/photo1.jpg" class="card-img-top img-fluid"
         alt="Mountain landscape at sunrise">
    <div class="card-body">
        <h2 class="card-title h5">Landscapes</h2>
        <p class="card-text">Mountains, coasts and changing light.</p>
        <a href="#" class="btn btn-primary">View gallery</a>
    </div>
</div>

Place three versions of this card inside the three responsive columns from section 5. h-100 makes cards in the same row equal in height, while card-img-top and card-body provide the expected card presentation.

Try it

Change one title and description, then add mb-4 to each column. Bootstrap's spacing utility adds a margin below each card so stacked cards do not touch.

8Navigation and the Burger Menu

This responsive navbar contains a brand, the links Home, Gallery and About, and a toggler button. navbar-expand-lg keeps navigation collapsed below the large breakpoint and expands it when more room is available.

<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
    <a class="navbar-brand" href="#">My Photography</a>
    <button class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#mainNav" aria-controls="mainNav"
            aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="mainNav">
        <ul class="navbar-nav ml-auto">
            <li class="nav-item"><a class="nav-link" href="#">Home</a></li>
            <li class="nav-item"><a class="nav-link" href="#gallery">Gallery</a></li>
            <li class="nav-item"><a class="nav-link" href="#about">About</a></li>
        </ul>
    </div>
</nav>

The button targets the collapsed element with the matching id="mainNav". Bootstrap JavaScript opens and closes it. The familiar burger icon appears on smaller screens because displaying three links across a narrow width would be cramped.

Try it

Resize the browser window slowly. Watch the links become a burger button, then select the button to confirm that the collapsed menu opens.

9A Little Custom CSS Is Fine

Using Bootstrap does not mean every Bootstrap website must look identical. Add a small <style> block after the Bootstrap CSS link when the site needs its own accent colour, hero spacing or image presentation:

<style>
    :root { --accent: #6f42c1; }
    .hero { padding: 5rem 1rem; background: #f4effc; }
    .btn-primary { background-color: var(--accent); border-color: var(--accent); }
    .card-img-top { height: 220px; object-fit: cover; }
</style>
Use Bootstrap for the common structural problems; use custom CSS for the site's individual visual identity.

Keep the custom layer small for now. This tutorial is about recognising and combining the foundational patterns.

10Put Everything Together

Replace your file with this complete index.html. Add three photographs at the sample paths—or change the paths to your own filenames—then open the file locally in a browser.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>My Photography</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
  <style>
    :root { --accent: #6f42c1; }
    .hero { padding: 5rem 1rem; background: #f4effc; }
    .btn-primary { background-color: var(--accent); border-color: var(--accent); }
    .card-img-top { height: 220px; object-fit: cover; }
  </style>
</head>
<body>
  <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
    <a class="navbar-brand" href="#">My Photography</a>
    <button class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#mainNav" aria-controls="mainNav"
            aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="mainNav">
      <ul class="navbar-nav ml-auto">
        <li class="nav-item active"><a class="nav-link" href="#">Home</a></li>
        <li class="nav-item"><a class="nav-link" href="#gallery">Gallery</a></li>
        <li class="nav-item"><a class="nav-link" href="#about">About</a></li>
      </ul>
    </div>
  </nav>

  <header class="hero text-center" id="about">
    <div class="container">
      <h1 class="display-4">Welcome to My Photography</h1>
      <p class="lead">A collection of landscapes, wildlife and travel photographs.</p>
    </div>
  </header>

  <main class="container py-5" id="gallery">
    <h2 class="text-center mb-4">Gallery</h2>
    <div class="row">
      <div class="col-12 col-md-6 col-lg-4 mb-4">
        <div class="card h-100">
          <img src="images/photo1.jpg" class="card-img-top img-fluid" alt="Mountain landscape at sunrise">
          <div class="card-body"><h3 class="card-title h5">Landscapes</h3>
            <p class="card-text">Mountains, coasts and changing light.</p>
            <a class="btn btn-primary" href="#">View gallery</a></div>
        </div>
      </div>
      <div class="col-12 col-md-6 col-lg-4 mb-4">
        <div class="card h-100">
          <img src="images/photo2.jpg" class="card-img-top img-fluid" alt="Bird resting on a branch">
          <div class="card-body"><h3 class="card-title h5">Wildlife</h3>
            <p class="card-text">Animals observed in their environment.</p>
            <a class="btn btn-primary" href="#">View gallery</a></div>
        </div>
      </div>
      <div class="col-12 col-md-6 col-lg-4 mb-4">
        <div class="card h-100">
          <img src="images/photo3.jpg" class="card-img-top img-fluid" alt="Colourful street on a journey">
          <div class="card-body"><h3 class="card-title h5">Travel</h3>
            <p class="card-text">Places, details and moments from the road.</p>
            <a class="btn btn-primary" href="#">View gallery</a></div>
        </div>
      </div>
    </div>
  </main>

  <footer class="bg-dark text-white text-center py-4">
    <p class="mb-0">&copy; 2026 My Photography</p>
  </footer>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>

On a large screen all three cards sit side by side. At smaller widths the breakpoint classes reorganise them, and the navigation collapses automatically.

Final Exercise

  1. Replace the sample site title.
  2. Replace the three sample image paths with your own photographs.
  3. Change the gallery titles.
  4. Resize the browser.
  5. Test the burger menu.
  6. Observe how the cards reorganise at different widths.

You do not need GitHub yet. Save index.html and simply open it locally in your browser.

What You Should Have at the End of Tutorial 2

You now have:

Most importantly, you understand enough of the generated HTML to recognise these patterns later when ChatGPT starts helping you create more sophisticated pages.

Continue learning

Next: Tutorial 3 — Setting Up GitHub Pages

Put the page you have just created into a GitHub repository and publish it on the web.

Start Tutorial 3

Previous: Tutorial 1 — Choosing an ArchitectureBack to: Build a Photography Website with AI