Skip to content

Bootstrap in Flask

Your patient app works. But it still looks like a plain HTML form with a plain HTML table. One link tag in the template changes that.


A Flask template is just an HTML file. The Bootstrap CDN link goes in <head> — same as always:

<head>
  <meta charset="UTF-8">
  <title>Patients</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous">
</head>

Flask does not know or care that Bootstrap is there. It just serves the HTML. The browser fetches Bootstrap from the internet and applies it before drawing the page.


Before — the plain template

Here is templates/index.html as it looked after the PookieDB in Flask section:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Patients</title>
  </head>
  <body>

    <h1>Add Patient</h1>

    <form action="/add" method="post">
        <label for="patient_name">Patient Name</label>
        <input type="text" id="patient_name" name="patient_name" placeholder="Full name">

        <label for="age">Age</label>
        <input type="number" id="age" name="age" placeholder="Age">

        <button type="submit">Add Patient</button>
    </form>

    <h2>Patients</h2>

    <table>
      <thead>
        <tr>
          <th>Name</th>
          <th>Age</th>
        </tr>
      </thead>
      <tbody>
        {% for patient in patients %}
        <tr>
          <td>{{ patient.name }}</td>
          <td>{{ patient.age }}</td>
        </tr>
        {% endfor %}
      </tbody>
    </table>

  </body>
</html>

It works. It looks rough.


After — with Bootstrap

Here is the same template with Bootstrap linked and class names applied:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Patients</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous">
  </head>
  <body>

    <div class="container mt-4">

      <h1 class="mb-4">Add Patient</h1>

      <form action="/add" method="post">

        <div class="mb-3">
          <label for="patient_name" class="form-label">Patient Name</label>
          <input type="text" id="patient_name" name="patient_name" class="form-control" placeholder="Full name">
        </div>

        <div class="mb-3">
          <label for="age" class="form-label">Age</label>
          <input type="number" id="age" name="age" class="form-control" placeholder="Age">
        </div>

        <button type="submit" class="btn btn-primary">Add Patient</button>

      </form>

      <h2 class="mt-5 mb-3">Patients</h2>

      <table class="table table-striped table-bordered">
        <thead>
          <tr>
            <th>Name</th>
            <th>Age</th>
          </tr>
        </thead>
        <tbody>
          {% for patient in patients %}
          <tr>
            <td>{{ patient.name }}</td>
            <td>{{ patient.age }}</td>
          </tr>
          {% endfor %}
        </tbody>
      </table>

    </div>

  </body>
</html>

app.py and database.py did not change at all. Only the template changed — and only with class names and one wrapper <div>. The app behaviour is identical. The page looks completely different.


What each class does

Class What it does
container Centres the content and gives it a comfortable max width
mt-4 Margin top — space above the element
mb-3, mb-4 Margin bottom — space below
mt-5 Larger top margin — pushes the Patients heading away from the form
form-label Styles the label to sit cleanly above the input
form-control Styles the input — rounded corners, full width, focus highlight
btn btn-primary A solid blue button
table Basic Bootstrap table — cleaner font, spacing, borders
table-striped Alternating row colours so rows are easy to scan
table-bordered Adds a border around every cell

Challenge

Open your patient app and replace templates/index.html with the Bootstrap version above. Run python app.py, add a few patients, and see the difference. Then try two things:

  1. Add table-hover to the table classes — hover your mouse over the rows
  2. Change btn-primary to btn-success — what colour does that give you?

← What is Bootstrap?    Next: Layout and Text Utilities →