📝 Html Css

Bootstrap 5: Components for DevBlog

P
Author
Pyland
📅
Published
30.06.2026
⏱️
Reading time
2 min
👁️
Views
83
🌿
Level
Medium

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.

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

Your reaction to the article

💬 Comments (0)

🔐 Sign in to leave a comment
🚪 Login
💭

No comments yet

Be the first to share your opinion about this article!

🔗 Similar

Similar articles

Continue learning with these materials

📝

Django: Template Tags

Template tags are logic inside HTML. Unlike {{ variable }} which only outputs a value,...

📅 30.06.2026 👁️ 85
📝

Colors and Fonts in CSS

The first thing a DevBlog reader sees is text. Well-chosen colors and fonts make a...

📅 30.06.2026 👁️ 75
📝

CSS Selectors

A selector is the first part of a CSS rule. It tells the browser: "apply...

📅 30.06.2026 👁️ 82

Did you like the article?

Subscribe to our updates and receive new articles first. Grow with PyLand!