Cómo resaltar el enlace activo en un menú de navegación con Django + Bootstrap

Cuando construyes una interfaz de usuario en Django, es común tener una barra de navegación que se repite en muchas páginas. Un pequeño detalle que mejora la experiencia del usuario es resaltar cuál es la página activa dentro del menú. En este artículo te explico cómo hacerlo de forma sencilla y elegante usando Django y Bootstrap 5.


URLs sin resaltado dinámico

Imagina que tienes un menú como este:

<ul class="nav">
  <li><a href="{% url 'home.index' %}" class="nav-link">Inicio</a></li>
  <li><a href="#" class="nav-link">Características</a></li>
  <li><a href="{% url 'home.faq' %}" class="nav-link">FAQ</a></li>
</ul>

Por defecto, no hay ninguna indicación visual de en qué sección estás. Todos los enlaces se ven iguales, lo que puede confundir a los usuarios.


La solución: usar request.path para detectar la URL actual

Django nos permite acceder a la URL actual a través del objeto request. Con request.path, podemos comparar la URL activa con la de cada enlace y aplicar estilos condicionalmente.

Así se vería el código actualizado:

<ul class="nav">
  <li>
    <a href="{% url 'home.index' %}"
       class="nav-link {% if request.path == '/' %}text-danger fw-bold{% else %}text-body{% endif %}">
       Inicio
    </a>
  </li>
  <li>
    <a href="#" class="nav-link text-body">Características</a>
  </li>
  <li>
    <a href="{% url 'home.faq' %}"
       class="nav-link {% if request.path == '/faq/' %}text-danger fw-bold{% else %}text-body{% endif %}">
       FAQ
    </a>
  </li>
</ul>

¿Qué estamos haciendo aquí?

  • request.path == '/': Verifica si la URL actual es la raíz (/), lo cual indica que estamos en la página de inicio.
  • text-danger: Es una clase de Bootstrap que colorea el texto según el tema (rojo por defecto).
  • fw-bold: Añade negrita al enlace activo.
  • text-body: Es el estilo base para los enlaces inactivos.

Alternativa más robusta: usar request.resolver_match.url_name

A veces es mejor comparar por nombre de vista que por ruta. Django nos permite acceder al nombre de la vista actual así:

{% if request.resolver_match.url_name == 'home.index' %}

Esto es más limpio, más robusto frente a cambios de URL y más legible si tienes muchas rutas.


Mejora semántica: usar la etiqueta <nav>

Otro pequeño, pero importante cambio es reemplazar el <div> que contiene la navegación por una etiqueta <nav>, ya que:

  • Mejora la semántica HTML.
  • Ayuda a los lectores de pantalla y a las herramientas de accesibilidad.
  • Es más correcto desde el punto de vista del SEO y estructura del documento.

Antes:

<div class="d-flex ...">
  <!-- enlaces -->
</div>

Después:

<nav class="d-flex ...">
  <!-- enlaces -->
</nav>

Resultado final

Con estos cambios, los usuarios verán qué página están navegando claramente, y tu código será más limpio, accesible y fácil de mantener.

Mejora visual del selector de tema con Font Awesome y CSS personalizado

Además, he aprovechado para modificar también los estilos de los botones del botón de cambio de tema (modo oscuro/claro) en una aplicación Django con Bootstrap. Nos enfocamos únicamente en:

  • Sustituir los emojis por íconos de Font Awesome.
  • Darles colores personalizados con CSS: luna blanca y sol naranja.
  • Asegurar que el botón sea visualmente atractivo y completamente clicable.

Cambio de íconos: de emojis a Font Awesome

Anteriormente, el botón usaba emojis Unicode. Estos son rápidos de implementar, pero tienen limitaciones visuales y de personalización.

Se reemplazaron por íconos de Font Awesome:

function updateButton(theme) {
  toggleBtn.innerHTML = theme === "dark"
    ? '<i class="fa-solid fa-moon icon-moon"></i>'
    : '<i class="fa-solid fa-sun icon-sun"></i>';
}

Esto permite aplicar estilos CSS específicos a cada ícono con clases como .icon-moon y .icon-sun.


Estilizado del botón y colores de íconos

El botón de cambio de tema fue mejorado con este CSS:

#theme-toggle {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.25rem;
  padding: 0;
}

.icon-moon {
  color: white;
}

.icon-sun {
  color: rgb(255, 166, 0);
}

Esto consigue:

  • Un botón completamente redondo, limpio y centrado.
  • Íconos visualmente claros: blanco sobre fondo oscuro y naranja sobre fondo claro.
  • Mejor accesibilidad táctil: el área es totalmente clicable, incluso si el ícono es pequeño.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

curso django Entrada anterior Añadiendo un sistema de reseñas de usuario en Django
curso django Entrada siguiente Cómo crear un carrito de compras persistente en Django