In this tutorial, we will create a modern and responsive landing page for a pickleball club using Frozen-Flask and Bootstrap 5, featuring a navigation bar, hero banner, about section, facilities showcase, contact form integration, and footer. This approach combines the simplicity of Flask development with the performance and cost benefits of static site hosting, making it an excellent choice for clubs, portfolios, small businesses, and promotional websites.
Prerequisite:
This tutorial is part of the Flask Landing Page and Reservation System Series.
📚 View the Complete Flask Landing Page and Reservation System Series
Preliminary:
python -m venv venv
venv\Scripts\activate
pip install flask frozen-flaskThen, we need to set up the file and folder structure, as below:- about.png,
- changing_rooms.png,
- court.png,
- free_parking.png,
- hero.png,
- logo.png, and
- night_lighting.png
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
JS:
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3
/dist/js/bootstrap.bundle.min.js">
</script>
Custom CSS
<link rel="stylesheet"
href="{{ url_for('static', filename='style.css') }}">
The benefits of using Bootstrap 5 are as follows:
- Faster Loading Times: Bootstrap 5 dropped a heavy code helper called jQuery. This makes the framework lighter and faster. Think of it like taking heavy weights off a race car so it can drive faster.
- Responsive by Default: Websites will automatically adjust to look great on phones, tablets, and desktop computers.
- Pre-built Components: You get ready-to-use pieces like buttons, forms, and navigation bars. Instead of building a button from scratch, you just use a pre-made one. It is like using Lego blocks to build a castle instead of carving it out of wood.
- Built-in Dark Mode: It allows developers to easily add a dark theme to websites. This is helpful for users who want to save battery on their phones or reduce eye strain at night.
- Customisation: It is easy to change colours, fonts, and sizes to match your own style.
Custom CSS: I am the author of every rule. I write the specific code to style your elements (e.g.,
background-color: blue;). This gives you complete control and allows me a unique, brand-specific design, but it requires significantly more time to build from scratch.Bootstrap CSS: This is a pre-written, open-source framework.
It provides a library of ready-to-use components (buttons, navbars, forms) and a mobile-first grid system. It is designed for speed and consistency, allowing you to build responsive layouts without reinventing the wheel.
It is common to use both, but you should do so carefully to keep your code maintainable:
Don't Modify Bootstrap Directly: Avoid editing the
bootstrap.cssfile itself. If you ever update the Bootstrap version, your changes will be overwritten.Use a Separate Custom File: Always keep your overrides in a separate file (e.g.,
custom.cssorstyle.css). In my tutorial, I used styles.css.Correct Loading Order: Ensure your custom stylesheet is linked in your HTML after the Bootstrap stylesheet so that the browser applies my custom styles as the final authority.
Leverage Utility Classes: Bootstrap 5 includes many "utility" classes (for spacing, colours, borders, etc.) that can often prevent me from needing to write custom CSS at all. Try to use these first to keep your project lightweight.
mkdir JCPC
cd JCPC
touch app.py
Next, in my app.py file, I will create a few lines of code as below:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=True)
Since the landing page is a single page, I only need a route.
mkdir templates
cd templates
touch index.html
cd ..
mkdir static
cd static
touch style.css
mkdir assets
cd..
The folder structure is as shown in the preliminary section above. Once the assets folder has been created, go ahead and copy the images to the assets folder.- Navigation and hero section
- About section
- Facilities section
- Contact form
- Footer section
html,
body {
overflow-x: hidden;
width: 100%;
background: #3f496a;
}
.h3 {
color: #ffc107;
}
.hero {
min-height: 500px;
height: 70vh;
background:
linear-gradient(
rgba(0,0,0,.5),
rgba(0,0,0,.5)
),
url("../static/assets/hero.png");
background-size: cover;
background-position: center center;
}
.hero-overlay {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.hero-overlay {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.lead {
color: white;
font-size: 25px;
font-weight: bold;
}
.section-divider {
height: 2px;
background: #dee2e6;
margin: 40px 0;
}
(b) index.html<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
<link rel="stylesheet"
href="{{ url_for('static', filename='style.css') }}">
<!-- Navigation -->
<nav class="navbar navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand d-flex align-items-center" href="#">
<img src="static/assets/logo.png" alt="JCPC Logo"
width="30" height="30" class="d-inline-block align-text-top me-2">
<span class="h3 mb-0">Jersey City Pickleball Club</span>
</a>
</div>
</nav>
<!---hero section--->
<section class="hero">
<div class="hero-overlay">
<div class="container text-center text-white">
<h1 class="display-3 fw-bold">
Jersey City Pickleball Club
</h1>
<p class="lead">
Play. Compete. Connect.
</p>
<a href="/#" class="btn btn-warning btn-lg">
Book a Court
</a>
</div>
</div>
</section
<hr class="section-divider">
-----------------------------------------------------------------------------------------------------------------------------
🎁 Get Your FREE Flask Cheat Sheet
Join 500+ Python learners and receive this printable Flask Cheat Sheet instantly. Plus, get new Flask tutorials delivered to your inbox.
✓ Practical coding tutorials
✓ Automation tips for SMEs
✓ New project ideas and templates
Download my FREE Flask Cheat Sheet (PDF)
-----------------------------------------------------------------------------------------------------------------------------
🎁 Get Your FREE Flask Cheat Sheet
Join 500+ Python learners and receive this printable Flask Cheat Sheet instantly. Plus, get new Flask tutorials delivered to your inbox.
✓ Practical coding tutorials
✓ Automation tips for SMEs
✓ New project ideas and templates
Download my FREE Flask Cheat Sheet (PDF)
Understanding the Navigation Bar
The navigation bar is usually the first element visitors see when they open a website. It provides branding and helps users identify the website immediately.
(i) Navbar
Bootstrap classes used here are:
-
navbarInitializes Bootstrap's navigation bar component and applies the necessary spacing and layout. -
navbar-darkadjusts the text and icon colours for use on dark backgrounds, ensuring good readability. -
bg-darkapplies Bootstrap's built-in dark background colour.
The container-fluid class creates a full-width container that stretches across the entire browser window.
Unlike the standard container class, which has fixed maximum widths at different screen sizes, it container-fluid allows the navigation bar to span the full width of the page. This is useful for modern landing pages where the header extends from edge to edge.
The <img> element displays the club's logo.
The attributes specify:
-
src– the location of the image file. -
alt– alternative text used by screen readers and displayed if the image cannot be loaded. -
widthandheight– set the displayed dimensions of the image.
These Bootstrap utility classes control the image alignment and spacing.
-
d-inline-blockallows the image to appear inline with the text while maintaining block-like properties. -
align-text-topaligns the image with the top of the surrounding text. -
me-2adds horizontal spacing (margin-end) between the logo and the club name, preventing them from touching.
mb-0 class removes the default bottom margin, helping keep the navigation bar compact.When combined, these elements produce a responsive navigation bar that:
- Displays the club logo.
- Shows the website name beside the logo.
- Uses Flexbox for proper alignment.
- Applies Bootstrap's dark theme.
- Spans the full width of the browser.
- Maintains consistent spacing and typography.
Creating the Hero Section
The hero section is the most prominent area of a landing page. It is typically the first section visitors see and is designed to communicate the website's purpose while encouraging users to take an action.
(i) Overlay
The overlay sits above the background image but beneath the text.
Its purpose is to improve text readability.
Without an overlay, white text can become difficult to read when displayed on bright or detailed background images.
(ii) Centring the Content
Bootstrap provides several utility classes that simplify page layout.
-
containerkeeps the content centered and limits the maximum width on larger screens. -
text-centerhorizontally centers all text inside the container. -
text-whitechanges the text color to white so it contrasts well against the darker overlay.
Using Bootstrap utilities reduces the amount of custom CSS required.
(iii) Displaying the Main Heading
Bootstrap classes enhance the appearance:
-
display-3creates a large, attention-grabbing heading suitable for hero sections. -
fw-boldapplies a bold font weight, making the heading more visually prominent.
Because this is the first thing visitors read, it should clearly communicate what the website offers.
(iv) Adding a Supporting Tagline
The lead class increases the font size and improves readability, making it suitable for introductory text.
Instead of overwhelming visitors with long descriptions, a short and memorable slogan communicates the club's purpose quickly.
(v) Creating a Call-to-Action Button
Bootstrap provides several utility classes:
-
btnstyles the anchor as a button. -
btn-warningapplies Bootstrap's warning colour, helping the button stand out from the darker background. btn-lgcreates a larger button that is easier to notice and click.
The <hr> element creates a horizontal rule that visually separates the hero section from the content that follows.
Applying a custom section-divider class allows you to control:
- Thickness
- Width
- Color
- Margins
- Overall spacing
This helps create a cleaner transition between different sections of the landing page.
h2 { color: white;
font-size: 48px;
font-weight: bold;
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
text-align: center;
margin: 0;}
p {
text-align: center;
margin-top: 20px;
}
.section-divider {
height: 2px;
background: #dee2e6;
margin: 40px 0;
}
(b) index.html<!---about section--->
<section id="about" class="section-padding">
<div class="row align-items-center">
<div class="col-lg-6">
<img src="{{ url_for('static', filename='assets/about.png') }}"
class="img-fluid rounded shadow" alt="About Image">
</div>
<div class="col-lg-6">
<h2>About Us</h2>
<p>
Jersey City Pickleball Club is a vibrant community where players of
all skill levels come together to enjoy pickleball.
</p>
<p>
Whether you're a beginner or an experienced competitor, you'll find
a welcoming place to play, improve, and connect with others.
</p>
</div>
</div>
</section>
<hr class="section-divider">
Creating the About Section
The About section introduces the organisation and gives visitors a brief overview of its purpose. Unlike the Hero section, which is designed to capture attention, the About section builds trust by providing background information about the club.
(i) Creating a Bootstrap Row
Bootstrap uses a 12-column grid system to build responsive layouts.
The row class creates a horizontal container for columns.
The align-items-center class uses Flexbox to vertically centre all columns within the row. This ensures that the image and text remain aligned even when their heights differ.
Without this class, the text would align to the top of the image instead of appearing centred beside it.
(ii) Creating the Left Column
The col-lg-6 class tells Bootstrap to allocate half of the available width to this column on large screens.
Since Bootstrap uses a 12-column grid:
-
6 + 6 = 12
The image occupies half of the row while the text occupies the other half.
On smaller devices such as tablets and smartphones, Bootstrap automatically stacks the columns vertically, making the layout responsive without requiring additional CSS.
(iii) Displaying the Image
Bootstrap utility classes enhance the appearance:
-
img-fluidmakes the image responsive by allowing it to scale with its parent container. -
roundedadds rounded corners for a softer, more modern design. -
shadowapplies a subtle drop shadow that helps the image stand out from the background.
The alt attribute provides alternative text for screen readers and is displayed if the image cannot be loaded. Including descriptive alt text also improves accessibility.
Last Updated: June 2026
---------------------------------------------------------------------------------------------------------------------------------------------------
About the Author
Kelvin Loh is a Python developer focused on Flask, desktop applications, and business automation solutions. He shares practical tutorials and real-world coding projects to help developers and small businesses build useful applications.
.png)




Comments