Build fast, responsive sites with Bootstrap

Quickly design and customize responsive mobile-first sites with Bootstrap, the world’s most popular front-end open source toolkit, featuring Sass variables and mixins, responsive grid system, extensive prebuilt components, and powerful JavaScript plugins.

Currently v5.1.3 · v4.6.x docs · All releases

Installation

Install Bootstrap’s source Sass and JavaScript files via npm, Composer, or Meteor.

Package managed installs don’t include documentation or our full build scripts. You can also use our npm template repo

Read installation docs
$ npm install bootstrap
$ gem install bootstrap -v 5.1.3

jsDelivr

When you only need to include Bootstrap’s compiled CSS or JS, you can use jsDelivr.

See it in action with our simple starter template , or browse the examples to jumpstart your next project. You can also choose to include Popper and our JS separately .

Explore the docs

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqy" crossorigin="anonymous">

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous">

Django

Configuración inicial y comandos esenciales para trabajar con Django.

Ver documentación
$ django-admin startproject "nombreDelProyecto" $ cd nombreDelProyecto
$ python manage.py runserver
$ python manage.py startapp "nombreApp"
INSTALLED_APPS = [ ..., 'nombreApp', ]
from django.http import HttpResponse def index(request): return HttpResponse("Hola mundo")
from django.urls import path from nombreApp.views import index urlpatterns = [ path('admin/', admin.site.urls), path('', index, name='index'), ]

One Page con JavaScript

Carga contenido dinámico cuando el usuario llega al final de la página.

Ver documentación

// Detectar scroll hasta el final
window.addEventListener('scroll', () => {
    if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
        loadCards();
    }
});

              

function loadCards(title, text) {
    var card = document.createElement('div');
    card.setAttribute('class', 'card col-4');

    var body = document.createElement('div');
    body.setAttribute('class', 'card-body');

    var h5 = document.createElement('h5');
    h5.setAttribute('class', 'card-title');
    h5.innerHTML = title;

    var p = document.createElement('p');
    p.setAttribute('class', 'card-text');
    p.innerHTML = text;

    body.appendChild(h5);
    body.appendChild(p);
    card.appendChild(body);

    document.getElementById('tarjetas').appendChild(card);
}

              

var i = 1;
window.addEventListener('scroll', () => {
    if ((window.scrollY + window.innerHeight) >= document.body.offsetHeight) {
        for (let index = 0; index < 5; index++) {
            if (i > 100) { break; }
            var object = {
                title: 'Título dinámico de la Card: ' + i,
                text: 'Texto dinámico de la Card: ' + i
            }
            loadCards(object.title, object.text);
            i++;
        }
    }
});

              

DataTables

Configuración de base de datos y modelo en Django para integrar DataTables.

Ver documentación
CREATE DATABASE mi_base_de_datos;
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'mi_base_de_datos', 'USER': 'root', 'PASSWORD': 'root', 'HOST': 'localhost', 'PORT': '3306', } }
$ pip install pymysql
import pymysql pymysql.install_as_MySQLdb()
from django.db import models class Cancion(models.Model): titulo = models.CharField(max_length=200) autor = models.CharField(max_length=100) duracion = models.FloatField() def __str__(self): return self.titulo
from django.shortcuts import render from .models import Cancion def lista_canciones(request): canciones = Cancion.objects.all() # Obtener todas las canciones return render(request, 'tabla.html', {'canciones': canciones})

<!-- HTML para mostrar las canciones con DataTables -->
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Lista de Canciones</title>

    <!-- Estilos y Scripts de DataTables -->
    <link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css">
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>

</head>
<body>

    <h2>Lista de Canciones</h2>

    <table id="tabla-canciones" class="display">
        <thead>
            <tr>
                <th>Título</th>
                <th>Autor</th>
                <th>Duración</th>
            </tr>
        </thead>
        <tbody>
            {% for cancion in canciones %}
            <tr>
                <td>{{ cancion.titulo }}</td>
                <td>{{ cancion.autor }}</td>
                <td>{{ cancion.duracion }}</td>
            </tr>
            {% endfor %}
        </tbody>
    </table>

    <script>
        $(document).ready( function () {
            $('#tabla-canciones').DataTable();
        });
    </script>

</body>
</html>

              
from django.urls import path from .views import lista_canciones urlpatterns = [ path('canciones/', lista_canciones, name='lista_canciones'), ]
$ python manage.py makemigrations $ python manage.py migrate

Forms

Configuración y uso de formularios en Django con autenticación.

Ver documentación

🔹 Paso 1: Crear una nueva aplicación

$ python manage.py startapp app2

🔹 Paso 2: Registrar la aplicación en INSTALLED_APPS

INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app', 'app2', ]

🔹 Paso 3: Configurar AUTH_USER_MODEL

AUTH_USER_MODEL = 'users.CustomUser'

🔹 Paso 4: Crear un modelo personalizado en models.py

Define un modelo de usuario personalizado en la aplicación `app2`.

from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin from django.db import models from django.utils.timezone import now class CustomUserManager(BaseUserManager): def create_user(self, email, password=None, **extra_fields): if not email: raise ValueError('El correo electrónico es obligatorio') email = self.normalize_email(email) user = self.model(email=email, **extra_fields) user.set_password(password) user.save(using=self._db) return user def create_superuser(self, email, password=None, **extra_fields): extra_fields.setdefault('is_staff', True) extra_fields.setdefault('is_superuser', True) return self.create_user(email, password, **extra_fields) class CustomUser(AbstractBaseUser, PermissionsMixin): email = models.EmailField(unique=True) name = models.CharField(max_length=100) surname = models.CharField(max_length=100) control_number = models.CharField(max_length=20, unique=True) age = models.PositiveIntegerField() tel = models.CharField(max_length=15) join_date = models.DateTimeField(default=now) is_active = models.BooleanField(default=True) is_staff = models.BooleanField(default=False) objects = CustomUserManager() USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['name', 'surname', 'control_number', 'age', 'tel'] def __str__(self): return self.email

🔹 Paso 5: Crear un archivo forms.py

Define el formulario de registro y autenticación.

from django import forms from django.contrib.auth.forms import UserCreationForm, AuthenticationForm from .models import CustomUser class CustomUserCreationForm(UserCreationForm): class Meta: model = CustomUser fields = ['email', 'name', 'surname', 'control_number', 'age', 'tel', 'password1', 'password2'] class CustomUserLoginForm(AuthenticationForm): pass

🔹 Paso 6: Migrar la base de datos

Ejecuta los siguientes comandos para aplicar los cambios en la base de datos.

$ python manage.py makemigrations $ python manage.py migrate

Validaciones

Validaciones en Django tanto desde el backend como desde el frontend.

Ver documentación

🔹 Validación desde Back

from django import forms from django.contrib.auth.forms import UserCreationForm, AuthenticationForm from .models import CustomUser class CustomUserCreationForm(UserCreationForm): class Meta: model = CustomUser fields = ['email', 'name', 'surname', 'control_number', 'age', 'tel', 'password1', 'password2'] widgets = { 'email': forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Correo electrónico', 'required': True}), 'password1': forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Contraseña', 'required': True}), }
import re from django.contrib.auth import authenticate class CustomUserLoginForm(AuthenticationForm): username = forms.CharField(label="Correo electrónico", max_length=150) password = forms.CharField(label="Contraseña", widget=forms.PasswordInput) def clean(self): cleaned_data = super().clean() email = cleaned_data.get("username") password = cleaned_data.get("password") if email and not re.match(r"^[a-zA-Z0-9._%+-]+@utez\.edu\.mx$", email): raise forms.ValidationError("El correo debe pertenecer a @utez.edu.mx.") if password and not re.match(r"^(?=.*[0-9])(?=.*[!#$%&?]).{8,}$", password): raise forms.ValidationError("La contraseña debe tener al menos 8 caracteres, incluir un número y un símbolo.") user = authenticate(username=email, password=password) if not user: raise forms.ValidationError("Usuario o contraseña incorrectos.") return cleaned_data

🔹 Validación desde Front


<div class="form-container">
    <h2 class="mb-4">Registro</h2>
    <form method="post" onsubmit="return validateForm()">
        {% csrf_token %}
        <div class="row">
            <div class="col-md-6 mb-3">
                <label class="form-label">Correo electrónico</label>
                <input type="email" name="email" class="form-control" required
                    pattern="^[a-zA-Z0-9]+@utez\.edu\.mx$"
                    title="El correo debe ser institucional @utez.edu.mx">
            </div>
            <div class="col-md-6 mb-3">
                <label class="form-label">Contraseña</label>
                <input type="password" id="password1" name="password1" class="form-control" required minlength="8">
            </div>
        </div>
        <button type="submit" class="btn btn-dark mt-3">Registrarse</button>
    </form>
</div>

              

function validateForm() {
    let password1 = document.getElementById("password1").value;
    let hasNumber = /\d/;
    let hasSymbol = /[!#$%&?]/;

    if (password1.length < 8) {
        Swal.fire("Error", "La contraseña debe tener al menos 8 caracteres.", "error");
        return false;
    }
    if (!hasNumber.test(password1)) {
        Swal.fire("Error", "Debe contener al menos un número.", "error");
        return false;
    }
    if (!hasSymbol.test(password1)) {
        Swal.fire("Error", "Debe contener un símbolo (!, #, $, %, & o ?).", "error");
        return false;
    }

    Swal.fire("¡Éxito!", "Registro exitoso.", "success");
    return true;
}

              

Bootstrap Icons

For the first time ever, Bootstrap has its own open source SVG icon library, designed to work best with our components and documentation.

Bootstrap Icons are designed to work best with Bootstrap components, but they’ll work in any project. They’re SVGs, so they scale quickly and easily, can be implemented in several ways, and can be styled with CSS.

Get Bootstrap Icons

Official Themes

Take Bootstrap to the next level with premium themes from the official Bootstrap Themes marketplace.

Themes are built on Bootstrap as their own extended frameworks, rich with new components and plugins, documentation, and powerful build tools.

Browse Themes