<div>
Semántica y estructura de página
Contenedor genérico de bloque sin semántica propia. Agrupa elementos para aplicar estilos CSS, definir zonas de layout o servir de gancho para JavaScript cuando ningún elemento semántico aplica.
<div> es el contenedor de bloque sin semántica: no le dice nada al navegador, al lector de pantalla ni al motor de búsqueda sobre el significado del contenido que envuelve. No genera ningún landmark. No comunica ningún rol. Es, en palabras simples, una caja invisible en el flujo del documento que agrupa elementos para que CSS o JavaScript puedan operar sobre ellos como grupo.
Entender <div> correctamente requiere entender primero para qué no sirve, porque es el elemento más fácil de sobreusar. Antes de HTML5, toda la estructura de las páginas se construía con <div> y atributos id o class que les daban nombres como "header", "nav", "main", "footer". El “div soup” resultante era código inaccesible: los lectores de pantalla no podían navegar por landmarks porque no había ninguno. Con HTML5 llegaron los elementos semánticos — <header>, <nav>, <main>, <footer>, <section>, <article>, <aside> — que comunican esos roles directamente, sin depender de nombres de clase.
<div> no quedó obsoleto con HTML5, pero cambió de rol. Ahora es el último recurso: el elemento que usás cuando ningún elemento semántico describe correctamente lo que estás agrupando. Para el estilo visual de una tarjeta de producto, para envolver un grid de ítems en un contenedor flex, para crear una capa de superposición (overlay), para dar un gancho a JavaScript en una sección de la UI sin significado semántico propio — esos son usos legítimos de <div>. Lo que no es legítimo es usarlo como contenedor genérico por defecto, sin preguntarse si existe un elemento más apropiado.
Cómo funciona
<div> es un elemento de bloque con display block por defecto. Ocupa el ancho disponible de su contenedor y genera salto de línea antes y después, igual que <p>, <h1> o <section>. No tiene estilos propios más allá del display — no tiene margen, padding, borde ni color predeterminado.
No genera ningún rol ARIA, ningún landmark, ninguna anotación semántica. Para un lector de pantalla, un <div> con contenido es indistinguible de su contenido sin el <div> — el contenedor es invisible semánticamente.
Precisamente esta neutralidad lo hace útil cuando se necesita un contenedor sin semántica:
- Contenedor para CSS flex/grid: cuando se necesita un
display: flexodisplay: gridsobre un conjunto de elementos que no tienen un elemento semántico que describa su agrupación. - Capa de superposición (overlay) o modal: un panel flotante que no es un
<dialog>(aunque hoy<dialog>es la opción semántica), un tooltip, un dropdown. - Gancho para JavaScript: un contenedor vacío en el que JavaScript va a insertar contenido dinámico.
- Agrupación para estilos compartidos: cuando varios elementos distintos necesitan el mismo padding, fondo o borde y ningún elemento semántico describe el grupo.
Modelo de contenido
<div> acepta contenido de flujo cuando es descendiente de un elemento que acepta contenido de flujo (la situación habitual). Si está dentro de un elemento <dl>, puede contener elementos <dt> y <dd>. Puede anidarse libremente y contener cualquier combinación de elementos de bloque y en línea.
Sintaxis
<!-- Contenedor de layout: tarjeta de producto -->
<div class="tarjeta-producto">
<img src="zapatilla.jpg" alt="Zapatilla Modelo X">
<h3>Zapatilla Modelo X</h3>
<p class="precio">$12.000</p>
<button type="button">Agregar al carrito</button>
</div>
<!-- Contenedor de grid para un catálogo -->
<main>
<h2>Catálogo de productos</h2>
<div class="grilla-productos">
<div class="tarjeta-producto">...</div>
<div class="tarjeta-producto">...</div>
<div class="tarjeta-producto">...</div>
</div>
</main>
<!-- Overlay o modal sin semántica de diálogo -->
<div class="overlay" hidden>
<div class="modal-panel">
<h2>Confirmar acción</h2>
<p>¿Estás seguro de que querés eliminar este elemento?</p>
<button type="button">Cancelar</button>
<button type="button">Eliminar</button>
</div>
</div>
Atributos
<div> no tiene atributos propios. Acepta todos los atributos globales de HTML. Los más usados en la práctica:
class— el más frecuente. Da nombre a la agrupación para CSS y a veces para JavaScript.id— identificador único en la página. Útil como destino de ancla o gancho de JavaScript.data-*— atributos de datos personalizados para JavaScript sin afectar la presentación.
Rol de landmark y accesibilidad
<div> no tiene rol ARIA implícito. No genera ningún landmark. Para los lectores de pantalla, es transparente — su contenido se lee como si el <div> no existiera. Esto es por diseño: es un contenedor neutro.
Si por algún motivo se necesita que un <div> tenga un rol específico (por ejemplo, en el contexto de una aplicación JavaScript donde se usa <div> para construir componentes interactivos), se puede agregar role explícito:
<div role="alert">El formulario tiene errores.</div>
<div role="status">Guardando cambios...</div>
Pero en documentos HTML estáticos, si el elemento necesita rol, generalmente lo que necesita es el elemento semántico correcto, no un <div> con role pegado.
Cuándo usar <div> / cuándo usar el elemento semántico
La regla es simple: primero buscá el elemento semántico. <div> es el último recurso.
| Necesidad | Primer candidato | ¿Cuándo usar <div>? |
|---|---|---|
| Encabezado del sitio | <header> | Nunca para esto |
| Navegación del sitio | <nav> | Nunca para esto |
| Contenido principal | <main> | Nunca para esto |
| Pie de página | <footer> | Nunca para esto |
| Agrupación temática con heading | <section> | Solo si no hay heading temático |
| Contenido autónomo (post, tarjeta) | <article> | Si no tiene autonomía redistribuible |
| Contenido complementario | <aside> | Si es esencial al argumento |
| Tarjeta de producto / layout wrapper | No hay elemento semántico | <div> es correcto |
| Overlay, modal, dropdown | <dialog> cuando aplica | <div> si no aplica <dialog> |
| Gancho para JS sin semántica | No hay elemento semántico | <div> es correcto |
Notas, gotchas e interacción
<div>en lugar de<article>para tarjetas es un error frecuente. Una tarjeta de producto que es redistribuible y autónoma debería ser<article>. Un contenedor de layout para un grid de ítems puede ser<div>.- El “div soup” es el antipatrón central de este módulo. Usar solo
<div>para toda la estructura, conidoclasscomo sustituto de semántica, produce código inaccesible e ilegible. Es el patrón pre-HTML5 que los elementos semánticos vinieron a reemplazar. <div>vs<span>. Ambos son contenedores sin semántica, pero<div>es de bloque y<span>es de en línea. Usar<span>donde se necesita bloque (o viceversa) produce comportamiento inesperado en el layout.- Display block es el default. A diferencia de
<span>,<div>no rompe el flujo del texto que lo rodea cuando está dentro de contenido en línea — pero su comportamiento como bloque puede crear saltos de línea inesperados si se usa dentro de un párrafo.
Vigente / legacy
<div> está completamente vigente. Nunca fue legacy — cambió de rol con HTML5 (de contenedor universal a último recurso), pero sigue siendo un elemento fundamental. El patrón legacy son los <div> con id/class imitando roles semánticos (<div id="header">, <div class="nav">, etc.) — esos patrones son los que reemplazaron los elementos semánticos de HTML5. No hay atributos propios de <div> marcados como legacy (el atributo align de <div> existía en HTML 4 pero fue eliminado en HTML5 — hoy se usa CSS).