Ir al contenido principal

Bootstrap

Qué es Bootstrap

En la página de CSS quedó claro el problema: para que una página se vea bien hay que escribir hoja de estilos, y escribirla lleva tiempo. Una tabla con bordes, un formulario prolijo, un botón que se note, un menú que en el celular se despliegue solo: todo eso son decenas de líneas de CSS, y hay que resolverlo en cada proyecto.

Bootstrap es una hoja de estilos ya escrita que resuelve eso. Es un framework de CSS —y un poco de JavaScript— que nació en 2011 dentro de Twitter, cuando dos de sus programadores se cansaron de reescribir los mismos estilos en cada proyecto interno. Se publicó como software libre y hoy es uno de los proyectos más usados de la web.

La idea central es simple, y es lo que hay que entender de entrada: no se aprende un lenguaje nuevo ni se cambia el HTML. Se le agregan atributos class a las etiquetas que ya existen, y Bootstrap se encarga del resto.

HTML sin Bootstrap El mismo HTML con Bootstrap
<button>Dar de alta</button> <button class="btn btn-primary">Dar de alta</button>
<input type="text"> <input type="text" class="form-control">
<table> <table class="table table-bordered">

Lo que aporta, en concreto, son cuatro cosas: una tipografía y unos colores base coherentes; una rejilla de 12 columnas para distribuir el contenido; un catálogo de componentes ya dibujados —botones, avisos, tablas, tarjetas, menús, ventanas—; y clases de utilidad para el espaciado, los bordes y la alineación. La versión que se usa en este material es la 5, que ya no necesita jQuery: trae su propio JavaScript.

Qué cambia, con el mismo HTML

Las dos capturas son la misma página: un título, un párrafo, un aviso, tres campos con su etiqueta y un botón. Los dos archivos tienen las mismas etiquetas y el mismo texto. La única diferencia es que la segunda tiene atributos class.

Un formulario de alta de socio sin Bootstrap: título en letra con serifa, etiquetas y campos estrechos uno debajo del otro, aviso en texto común y un botón gris con borde
Sin Bootstrap. El navegador aplica su estilo por defecto: letra con serifa, campos estrechos, botón gris. Nada está mal: ese es el punto de partida.
El mismo formulario de alta de socio con Bootstrap: tipografía sin serifa, campos que ocupan todo el ancho, un aviso amarillo con texto oscuro y un botón azul lleno
Con Bootstrap. Las mismas etiquetas, con clases: letra sin serifa, campos de ancho completo, un aviso con color y un botón azul que se nota.

Conviene ver lo que no cambió: el contenido es el mismo, la estructura es la misma, los name de los campos —que son los que viajan al servidor— son los mismos. Bootstrap es una capa de presentación: cambia cómo se ve, no qué dice ni qué envía. Por eso se puede agregar a un formulario que ya funciona sin tocar una línea del programa que lo procesa.

Cómo se inserta

Bootstrap es, en el fondo, un archivo .css. Insertarlo es lo mismo que se vio en la página de CSS: una etiqueta <link> en el <head>. Lo único que hay que decidir es de dónde sale ese archivo, y hay tres caminos.

Forma Qué hay que hacer Cuándo conviene
CDN
enlace a un servidor ajeno
Pegar una línea en el <head>. No se descarga nada. Para empezar y para practicar. Es la más rápida: no hay archivos que copiar ni rutas que arreglar.
Descarga local Bajar el archivo y copiarlo a una carpeta del proyecto. Cuando no hay internet —un aula, una computadora sin conexión— o cuando el sitio tiene que ser autosuficiente.
Gestor de paquetes
npm y un empaquetador
Instalarlo con npm install bootstrap e importarlo desde la hoja propia. Sitios grandes, donde además se quiere compilar y minimizar el CSS.

1. Por CDN: la línea que se pega

Es lo que usa el proyecto de la tienda, y es la forma más simple: una sola línea dentro del <head>.

<head>
    <meta charset="utf-8">
    <title>Menú Principal</title>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
          rel="stylesheet"
          integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
          crossorigin="anonymous">
    <link href="styles.css" rel="stylesheet">
</head>

Cada parte de esa etiqueta tiene su motivo:

  • href apunta al archivo en el servidor del CDN. La versión está fijada en la dirección (@5.3.3). Si se dejara sin número, el CDN entregaría siempre la última y el sitio podría romperse solo el día que salga una versión nueva.
  • integrity es la huella digital del archivo. El navegador la calcula y la compara: si el archivo que devuelve el CDN no coincide exactamente con esa huella, lo descarta y no lo aplica. Sirve para cubrir el caso de que alguien altere el archivo en el servidor ajeno. Es la razón por la que ese código parece un galimatías: no se escribe a mano, se copia del sitio de Bootstrap junto con la dirección.
  • crossorigin="anonymous" acompaña al anterior: indica que el archivo se pide sin credenciales. Sin él, el navegador no puede comprobar la huella.

El CDN (Content Delivery Network, red de distribución de contenido) es un servidor que entrega archivos públicos para que no haya que alojarlos. Tiene una ventaja práctica: como muchísimos sitios usan el mismo archivo, es probable que el navegador ya lo tenga en la caché de otra visita y no lo descargue de nuevo. Y una desventaja que hay que tener presente: el sitio depende de internet. Sin conexión, no hay estilos.

2. Con el archivo propio: funciona sin internet

Se descarga el paquete, se copia el archivo a una carpeta del proyecto y se lo enlaza con una ruta relativa, igual que cualquier hoja propia:

mi-sitio/
├── css/
│   ├── bootstrap.min.css     ← el archivo copiado
│   └── estilos.css           ← la hoja propia
└── index.php
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="css/estilos.css" rel="stylesheet">

Ventaja: el sitio no depende de nadie. Desventaja: actualizar Bootstrap a mano cuando salga una versión nueva.

3. Con un gestor de paquetes: cómo lo hace este mismo sitio

Las páginas de este material también usan Bootstrap, pero lo instalan con npm y lo compilan con Vite. En lugar de un <link> al CDN hay una importación dentro de la hoja propia:

/* resources/css/app.css */

@import 'bootstrap/dist/css/bootstrap.min.css';
@import 'bootstrap-icons/font/bootstrap-icons.css';
// resources/js/app.js

import 'bootstrap';

Vite lee esas importaciones, junta todo, lo minimiza y escribe un solo archivo en public/build/, que es el que el navegador descarga. Es la forma más ordenada, y también la que más piezas necesita: requeriría explicar npm, un empaquetador y un paso de compilación antes de poder mostrar un botón azul. Por eso, para la materia, alcanza con el CDN o con el archivo copiado.

¿Y el JavaScript? Solo si hace falta

El archivo .css alcanza para la tipografía, la rejilla, los botones, las tablas y los formularios: todo lo que no se mueve. Algunos componentes sí necesitan JavaScript —el menú desplegable, la ventana emergente, el acordeón, la pestaña, el aviso que se cierra—, y para eso va una segunda etiqueta, antes de cerrar el <body>:

<body>
    ... toda la página ...

    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
            integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
            crossorigin="anonymous"></script>
</body>

La palabra clave es bundle: ese archivo ya incluye Popper, una biblioteca de posicionamiento que Bootstrap necesita para ubicar las ventanas y los menús. La etiqueta va al final del body y no en el head por una razón de velocidad: el navegador lee el HTML de arriba hacia abajo, y si se detuviera a descargar y ejecutar un script antes de dibujar la página, el usuario vería la pantalla en blanco unos segundos.

El orden de las hojas: por qué va primero Bootstrap

En las dos formas anteriores, Bootstrap aparece antes que la hoja propia. No es una manía de orden: es la cascada la que lo exige.

Cuando dos reglas afectan al mismo elemento y tienen la misma fuerza, gana la última que se escribió. Y eso, cuando hay varias hojas, se resuelve por el orden de las etiquetas <link>: la que va después es la última.

Orden Quién gana Consecuencia
Bootstrap, después estilos.css La hoja propia Los ajustes propios se aplican. Es lo que se busca.
estilos.css, después Bootstrap Bootstrap Los ajustes propios se ignoran y el sitio se ve «de fábrica». Es el famoso «cambié el CSS y no pasa nada».

La forma de pensarlo: Bootstrap pone el piso y la hoja propia decide lo que queda distinto. Si se invierte, el framework pisa todo lo escrito. Y hay un detalle importante: la cascada se decide por el orden de las etiquetas, no por el de los archivos en la carpeta.

La rejilla: repartir el ancho en 12 columnas

Es la pieza más útil y la que más se usa. La idea es que todo el ancho de la página se divide imaginariamente en 12 columnas, y cada bloque declara cuántas ocupa. Con eso se arma cualquier distribución sin escribir CSS: dos mitades son 6 + 6, un menú chico con contenido son 3 + 9, tres tarjetas son 4 + 4 + 4.

La rejilla tiene tres niveles que se anidan uno dentro del otro, y el orden importa:

<div class="container">          <!-- 1. el ancho máximo y los márgenes -->
    <div class="row">            <!-- 2. la fila, que agrupa columnas -->

        <div class="col-md-6">…</div>   <!-- 3. las columnas -->
        <div class="col-md-6">…</div>

    </div>
</div>
  • container centra el contenido y le pone un ancho máximo según el tamaño de la pantalla. Es lo que evita que el texto llegue de borde a borde en un monitor grande. container-fluid en cambio ocupa todo el ancho siempre.
  • row junta las columnas de una misma fila y compensa los márgenes internos de cada una.
  • col reparte el ancho. Sin número, todas las columnas de la fila se reparten el espacio en partes iguales.

Ahora, lo que hace que la rejilla sirva de verdad: el número puede cambiar según el ancho de la pantalla. Se declara una clase por tamaño, y Bootstrap aplica la que corresponde. Las medidas de referencia son estas (en píxeles de ancho de ventana):

Nombre Se aplica desde Se escribe Pensado para
xs0 (siempre)col-12Celulares parados.
sm576 pxcol-sm-6Celulares acostados.
md768 pxcol-md-4Tabletas. Es el punto de quiebre que más se usa.
lg992 pxcol-lg-3Notebooks.
xl1200 pxcol-xl-2Monitores grandes.
xxl1400 pxcol-xxl-1Monitores muy anchos.

Los nombres xs, sm, md, lg… se llaman puntos de quiebre (breakpoints): los anchos en los que el diseño cambia de forma. Y hay una regla que se ve en la tabla y hay que retener: se aplican hacia arriba. La clase col-md-6 no solo rige en el ancho de tableta, sino en todas las pantallas más grandes, salvo que otra clase la reemplace.

De ahí sale la forma típica de escribir un bloque que se adapta, y que se lee de menor a mayor:

<div class="col-12 col-md-6 col-lg-4">…</div>

Traducido: en el celular ocupa todo el ancho (las 12 columnas, una tarjeta por fila); desde la tableta, la mitad (dos por fila); desde el notebook, un tercio (tres por fila). Una sola línea, y el diseño se acomoda solo. Esto es lo que se llama empezar por el celular (mobile first), que es justamente cómo está pensado Bootstrap: lo que se declara sin prefijo vale para todos los tamaños, y después se agregan excepciones hacia arriba.

Hay una advertencia que conviene tener a mano, porque es el error que hace que todo se descoloque: una col va siempre dentro de un row. Las columnas tienen márgenes internos para separarse entre sí, y el row los compensa. Sin él, esos márgenes se suman al ancho y aparece una barra de desplazamiento horizontal que no debería estar, o columnas que no se acomodan como se espera.

Los componentes

Un componente es una pieza ya dibujada a la que se le pone el contenido. La forma de usarlo es siempre la misma: se elige la clase base —btn, alert, table, card— y se le agrega una segunda clase que define la variante, casi siempre por color.

Componente Clases Ejemplo
Botón btn + btn-primary, btn-success, btn-danger, btn-outline-secondary, btn-sm. <button class="btn btn-primary">Guardar</button>
Aviso alert + alert-warning, alert-danger, alert-success. <div class="alert alert-warning">Atención…</div>
Tabla table + table-bordered, table-striped, table-hover. <table class="table table-bordered">
Etiqueta de campo form-label <label class="form-label">Nombre</label>
Campo de texto form-control <input type="text" class="form-control">
Lista desplegable form-select <select class="form-select">
Tarjeta card, card-body, card-title. <div class="card"><div class="card-body">…

Y las utilidades, que son clases cortas para retoques sueltos. El m y el p son margin y padding; el número es la cantidad, en una escala fija de 0 a 5, y la letra final indica el lado:

Clase Qué hace
mt-3Margen arriba (margin-top), escala 3. Separar un bloque del anterior.
mb-0Saca el margen de abajo. Muy usado para que el último párrafo no deje un hueco antes del borde.
py-4Relleno arriba y abajo (padding-y), escala 4. Dar aire dentro de un contenedor.
g-3La separación entre las columnas de una fila (gap).
text-center / text-endAlinear el texto al centro o a la derecha.
text-mutedBajarle el contraste a un texto secundario.
w-100Ancho completo.

Los lados se abrevian con una letra: t arriba (top), b abajo (bottom), s izquierda, e derecha, x los dos lados horizontales, y los dos verticales. La s y la e —start y end— son una decisión de diseño que se explica más abajo, entre los errores comunes.

Un formulario completo, con la rejilla y los componentes

Juntando lo anterior: el formulario de alta de socios de la biblioteca, propio de esta unidad, ahora con Bootstrap. Los name son los mismos de siempre —los que necesita $_POST— y lo único que se agregó son las clases.

<div class="container py-4">

    <h1 class="h3">Alta de socio</h1>

    <form action="alta.php" method="post" class="row g-3">

        <div class="col-md-8">
            <label for="nombre" class="form-label">Nombre y apellido</label>
            <input type="text" id="nombre" name="nombre" class="form-control" required>
        </div>

        <div class="col-md-4">
            <label for="documento" class="form-label">Documento</label>
            <input type="text" id="documento" name="documento" class="form-control" required>
        </div>

        <div class="col-md-6">
            <label for="correo" class="form-label">Correo electrónico</label>
            <input type="email" id="correo" name="correo" class="form-control">
        </div>

        <div class="col-md-6">
            <label for="localidad" class="form-label">Localidad</label>
            <select id="localidad" name="localidad" class="form-select">
                <option value="">Elegir…</option>
                <option value="san-francisco">San Francisco</option>
                <option value="frontera">Frontera</option>
            </select>
        </div>

        <div class="col-12">
            <button type="submit" class="btn btn-primary">Dar de alta</button>
            <a href="listado.php" class="btn btn-outline-secondary">Cancelar</a>
        </div>

    </form>
</div>

Tres cosas de ese código que valen más que las clases mismas:

  • La fila no se cierra después de cada campo. Las cuatro columnas van dentro del mismo row y Bootstrap las acomoda: en una pantalla grande entran dos por renglón (8+4 y 6+6) y en el celular cada una ocupa todo el ancho. Si se cerrara la fila en cada campo, cada uno quedaría solo.
  • El name y el id siguen ahí, intactos. El name es el que viaja al servidor y el id es el que une la etiqueta con el campo. Ninguna clase de Bootstrap los reemplaza: el aspecto es una cosa y el dato es otra.
  • El botón de cancelar es un enlace, no un botón. Como no envía nada, no puede ser un submit; pero con la clase btn se ve igual que un botón. Es un ejemplo del tipo de decisión que aparece todo el tiempo: primero se decide qué hace el elemento y después cómo se ve.

Y una advertencia sobre el required: es el mismo de la página de HTML, la validación del navegador. Bootstrap lo hace visible —cuando el campo está mal, lo marca en rojo y muestra el mensaje—, pero no agrega ninguna validación. Si el atributo no está, no hay control. Y como se vio en Formularios web, la validación del navegador se saltea con una petición armada a mano: la que vale es la del servidor.

Bootstrap Icons

Bootstrap tiene, aparte, una biblioteca de iconos. No viene incluida en el archivo de Bootstrap: es un proyecto separado que se inserta igual —con su propia hoja de estilos— y que sirve para poner símbolos sin depender de imágenes.

<link href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.min.css"
      rel="stylesheet">

Después, cada icono es una etiqueta <i> con dos clases: bi y el nombre del icono. Estos seis son los que aparecen en casi cualquier sistema de carga de datos:

Icono Clase Para qué se usa
bi-plus-lg Agregar. El botón del menú que lleva al alta de un registro nuevo.
bi-pencil-square Modificar. El botón de la fila del listado que abre el formulario con los datos cargados.
bi-trash Eliminar. El botón de baja de la fila. Como destruye, va con cuidado: en rojo y siempre con confirmación.
bi-search Buscar. El botón del filtro del listado, o el que acompaña al campo de búsqueda.
bi-check-lg Confirmar o guardar. El botón que envía el formulario. Es el que más se repite.
bi-download Descargar o exportar. El botón que baja el listado o la planilla de notas a un archivo.

Los seis se ven dibujados ahí arriba porque los dibuja el propio Bootstrap Icons en esta misma página: no son imágenes ni capturas. Y como son texto, se les cambia el color y el tamaño con las herramientas de siempre —el text-danger los pinta de rojo y el fs-5 los agranda—, y además heredan el color de donde estén: dentro de un btn-danger salen blancos, sin hacer nada.

La forma de usarlos es poner el icono adelante del texto, con un espacio en el medio:

<button type="submit" class="btn btn-primary">
    <i class="bi bi-check-lg"></i> Guardar
</button>

<a href="eliminar.php?id=7" class="btn btn-sm btn-outline-danger">
    <i class="bi bi-trash"></i> Eliminar
</a>

Errores comunes

Qué se ve Qué pasó Cómo se arregla
Todo se ve sin estilos, como antes de usar Bootstrap. Falta la etiqueta <link>, la ruta está mal, o falta internet si el enlace es al CDN. Mirar el código fuente de la página y comprobar que el enlace llega. Es el primer lugar donde hay que mirar siempre.
Las clases están, pero no cambia nada. La hoja propia está antes que la de Bootstrap, y la cascada descarta los cambios. Poner Bootstrap primero y la hoja propia después.
Aparece una barra de desplazamiento horizontal y las columnas no se acomodan. Una col fuera de un row, o un row fuera de un container. Respetar los tres niveles: container → row → col.
La clase existe pero no hace nada (ml-3, text-left). Son nombres de Bootstrap 4, cambiados en la versión 5. Usar los de la 5: ms-3, text-start.
El menú desplegable no se abre. Falta el <script> de Bootstrap antes de cerrar el body. Agregar el bootstrap.bundle.min.js: el CSS no alcanza para lo que se mueve.
El formulario se ve bien pero llega vacío al servidor. Se tocaron los class y, sin querer, los name. Revisar los name: son los únicos que el programa lee.

Sobre ms-3, el cambio de la versión 4 a la 5 merece una explicación, porque el motivo es interesante. En Bootstrap 5 ml-3 —margin-left— pasó a llamarse ms-3, con s de start; y mr-3 pasó a me-3, con e de end. La razón es la escritura de derecha a izquierda: en árabe o en hebreo, «izquierda» y «derecha» se invierten, y una clase llamada ml quedaría del lado equivocado. Con start y end, la clase se refiere a donde empieza y donde termina el texto, y funciona en los dos sentidos de escritura.

El mismo cambio tocó a las clases de alineación y de flotación: text-left pasó a text-start, float-right a float-end. Copiar ejemplos viejos de internet es la fuente más común de estas clases que «no existen».

Cuándo conviene usarlo y cuándo no

Bootstrap es una herramienta, no una obligación, y tiene un costo concreto: el archivo completo pesa alrededor de 232 KB antes de comprimirse. Para un formulario de alta es una enormidad. Lo que se compra con eso es tiempo.

Conviene No conviene
Cuando el objetivo es la funcionalidad —una pantalla que carga datos, un panel interno, un panel de administración— y el diseño no es el tema. Cuando el objetivo es aprender CSS. Usar el framework primero esconde justamente lo que se quiere aprender.
Para prototipos y trabajos escolares: en minutos se ve prolijo y ordenado, y el esfuerzo va a lo que sí importa. Cuando el diseño tiene identidad propia. Todo sitio Bootstrap se parece bastante a otro sitio Bootstrap.
Cuando hay que publicar algo rápido y el tiempo de escribir los estilos no está. Cuando el peso o el rendimiento importan: hay sitios donde cargar 232 KB de estilos para usar tres botones es un desperdicio.

El proyecto de la unidad es un caso típico del cuadro de la izquierda: lo que se está enseñando es el camino del dato —de la pantalla a la tabla— y el formulario tiene que verse presentable para que el usuario entienda qué se le pide. Un framework resuelve eso y deja el esfuerzo para el SQL, la validación y el POST, que es donde está el contenido de la materia.

Y el camino intermedio, que es el que se usa en la práctica: tomar solo lo que hace falta. En vez del archivo completo, se puede escribir a mano el CSS de los cuatro componentes que el sistema usa. Es más trabajo y menos riesgo; la elección depende de cuánto tiempo haya. Lo que no sirve es ninguna de las dos posturas extremas: ni escribir todo desde cero por orgullo, ni aceptar que el sitio se vea «de fábrica» porque sí.

Resumen

  • Bootstrap es una hoja de estilos ya escrita: se usa agregando atributos class al HTML que ya existe.
  • Aporta tipografía y colores base, una rejilla de 12 columnas, componentes y utilidades de espaciado.
  • Se inserta con una etiqueta <link> en el <head>: desde un CDN, con el archivo copiado al proyecto, o con un gestor de paquetes.
  • La versión de la dirección tiene que estar fijada, y el integrity es la huella que verifica que el archivo llegue sin alteraciones.
  • Bootstrap va antes que la hoja propia: la cascada decide por el orden de las etiquetas, y la última gana.
  • La rejilla se anida container → row → col, y la columna declara cuántas de las 12 ocupa.
  • Las clases col-md-6 se aplican hacia arriba, y se escriben de menor a mayor: col-12 col-md-6 col-lg-4.
  • El JavaScript solo hace falta para los componentes que se mueven (menú, ventana, acordeón), y va antes de cerrar el body.
  • Bootstrap cambia cómo se ve, no qué datos viajan: los name y la validación del servidor no se tocan.
  • Es una herramienta con costo: conviene cuando el objetivo es la funcionalidad, y estorba cuando el objetivo es aprender CSS.

Seguir con los tipos de ingreso