Por qué un simple salto de línea merece atención
Escribir una dirección postal en una página web parece trivial hasta que lo intentas por primera vez. Pulsas Enter en el editor, guardas el archivo, abres el navegador y descubres que todo el texto aparece en una sola línea. No es un error del navegador: es exactamente como HTML está diseñado para comportarse. Los saltos de línea que escribes en el código fuente no se trasladan a la página.
Para insertar un salto de línea dentro de un bloque de texto, HTML ofrece un elemento específico: <br>. Es uno de los elementos más antiguos y sencillos del lenguaje, y al mismo tiempo uno de los más mal utilizados. Durante años se empleó para separar párrafos, crear espacio vertical entre secciones o maquetar formularios, tareas que hoy corresponden a CSS y que con <br> producen páginas frágiles y poco accesibles.
En esta guía veremos cómo funciona <br> según el estándar vivo de HTML que mantiene el WHATWG, en qué casos es la herramienta correcta y en cuáles conviene sustituirlo. También repasaremos cómo controlar los saltos de línea desde CSS, cómo manejar texto con saltos que llega desde una base de datos o un formulario, cómo hacerlo con JavaScript sin abrir la puerta a vulnerabilidades y qué ocurre con los lectores de pantalla. Al final tendrás criterios claros para decidir, en cada situación, entre <br>, un nuevo párrafo o una regla de estilo.
Cómo trata HTML los espacios y los saltos de línea
Para entender por qué existe <br>, primero hay que entender cómo procesa el navegador los espacios en blanco del código. Por defecto, cualquier secuencia de espacios, tabulaciones y saltos de línea dentro del texto se colapsa en un único espacio. Este comportamiento permite indentar y organizar el código fuente con libertad sin que esa organización afecte al resultado visual.
Observa este fragmento:
<p>Calle de los Olivos 42 Colonia Centro Monterrey, Nuevo León</p>
Aunque en el código hay tres líneas, el navegador mostrará algo equivalente a esto:
Calle de los Olivos 42 Colonia Centro Monterrey, Nuevo León
El motivo es que, para HTML, el contenido de un párrafo es un flujo continuo de texto que se ajusta al ancho disponible. Las líneas visibles en pantalla dependen del tamaño de la ventana, no de dónde pulsaste Enter. Si quieres que el texto se corte en un punto exacto, tienes que decírselo al navegador de forma explícita, y ahí es donde entra <br>.
Este colapso de espacios lo controla en realidad CSS, mediante la propiedad white-space. El valor por defecto, normal, es el que colapsa los espacios. Más adelante veremos cómo cambiarlo para que el navegador respete los saltos del texto original, lo que en muchos casos es una alternativa mejor que llenar el marcado de etiquetas.
La etiqueta br en HTML: sintaxis y comportamiento
El uso de la etiqueta br en HTML es muy sencillo. Se coloca exactamente donde quieres que termine una línea y comience la siguiente:
<p>
Calle de los Olivos 42<br />
Colonia Centro<br />
Monterrey, Nuevo León
</p>
Ahora el navegador mostrará la dirección en tres líneas, todas dentro del mismo párrafo. Ese matiz es importante: <br> no crea un párrafo nuevo ni un bloque nuevo, solo rompe la línea dentro del bloque en el que se encuentra.
<br> es un elemento vacío, también llamado elemento sin contenido. No puede contener texto ni otros elementos, por lo que no tiene etiqueta de cierre. Por ese motivo verás tres formas de escribirlo:
<br />
<br />
<br />
En HTML las tres son válidas y producen el mismo resultado. La barra final es opcional y el navegador la ignora. Su presencia es una herencia de XHTML, donde era obligatoria, y de algunos entornos como JSX, donde también lo es. En un documento HTML normal, lo más habitual y limpio es escribir simplemente <br>.
Lo que sí es incorrecto es escribir una etiqueta de cierre:
<!-- Incorrecto -->
<p>Primera línea</br>Segunda línea</p>
Los navegadores son tolerantes y, por razones históricas, interpretan </br> como si fuera <br>, pero el validador lo marcará como error y otras herramientas que procesan HTML pueden comportarse de forma distinta. Conviene evitarlo.
Cuándo br es la herramienta adecuada
La especificación de HTML es clara sobre el propósito de este elemento: los saltos de línea deben formar parte del contenido, no de la presentación. Es decir, <br> se justifica cuando el corte de línea tiene significado por sí mismo y desaparecería información si se eliminara.
Hay varios casos clásicos que cumplen esa condición. El primero son las direcciones postales, donde cada línea representa una parte distinta de la dirección:
<address>
Estudio Lumen Digital<br />
Avenida Reforma 1180, piso 7<br />
Ciudad de México, CDMX 06600
</address>
El segundo son los poemas, letras de canciones propias o cualquier texto en verso, donde la división en líneas forma parte de la obra:
<p>
Compila el código al amanecer,<br />
revisa los tests al mediodía,<br />
y al caer la tarde, sin temer,<br />
despliega a producción con alegría.
</p>
El tercero son bloques de datos de contacto o firmas en los que cada dato ocupa su propia línea, como el pie de una tarjeta de presentación:
<p class="firma">
Daniela Ortega<br />
Arquitecta de software<br />
[email protected]
</p>
En todos estos casos, si quitas los saltos, el contenido pierde estructura. Una dirección en una sola línea sigue siendo legible, pero un poema sin versos deja de ser un poema. Ese es el criterio práctico: si el salto forma parte de lo que quieres decir, <br> es correcto.
Cuándo no usar br
La tentación habitual es usar <br> para conseguir efectos visuales: separar dos párrafos, dejar espacio antes de un título o empujar un botón hacia abajo. Este uso es el que se considera una mala práctica, y por buenas razones.
Este es el patrón que conviene evitar:
<!-- Patrón a evitar -->
<p>Nuestro equipo atiende de lunes a viernes.</p>
<br /><br /><br />
<h2>Preguntas frecuentes</h2>
<p>Primera pregunta...<br /><br />Segunda pregunta...</p>
Este marcado tiene varios problemas. El espacio vertical depende del tamaño de fuente, así que cambia de forma impredecible en cada dispositivo. Si mañana necesitas más o menos separación, tendrás que editar el HTML en cada página en lugar de modificar una regla de estilo. Y para quienes usan lectores de pantalla, los dos <br> seguidos dentro del párrafo no indican que haya dos preguntas distintas: para la tecnología de asistencia sigue siendo un único párrafo.
La versión correcta separa el contenido de la presentación:
<p>Nuestro equipo atiende de lunes a viernes.</p>
<h2>Preguntas frecuentes</h2>
<p>Primera pregunta...</p>
<p>Segunda pregunta...</p>
h2 {
margin-block-start: 3rem;
}
p + p {
margin-block-start: 1rem;
}
Ahora cada idea está en su propio párrafo, el título tiene su propio espacio definido en CSS y cualquier ajuste futuro se hace en un solo lugar. La regla general es sencilla: si quieres separar ideas, usa párrafos; si quieres separar visualmente bloques, usa márgenes.
Separar elementos con CSS en lugar de br
Una vez que se abandona <br> como herramienta de maquetación, CSS ofrece varias formas de separar elementos con CSS de manera precisa y mantenible. La más básica son los márgenes, preferiblemente con propiedades lógicas que respetan la dirección de escritura:
.tarjeta {
margin-block-end: 1.5rem;
padding: 1rem 1.25rem;
}
Las propiedades margin-block-start y margin-block-end equivalen a los márgenes superior e inferior en idiomas que se escriben de arriba abajo, y se adaptan automáticamente si el diseño se usa con otros modos de escritura.
Cuando los elementos están dentro de un contenedor flexible o de rejilla, la propiedad gap es todavía más cómoda, porque define el espacio entre hijos sin tener que preocuparse por el primero o el último:
<div class="pila">
<label for="correo">Correo electrónico</label>
<input id="correo" type="email" />
<button type="submit">Suscribirme</button>
</div>
.pila {
display: flex;
flex-direction: column;
gap: 0.75rem;
}
Este patrón sustituye el antiguo hábito de poner <br> entre etiqueta, campo y botón en los formularios. El resultado se puede ajustar con un solo valor y se comporta bien en pantallas de cualquier tamaño.
También existe el caso contrario: elementos que por defecto aparecen en la misma línea, como enlaces o imágenes, y que queremos apilar. En lugar de insertar <br> entre ellos, basta con cambiar su forma de mostrarse:
.lista-enlaces a {
display: block;
}
Con display: block, cada enlace ocupa su propia línea sin tocar el HTML, y si en una versión de escritorio prefieres mostrarlos en fila, una media query lo resuelve.
Respetar los saltos del texto con white-space
En muchas aplicaciones, el texto no se escribe a mano en el HTML: llega de una base de datos, de un campo de formulario o de una API, y ya contiene saltos de línea como caracteres \n. Pensemos en la descripción de un producto que un administrador escribió en un <textarea> separando las ideas en líneas.
Si mostramos ese texto directamente, el navegador colapsará los saltos, como vimos al principio. La solución más limpia no es convertir cada \n en <br>, sino indicarle a CSS que respete los saltos de línea:
<p class="descripcion">
Mochila impermeable de 25 litros. Compartimento acolchado para portátil de
15 pulgadas. Correas ajustables con espuma transpirable.
</p>
.descripcion {
white-space: pre-line;
}
El valor pre-line conserva los saltos de línea del texto, pero sigue colapsando los espacios múltiples y permite que las líneas largas se ajusten al ancho del contenedor. Es exactamente lo que se suele necesitar para contenido escrito por personas.
La propiedad white-space admite otros valores útiles según el caso:
normal: colapsa espacios y saltos; es el valor por defecto.pre: respeta espacios y saltos, pero no ajusta líneas largas; es el comportamiento del elemento<pre>.pre-wrap: respeta espacios y saltos y además ajusta las líneas largas.pre-line: respeta solo los saltos y ajusta las líneas largas.nowrap: colapsa espacios y evita cualquier ajuste de línea.
En las especificaciones recientes de CSS, white-space se ha convertido en una propiedad abreviada que combina otras más específicas, como white-space-collapse y text-wrap-mode. Para la mayoría de los proyectos, seguir usando white-space con los valores anteriores es lo más práctico y compatible.
Para fragmentos de código o texto preformateado en los que importan también los espacios, el elemento adecuado es <pre>:
<pre>
servidor:
puerto: 8080
modo: produccion
</pre>
Saltos de línea con JavaScript sin riesgos
Al trabajar con contenido dinámico, una solución muy extendida es reemplazar los \n por <br> y asignar el resultado con innerHTML. Funciona, pero introduce un riesgo serio de seguridad. Gestionar saltos de línea con JavaScript de esta forma permite que cualquier HTML contenido en el texto se interprete, incluidos scripts maliciosos.
Este es el patrón peligroso:
// Patrón vulnerable a XSS: no lo uses con texto de usuarios
const comentario = obtenerComentarioDelServidor();
contenedor.innerHTML = comentario.replace(/\n/g, "<br>");
Si un usuario escribe en su comentario algo como <img src=x onerror="robarSesion()">, ese código se ejecutará en el navegador de quien lea la página. Es una vulnerabilidad de tipo cross-site scripting.
La alternativa más sencilla combina textContent, que nunca interpreta HTML, con la regla de CSS que vimos en la sección anterior:
const comentario = obtenerComentarioDelServidor();
contenedor.textContent = comentario;
contenedor.style.whiteSpace = "pre-line";
Si por algún motivo necesitas elementos <br> reales en el DOM, puedes construirlos con métodos seguros en lugar de concatenar cadenas:
function mostrarConSaltos(contenedor, texto) {
contenedor.replaceChildren();
const lineas = texto.split("\n");
lineas.forEach((linea, indice) => {
if (indice > 0) {
contenedor.append(document.createElement("br"));
}
contenedor.append(document.createTextNode(linea));
});
}
mostrarConSaltos(
document.querySelector("#nota"),
"Pedido confirmado\nEnvío estimado: 3 días\nGracias por tu compra"
);
Cada línea se inserta como nodo de texto, de modo que cualquier carácter especial se muestra tal cual y nunca se ejecuta. En frameworks como React, el principio es el mismo: evita dangerouslySetInnerHTML y aplica white-space: pre-line al elemento o divide el texto en líneas dentro del JSX:
function Nota({ texto }) {
return <p style={{ whiteSpace: "pre-line" }}>{texto}</p>;
}
Romper palabras largas con wbr y CSS
Un problema relacionado, pero distinto, aparece con palabras o cadenas muy largas que no caben en el contenedor: URLs, nombres de archivos, identificadores o términos técnicos compuestos. En estos casos no quieres un salto obligatorio, sino un punto donde el navegador pueda cortar si lo necesita.
Para eso existe el elemento <wbr>, otro elemento vacío que marca una oportunidad de corte:
<p>
Descarga el archivo informe<wbr />_trimestral<wbr />_ventas<wbr />_2026<wbr />.pdf
desde el panel.
</p>
Si hay espacio suficiente, la palabra se muestra completa; si no, el navegador corta en alguno de los puntos marcados. A diferencia de <br>, <wbr> nunca fuerza un salto.
Cuando no controlas el contenido, por ejemplo con URLs que introducen los usuarios, CSS es más práctico para romper palabras largas sin tocar el marcado:
.contenido-usuario {
overflow-wrap: anywhere;
}
overflow-wrap: anywhere permite cortar en cualquier punto solo cuando una palabra no cabe, evitando que desborde el diseño en pantallas pequeñas. Para textos en idiomas con palabras compuestas largas, también puede ayudar hyphens: auto junto con el atributo lang correcto en el documento.
Accesibilidad y lectores de pantalla
Los lectores de pantalla no anuncian los elementos <br> como tales. En general, tratan el salto como una pequeña pausa o simplemente continúan leyendo el texto. Esto tiene una consecuencia importante: la estructura que construyes con <br> es puramente visual y no llega a quienes navegan por la página con tecnología de asistencia.
Por ejemplo, este marcado parece una lista en pantalla:
<p>
Ingredientes:<br />
- 200 g de harina<br />
- 2 huevos<br />
- 100 ml de leche
</p>
Pero para un lector de pantalla es un único párrafo. El usuario no sabe cuántos elementos tiene la lista ni puede saltar de uno a otro. La versión accesible usa una lista real:
<h3>Ingredientes</h3>
<ul>
<li>200 g de harina</li>
<li>2 huevos</li>
<li>100 ml de leche</li>
</ul>
Ahora la tecnología de asistencia anuncia que hay una lista con tres elementos y permite navegar entre ellos. Lo mismo ocurre con secciones, títulos y párrafos: cada vez que usas <br> para simular una estructura que HTML ya ofrece con un elemento propio, la página pierde semántica.
Otro detalle a tener en cuenta es la traducción automática y el ajuste de texto. Un <br> colocado para que un titular quede bonito en una resolución concreta puede producir cortes absurdos en otros idiomas o tamaños de pantalla. Para equilibrar titulares, CSS ofrece text-wrap: balance, que reparte el texto entre líneas de forma más uniforme sin fijar el punto de corte:
h1 {
text-wrap: balance;
}
Saltos de línea en otros contextos
<br> solo funciona dentro del HTML que el navegador renderiza. Hay varios contextos relacionados donde los saltos de línea se gestionan de otra manera, y confundirlos es una fuente frecuente de errores.
En un <textarea>, el contenido es texto plano y los saltos de línea se escriben literalmente. Una etiqueta <br> dentro de un <textarea> aparecerá como texto, no como salto:
<textarea name="mensaje" rows="4">
Hola,
quisiera más información sobre el plan anual.</textarea
>
En los atributos, como title o alt, tampoco tiene efecto. Si necesitas un salto dentro del atributo title de un tooltip nativo, puedes usar la referencia de carácter de salto de línea, aunque su visualización depende del navegador:
<abbr title="HyperText Markup Language Lenguaje de marcado de hipertexto"
>HTML</abbr
>
En Markdown, que muchos generadores de sitios estáticos convierten a HTML, un salto simple dentro de un párrafo se ignora. Para forzarlo, se terminan las líneas con dos espacios o con una barra invertida, según el procesador, o se escribe directamente <br> si el motor permite HTML en línea:
Avenida Juárez 210\
Guadalajara, Jalisco
Y en los correos electrónicos HTML, donde el soporte de CSS en los clientes de correo es más limitado, <br> sigue siendo más habitual que en la web, aunque se recomienda igualmente usar párrafos para separar bloques de texto.
Errores comunes y cómo evitarlos
Varios errores se repiten con frecuencia al trabajar con saltos de línea.
El primero es encadenar varios <br> para crear espacio. Cuando veas dos o más seguidos, casi siempre la solución correcta es un nuevo párrafo o un margen en CSS.
El segundo es usar <br> dentro de listas, tablas o formularios para separar elementos que deberían ser elementos propios. Si el contenido tiene forma de lista, usa <ul> u <ol>; si tiene forma de tabla, usa <table>.
El tercero es colocar <br> al final de un párrafo o justo antes de cerrar un bloque, lo que añade una línea vacía que no aporta nada y a veces descuadra el diseño:
<!-- Innecesario -->
<p>Gracias por registrarte.<br /></p>
El cuarto es escribir </br> como etiqueta de cierre, que ya vimos que es inválido aunque el navegador lo tolere.
El quinto, y más grave, es convertir saltos de línea a <br> con innerHTML en contenido que procede de usuarios, lo que abre la puerta a ataques de inyección.
Una forma rápida de detectar algunos de estos problemas es pasar el documento por un validador de HTML o configurar un linter en el proyecto. Por ejemplo, con html-validate puedes revisar los archivos desde la terminal:
npx html-validate "src/**/*.html"
src/contacto.html
14:22 error Stray end tag "</br>" parser-error
✖ 1 problem (1 error, 0 warnings)
El mensaje concreto puede variar según la herramienta y su configuración, pero cualquier validador moderno señalará la etiqueta de cierre inválida.
Comparativa de alternativas
Para decidir rápidamente qué usar en cada caso, conviene tener una visión de conjunto de las opciones disponibles:
<br>: salto de línea obligatorio que forma parte del contenido, como en direcciones o versos.<p>: separar ideas o bloques de texto independientes.- Listas
<ul>y<ol>: enumerar elementos relacionados. - Márgenes y
gapen CSS: crear espacio visual entre elementos. display: block: apilar elementos que por defecto van en línea.white-space: pre-line: respetar los saltos de texto que viene de datos o de formularios.<pre>: mostrar texto preformateado donde importan espacios y saltos.<wbr>yoverflow-wrap: permitir cortes en palabras largas sin forzarlos.text-wrap: balance: equilibrar titulares sin fijar cortes manuales.
Cada una resuelve un problema distinto. La clave está en identificar si lo que buscas es un cambio de significado, de estructura o de presentación. Solo en el primer caso la respuesta es <br>.
Casos de uso reales
Veamos cómo se combinan estas herramientas en situaciones típicas de un proyecto web.
En el pie de página de una tienda en línea, la dirección física de la empresa se marca con <address> y <br> entre líneas, porque cada línea es un dato distinto. Los enlaces legales del mismo pie se colocan en una lista y se separan con gap, no con saltos.
En un sistema de comentarios, el texto que escriben los usuarios se guarda tal cual, con sus \n, y se muestra con textContent y white-space: pre-line. Así se respetan los párrafos que escribió cada persona sin riesgo de inyección de código.
En la ficha de un producto, la descripción larga que redacta el equipo de contenido se gestiona desde un CMS que produce párrafos reales, mientras que las especificaciones técnicas se presentan como una lista o una tabla.
En una página de documentación técnica, los nombres de archivos y rutas largas se envuelven en un contenedor con overflow-wrap: anywhere para que no rompan el diseño en móviles, y los fragmentos de configuración se muestran dentro de <pre>.
Impacto en SEO y en la indexación del contenido
Los motores de búsqueda leen el HTML de forma parecida a como lo hacen las tecnologías de asistencia: prestan atención a la estructura semántica para entender qué partes del contenido son títulos, párrafos, listas o datos de contacto. Un texto dividido con <br> en lugar de párrafos sigue indexándose, pero pierde señales sobre cómo se organiza la información.
Esto se nota especialmente en los fragmentos enriquecidos que aparecen en los resultados de búsqueda. Una lista de pasos marcada con <ol> es más fácil de interpretar como un procedimiento que una serie de líneas separadas por saltos dentro de un único párrafo. Lo mismo ocurre con las preguntas frecuentes, las tablas de especificaciones o los horarios de un comercio.
Además, cuando un salto de línea separa dos palabras sin espacio alrededor, algunos procesos de extracción de texto pueden unirlas. Por eso conviene dejar el salto al final de la línea de código, después de la palabra, como en los ejemplos de esta guía:
<p>
Lunes a viernes: 9:00 a 18:00<br />
Sábados: 10:00 a 14:00
</p>
El espacio en blanco que sigue al <br> en el código garantiza que las palabras de ambas líneas permanezcan separadas en cualquier contexto.
Conclusiones
La etiqueta <br> es uno de los elementos más simples de HTML: no tiene atributos propios relevantes, no tiene contenido y no necesita cierre. Precisamente por esa simplicidad es fácil abusar de ella. Su función legítima es marcar saltos de línea que forman parte del contenido, como los de una dirección postal, una firma o un poema.
Para todo lo demás existen herramientas mejores. Los párrafos y las listas aportan estructura y accesibilidad; los márgenes, gap y display controlan el espacio y la disposición; white-space: pre-line respeta los saltos del texto dinámico; <wbr> y overflow-wrap resuelven las palabras largas; y textContent permite mostrar contenido de usuarios sin riesgos de seguridad.
Si antes de escribir un <br> te preguntas si el salto forma parte de lo que quieres comunicar o solo de cómo quieres que se vea, tendrás la respuesta casi siempre. Ese pequeño hábito hace que el HTML sea más limpio, más accesible y mucho más fácil de mantener a largo plazo.
