Bootstrap ships with a set of ready-made UI components. Instead of writing CSS from scratch, you grab the HTML markup from the docs and customise it. Let’s cover five components you need in a personal developer blog.
Navbar
A navigation bar with a logo and links. On mobile it collapses into a hamburger button.
<nav class="navbar navbar-expand-lg bg-dark navbar-dark">
<div class="container">
<!-- Logo / site name -->
<a class="navbar-brand" href="/">DevBlog</a>
<!-- Hamburger button for mobile -->
<button class="navbar-toggler" type="button"
data-bs-toggle="collapse" data-bs-target="#navMenu">
<span class="navbar-toggler-icon"></span>
</button>
<!-- Navigation links -->
<div class="collapse navbar-collapse" id="navMenu">
<ul class="navbar-nav ms-auto">
<li class="nav-item">
<a class="nav-link" href="/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/articles/">Articles</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/about/">About</a>
</li>
</ul>
</div>
</div>
</nav>
navbar-expand-lg expands the menu horizontally from lg (992px) upwards. On mobile it becomes a burger button. ms-auto pushes the links to the right edge.
Card
A card is the main element for displaying articles on the home page.
<div class="card h-100 shadow-sm">
<img src="{{ post.image.url }}" class="card-img-top" alt="{{ post.title }}">
<div class="card-body d-flex flex-column">
<h5 class="card-title">{{ post.title }}</h5>
<p class="card-text text-muted">{{ post.summary }}</p>
<!-- Button pinned to the bottom of the card -->
<a href="{{ post.get_absolute_url }}" class="btn btn-primary mt-auto">
Read article
</a>
</div>
<div class="card-footer text-muted small">
{{ post.published_at|date:"d.m.Y" }}
</div>
</div>
h-100 makes all cards in a row the same height (works inside a flex/grid row). mt-auto pushes the button to the bottom of the card body.
Badge
A small label — handy for article tags or status indicators.
<!-- Article tags -->
<h1>
{{ post.title }}
<span class="badge bg-secondary">Python</span>
<span class="badge bg-info text-dark">Django</span>
</h1>
<!-- Draft status -->
{% if not post.is_published %}
<span class="badge bg-warning text-dark">Draft</span>
{% endif %}
<!-- Comment counter in navigation -->
<a href="/comments/" class="nav-link">
Comments <span class="badge bg-danger">{{ comments_count }}</span>
</a>
Alert
Info blocks for error, success, and warning messages.
<!-- Success / error messages from Django's messages framework -->
{% if messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
{% endfor %}
{% endif %}
<!-- Static variants -->
<div class="alert alert-success">Article published!</div>
<div class="alert alert-danger">Error while saving.</div>
<div class="alert alert-warning">Article is in drafts.</div>
<div class="alert alert-info">Don't forget to add tags.</div>
Django’s messages framework automatically uses tags success, error, warning, info — they match Bootstrap alert classes directly.
Pagination
Page navigation for a list of articles.
{% if is_paginated %}
<nav aria-label="Page navigation">
<ul class="pagination justify-content-center">
<!-- Previous button -->
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}">
« Previous
</a>
</li>
{% else %}
<li class="page-item disabled">
<span class="page-link">« Previous</span>
</li>
{% endif %}
<!-- Page numbers -->
{% for num in paginator.page_range %}
<li class="page-item {% if page_obj.number == num %}active{% endif %}">
<a class="page-link" href="?page={{ num }}">{{ num }}</a>
</li>
{% endfor %}
<!-- Next button -->
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.next_page_number }}">
Next »
</a>
</li>
{% else %}
<li class="page-item disabled">
<span class="page-link">Next »</span>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
is_paginated and page_obj are context variables that Django adds automatically when you use ListView with paginate_by.
Class Reference
| Component | Key classes |
|---|---|
| Navbar | navbar, navbar-expand-lg, navbar-toggler, collapse navbar-collapse |
| Card | card, card-body, card-title, card-text, card-img-top, card-footer |
| Badge | badge, bg-primary/secondary/success/danger/warning/info |
| Alert | alert, alert-success/danger/warning/info, alert-dismissible |
| Pagination | pagination, page-item, page-link, active, disabled |
💬 Comments (0)
No comments yet
Be the first to share your opinion about this article!